Как вы используете двунаправленную BFS для поиска кратчайшего пути?

Как вы используете двунаправленную BFS для поиска кратчайшего пути? Допустим, есть сетка 6x6. Начальная точка находится в (0,5), а конечная точка — в (4,1). Каков кратчайший путь с использованием двунаправленного BFS? Стоимость пути отсутствует. И это ненаправлено.




Ответы (1)


Как работает двунаправленная BFS?

Одновременно запустите два BFS как из исходной, так и из целевой вершин, завершив работу, как только будет обнаружена вершина, общая для обоих запусков. Эта вершина будет на полпути между источником и целью.

Почему это лучше, чем BFS?

Двунаправленная BFS в большинстве случаев даст гораздо лучшие результаты, чем простая BFS. Предположим, что расстояние между источником и целью равно k, а коэффициент ветвления равен B (каждая вершина имеет в среднем B ребер).

  • BFS пройдет 1 + B + B^2 + ... + B^k вершин.
  • Двунаправленный BFS будет проходить через 2 + 2B^2 + ... + 2B^(k/2) вершины.

Для больших B и k второй, очевидно, намного быстрее первого.


В вашем случае:

Для простоты я буду считать, что в матрице нет препятствий. Вот что происходит:

iteration 0 (init):
front1 = { (0,5) }
front2 = { (4,1) }

iteration 1: 
front1 = { (0,4), (1,5) }
front2 = { (4,0), (4,2), (3,1), (5,1) }

iteration 2:
front1 = { (0,3), (1,4), (2,5) }
front2 = { (3,0), (5,0), (4,3), (5,2), (3,2), (2,1) }

iteration 3:
front1 = { (0,2), (1,3), (2,4), (3,5) }
front2 = { (2,0), (4,4), (3,3), (5,3), (2,2), (1,1), }

iteration 4:
front1 = { (0,1), (1,2), .... }
front2 = { (1,2) , .... }

Теперь мы обнаружили, что фронты пересекаются в (1,2) вместе с путями, по которым можно попасть туда из исходной и целевой вершин:

path1: (0,5) -> (0,4) -> (0,3) -> (0,2) -> (1,2)
path2: (4,1) -> (3,1) -> (2,1) -> (1,1) -> (1,2)

Теперь нам просто нужно перевернуть путь 2 и добавить его к пути 1 (конечно, удалив одну из общих пересекающихся вершин), чтобы получить наш полный путь:

(0,5) -> (0,4) -> (0,3) -> (0,2) -> (1,2) -> (1,1) -> (2,1) -> (3,1) -> (4,1)
person amit    schedule 01.11.2012
comment
Хорошее объяснение. Хотите знать, как бы вы сохранили все пути, чтобы проследить, когда есть пересечение между очередями? Если бы мы хранили все пути, для каждого узла потребовалось бы много места. - person newbie_old; 06.09.2016
comment
@newbie_old Подобно обычному BFS, каждый обнаруженный вами узел вы отмечаете, как вы его обнаружили. (В двунаправленной BFS особое внимание следует уделить пересекающемуся узлу, который должен иметь двух родителей). Затем вы возвращаетесь от узла до корня. Требуемое пространство линейно зависит от количества вершин, которое в любом случае является необходимым пространством для BFS (для набора visited и для очереди). - person amit; 06.09.2016
comment
Таким образом, временная сложность уменьшается на квадратный корень; а космическая сложность одинакова? - person LookIntoEast; 22.01.2018
comment
@ user815408 В асимптотических обозначениях да. (Например, искомое пространство удваивается, но это в той же асимптотической сложности). - person amit; 22.01.2018
comment
@amit Интересно, почему его время лучше обычного BFS? мы должны проверять весь посещенный массив на наличие пересечения после каждой операции удаления из очереди (т.е. для каждого нового уровня), и, поскольку мы обрабатываем d/2 уровней в двунаправленной BFS, мы собираемся сделать V×(d/2) сравнений всего а V здесь не меньше, чем b^d. В чем тогда смысл? Может кто-нибудь объяснить мне, где я могу ошибаться? - person mangusta; 03.03.2019
comment
@mangusta Я не уверен, что понял твой вопрос. Вам не нужно проверять каждый обнаруженный узел по сравнению со всеми остальными, для этого вы используете DS на основе дерева/хэша, и это линейное/квазилинейное время. - person amit; 03.03.2019
comment
@amit верно, я понял, что нам не нужно проверять все узлы каждый раз, когда мы открываем новый уровень. Код, который я анализировал на конкретном веб-сайте (не буду здесь упоминать его название), вводил в заблуждение. Всякий раз, когда мы обнаруживаем узел при обходе A, нам просто нужно проверить его статус обнаружения в discovered массиве обхода B и наоборот. - person mangusta; 04.03.2019