Ви можете використовувати set
(в математичному сенсі цього слова, тобто колекцію, яка не може містити дублікатів) для зберігання станів, які ви вже бачили. Операції, які вам знадобляться для виконання, це:
- вставки елементів
- тестування, якщо елементи вже є
Практично кожна мова програмування вже повинна мати підтримку структури даних, яка може виконувати обидві ці операції в постійному режимі (O ( 1 )) час. Наприклад:
set
в Python
HashSet
на Java
На перший погляд, може здатися, що додавання всіх станів, які ви коли-небудь бачите, до такого набору буде дорогим для пам'яті, але це не так вже й погано в порівнянні з пам'яттю, яка вам вже потрібна для вашого кордону; якщо ваш коефіцієнт розгалуженняб, ваш кордон буде рости б - 1 елементів на вузол, який ви відвідуєте (видаліть) 1 вузол від кордону, щоб "відвідати" його, додати б нових наступників / дітей), тоді як ваш набір буде лише зростати 1 додатковий вузол на відвідуваний вузол.
У псевдокоді такий набір (назвемо його closed_set
, щоб він узгоджувався з псевдокодом у Вікіпедії, міг би використовуватися в пошуку за шириною-першим наступним чином:
frontier = First-In-First-Out Queue
frontier.add(initial_state)
closed_set = set()
while frontier not empty:
current = frontier.remove_next()
if current == goal_state:
return something
for each child in current.generate_children()
if child not in closed_set: // This operation should be supported in O(1) time regardless of closed_set's current size
frontier.add(child)
closed_set.add(current) // this should also run in O(1) time
(деякі варіанти цього псевдокоду можуть також працювати і бути більш-менш ефективними залежно від ситуації; наприклад, ви також можете взяти, closed_set
щоб містити всі вузли, до яких ви вже додали дітей до кордону, а потім повністю уникати generate_children()
дзвінка якщо current
вже в closed_set
.)
Те, що я описав вище, було б стандартним способом вирішення цієї проблеми. Інтуїтивно, я підозрюю, що іншим "рішенням" може бути завжди рандомізувати порядок нового списку держав-наступників перед тим, як додати їх до кордону. Таким чином, ви не уникнете проблеми періодичного додавання держав, які ви вже попередньо розширили до кордону, але я думаю, що це повинно значно зменшити ризик застрягти в нескінченних циклах.
Будьте уважні : я не знаю жодного формального аналізу цього рішення, який би підтверджував, що він завжди уникає нескінченних циклів, хоча. Якщо я спробую "пропустити" це через голову, інтуїтивно, я підозрюю, що це повинно працювати, і це не потребує додаткової пам'яті. Можливо, є певні випадки, про які я зараз не замислююся, тому це також може просто не працювати, стандартне рішення, описане вище, стане більш безпечною ставкою (ціною більше пам'яті).