Дейкстра против Флойда-Уоршалла: поиск оптимального маршрута для всех пар узлов

Я читаю об алгоритме Дейкстры и алгоритме Флойда-Уоршалла. Я понимаю, что Dijkstra's находит оптимальный маршрут от одного узла ко всем другим узлам, а Floyd-Warshall находит оптимальный маршрут для всех пар узлов.

Мой вопрос: был бы алгоритм Дейкстры более эффективным, чем алгоритм Флойда, если бы я запускал его на каждом отдельном узле, чтобы найти оптимальный маршрут между всеми парами.

Время выполнения Дейкстры - O (E + VlogV), а у Флойда - O (V 3). Если Дейкстры выйдет из строя, какова была бы его среда выполнения в этом случае? Спасибо!


person pyt    schedule 18.11.2010    source источник
comment
возможный дубликат алгоритма поиска кратчайшего пути   -  person Andreas Brinck    schedule 18.11.2010


Ответы (4)


Как отмечали другие, Floyd-Warshall выполняется за время O (n 3) и выполняет поиск Дейкстры от каждого узла к каждому другому узлу, предполагая, что вы используете кучу Фибоначчи для поддержки своей реализации Дейкстры , занимает O (mn + n 2 log n). Однако вы не всегда можете безопасно запускать алгоритм Дейкстры на произвольном графе, потому что алгоритм Дейкстры не работает с отрицательными весами ребер.

Существует поистине замечательный алгоритм под названием алгоритм Джонсона, который представляет собой небольшая модификация запуска алгоритма Дейкстры из каждого узла, которая позволяет этому подходу работать, даже если граф содержит отрицательные ребра (при условии, что нет отрицательных циклов). Алгоритм работает при первом запуске Беллмана-Форда на графике для его преобразования. в граф без отрицательных ребер, затем с помощью алгоритма Дейкстры, начиная с каждой вершины. Поскольку Беллман-Форд работает за время O (mn), общее асимптотическое время выполнения по-прежнему равно O (mn + n 2 log n), поэтому, если m = o (n 2 ) (обратите внимание, что это мало от n), этот подход асимптотически быстрее, чем использование Floyd-Warshall.

Единственная загвоздка здесь в том, что это предполагает, что у вас есть алгоритм Дейкстры, поддерживаемый кучей Фибоначчи. Если у вас нет доступной кучи Фибоначчи и вы не желаете вкладывать 72 часа, необходимые для ее создания, отладки и тестирования, вы все равно можете использовать двоичную кучу для алгоритма Дейкстры; он просто увеличивает время выполнения до O (m log n), поэтому эта версия алгоритма Джонсона работает за O (mn log n). Это уже не всегда асимптотически быстрее, чем Флойда-Уоршалла, потому что если m = (n 2), то Флойд-Уоршалл работает за O (n 3), в то время как алгоритм Джонсона работает в O (n 3 войти n). Однако для разреженных графов, где m = o (n 2 / log n), эта реализация алгоритма Джонсона все еще асимптотически лучше, чем Флойда-Уоршалла.

Короче:

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

Надеюсь это поможет!

person templatetypedef    schedule 01.09.2011
comment
+ за упоминание алгоритма Джонсона - person ; 28.11.2017
comment
9 с половиной лет спустя ... отличный ответ. Я искал именно это несколько дней. Спасибо @templatetypedef - person ; 04.10.2020

Сложность запуска Дейкстры на всех узлах будет O (EV + V 2 logV). Эта сложность ниже, чем O (V 3), если и только если E ‹V 2.

person Andreas Brinck    schedule 18.11.2010
comment
Это правда. Однако обратите внимание, что Floyd-Warshall выполняет очень мало операций во внутреннем цикле, поэтому на практике Floyd-Warshall, вероятно, будет работать быстрее, чем Dijkstra для кратчайшего пути для всех пар. - person Keegan Carruthers-Smith; 18.11.2010
comment
Обратите внимание, что E ‹V ^ 2 истинно, поскольку полный граф имеет (V * V-1) / 2 ребра (или вдвое больше, если направлено). - person domen; 08.04.2016

По-разному. Запуск Дейкстры для всех узлов дает O(VE + V^2log V), а Флойда - O(V^3). Если E = O(V^2), то теоретически они идентичны, а на практике Флойд быстрее. Если вы E = O(V), то запуск Дейкстры для всех узлов, если лучше как в теории, так и на практике.

По сути, запустите Dijkstra со всех узлов, если вы ожидаете, что у вас будет столько же ребер, сколько у вас узлов, и запустите Floyd, если вы ожидаете получить почти полные графы.

person IVlad    schedule 18.11.2010
comment
Почему run Floyd if you expect to have almost complete graphs? запустить Дейкстру в обоих случаях, какая разница в скорости? зачем усложнять алгоритм? - person Saeed Amiri; 18.11.2010
comment
@Saeed - потому что на практике Floyd должен быть быстрее (хотя я его не тестировал) из-за термина V^2log V. И реализовать Floyd намного проще, чем оптимального Dijkstra, поэтому, если вы хотите использовать только один, вы также можете использовать Floyd. - person IVlad; 18.11.2010
comment
@IVlad, я не слежу за этим. dijkstra, если он наивно реализован с использованием неупорядоченного массива, а не кучи, будет работать за время o (v ^ 2) (каждый узел имеет не более v соседей). выполнение этого один раз для каждого узла, что дает время o (n ^ 3). реальным преимуществом Floyd's, по-видимому, является его способность обрабатывать отрицательные грани (как указано в других комментариях) - person TolkienWASP; 14.05.2020

Практически нет кратчайшего пути Флойда-Уоршалла быстрее, чем путь Дейкстры для всех пар (как правило !!)

person piyush_raman    schedule 11.07.2012