Из Википедии, свободной энциклопедии
Перейти к навигации Перейти к поиску

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

Алгоритм [ править ]

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

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

Ниже представлен псевдокод алгоритма. [3] Вот очередь вершин-кандидатов «первым пришел - первым обслужен», а это вес ребра .

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

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

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

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

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

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

Продолжительность [ править ]

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

Методы оптимизации [ править ]

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

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

процедура Small-Label-First ( G , Q ), если d (back ( Q )) <d (front ( Q )), то u: = вытолкнуть заднюю часть Q, протолкнуть u перед Q

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

процедура Large-Label-Last ( G , Q ) x  : = среднее значение d ( v ) для всех v в Q, в  то время как d (front ( Q ))> x  u  : = вытолкнуть перед Q толкнуть u в заднюю часть Q

Ссылки [ править ]

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