Самый быстрый алгоритм кратчайшего пути - Shortest Path Faster Algorithm

В Самый быстрый алгоритм кратчайшего пути (SPFA) это улучшение Алгоритм Беллмана – Форда который вычисляет кратчайшие пути из одного источника во взвешенном ориентированном графе. Считается, что алгоритм хорошо работает на случайных разреженных графах и особенно подходит для графов, содержащих ребра с отрицательным весом.[1] Однако сложность SPFA наихудшего случая такая же, как у Беллмана – Форда, поэтому для графов с неотрицательными весами ребер Алгоритм Дейкстры является предпочтительным. Алгоритм SPFA был впервые опубликован Эдвард Ф. Мур в 1959 г., как обобщение поиск в ширину;[2] SPFA - это «алгоритм D» Мура.

Алгоритм

Учитывая взвешенный ориентированный граф и исходная вершина , алгоритм SPFA находит кратчайший путь из , в каждую вершину , на графике. Длина кратчайшего пути от к хранится в для каждой вершины .

Основная идея SPFA такая же, как и у алгоритма Беллмана – Форда, в том, что каждая вершина используется в качестве кандидата для ослабления смежных вершин. Улучшение по сравнению с последним состоит в том, что вместо того, чтобы пробовать все вершины вслепую, SPFA поддерживает очередь вершин-кандидатов и добавляет вершину в очередь, только если эта вершина ослаблена. Этот процесс повторяется до тех пор, пока не перестанет расслабляться вершина.

Ниже представлен псевдокод алгоритма.[3] Здесь - очередь кандидатов вершин в порядке очереди, и это вес края .

Демонстрация SPFA на основе евклидова расстояния. Красные линии - это покрытие кратчайшего пути (пока наблюдалось). Синие линии показывают, где происходит расслабление, т.е. с узлом в , что дает более короткий путь от источника до .
 процедура Кратчайший путь-быстрый-алгоритм (грамм, s)  1    за каждая вершина vs в V(грамм) 2 д (v): = ∞ 3 d (s): = 0 4 нажать s в Q  5    пока Q не пусто делать  6        ты : = опрос Q  7        для каждого край (ты, v) в E(грамм) делать  8            если d (ты) + w (ты, v) v) тогда  9 дн (v): = d (ты) + w (ты, v) 10                если v не в Q тогда 11 толчок v в Q

Алгоритм также можно применить к неориентированному графу, заменив каждое неориентированное ребро двумя направленными ребрами противоположных направлений.

Доказательство правильности

Мы докажем, что алгоритм никогда не вычисляет неверные длины кратчайшего пути.

Лемма: Всякий раз, когда очередь проверяется на пустоту, любая вершина, способная в данный момент вызвать релаксацию, находится в очереди.
Доказательство: Мы хотим показать, что если для любых двух вершин и во время проверки условия, в очереди. Мы делаем это индукцией по количеству уже выполненных итераций цикла. Прежде всего отметим, что это определенно выполняется до входа в цикл: если , то расслабление невозможно; расслабление возможно от , и это добавляется в очередь непосредственно перед входом в цикл while. Теперь посмотрим, что происходит внутри цикла. Вершина выскакивает и используется, чтобы расслабить всех своих соседей, если это возможно. Следовательно, сразу после этой итерации цикла больше не вызывает расслабления (и больше не должен стоять в очереди). Однако релаксация может привести к тому, что некоторые другие вершины станут способными вызывать расслабление. Если есть какие-то так что перед текущей итерацией цикла тогда уже в очереди. Если это условие выполняется в течениетекущая итерация цикла, то либо увеличился, что невозможно, или уменьшилось, подразумевая, что был расслаблен. Но после расслаблен, он добавляется в очередь, если его еще нет.
Следствие: Алгоритм завершается тогда и только тогда, когда дальнейшие ослабления невозможны.
Доказательство: Если дальнейшие релаксации невозможны, алгоритм продолжает удалять вершины из очереди, но больше не добавляет в очередь, потому что вершины добавляются только после успешных релаксаций. Поэтому очередь становится пустой, и алгоритм завершается. Если возможны дальнейшие ослабления, очередь не пуста, и алгоритм продолжает работать.

Алгоритм не может завершиться, если из источника достижимы циклы с отрицательным весом. Видеть здесь для доказательства того, что релаксации всегда возможны, когда существуют циклы с отрицательным весом. В графе без циклов отрицательного веса, когда релаксации больше невозможно, были вычислены правильные кратчайшие пути (доказательство ). Следовательно, в графах, не содержащих циклов отрицательного веса, алгоритм никогда не завершится с неправильными длинами кратчайшего пути.[4].

Продолжительность

Наихудшее время работы алгоритма составляет , как и стандартный Беллман-Форд алгоритм.[1] Эксперименты показывают, что среднее время работы составляет , и это действительно так для случайных графов, но можно построить разреженные графы, в которых SPFA выполняется во времени как обычный алгоритм Беллмана-Форда[5].

Методы оптимизации

Производительность алгоритма во многом определяется порядком, в котором вершины-кандидаты используются для ослабления других вершин. Фактически, если является приоритетной очередью, то алгоритм очень похож на алгоритм Дейкстры. Однако, поскольку очередь с приоритетом здесь не используется, иногда используются два метода для улучшения качества очереди, что, в свою очередь, улучшает производительность в среднем случае (но не в худшем случае). Оба метода изменяют порядок элементов в так что в первую очередь обрабатываются вершины, расположенные ближе к источнику. Поэтому при реализации этих методов больше не является очередью «первым пришел - первым ушел», а скорее является обычным двусвязным списком или двусторонней очередью.

Сначала малый лейбл (SLF) техника. В строке 11 вместо того, чтобы всегда нажимать вершину до конца очереди, сравниваем к и вставьте в начало очереди, если меньше. Псевдокод для этой техники (после нажатия до конца очереди в строке 11):

процедура Small-Label-First (грамм, Q)    если d (назад (Q)) Q)) тогда        u: = выскочить назад Q        толкнуть тебя перед Q

Большой ярлык последний (LLL) техника. После строки 11 мы обновляем очередь так, чтобы первый элемент был меньше среднего, а любой элемент больше среднего перемещался в конец очереди. Псевдокод:

процедура Крупная этикетка-последний (грамм, Q)    Икс : = среднее значение d (v) для всех v в Q    пока d (перед (Q)) > Икс        ты : = открыть перед Q        толкать ты к спине Q

Рекомендации

  1. ^ а б О так называемом алгоритме SPFA
  2. ^ Мур, Эдвард Ф. (1959). «Кратчайший путь через лабиринт». Материалы Международного симпозиума по теории переключения.. Издательство Гарвардского университета. С. 285–292.
  3. ^ http://codeforces.com/blog/entry/16221
  4. ^ "Самый быстрый алгоритм кратчайшего пути". Wcipeg.
  5. ^ Кэ, Ян. «Худший тестовый пример для SPFA».