Dijkstra vs. Floyd-Warshall:在所有节点对上寻找最佳路线

时间:2010-11-18 07:10:57

标签: algorithm graph shortest-path dijkstra floyd-warshall

我正在阅读Dijkstra的算法和Floyd-Warshall算法。据我所知,Dijkstra找到了从一个节点到所有其他节点的最佳路径,Floyd-Warshall找到了所有节点配对的最佳路径。

我的问题是,如果我在每个节点上运行它,Dijkstra的算法会比Floyd更有效,以便找到所有配对之间的最佳路径。

Dijkstra的运行时间是O(E + VlogV),其中Floyd是O(V 3 )。如果Dijkstra失败了,在这种情况下它的运行时间是什么?谢谢!

4 个答案:

答案 0 :(得分:33)

正如其他人所指出的那样,Floyd-Warshall在时间O(n 3 )运行并运行Dijkstra从每个节点到另一个节点的搜索,假设您正在使用Fibonacci堆返回你的Dijkstra的实现,需要O(mn + n 2 log n)。但是,你不能总是在任意图上安全地运行Dijkstra,因为Dijkstra的算法不适用于负边权重。

有一个名为 Johnson's algorithm 的真正卓越的算法,它是对每个节点运行Dijkstra算法的略微修改,即使图形包含负边缘,也允许该方法工作(因为没有任何负面周期)。该算法首先在图上运行Bellman-Ford以将其转换为没有负边的图,然后使用从每个顶点开始的Dijkstra算法。因为Bellman-Ford在时间O(mn)运行,所以整体渐近运行时仍然是O(mn + n 2 log n),所以如果m = o(n 2 )(注意这是n的 little-o ),这种方法比使用Floyd-Warshall更快。

这里的一个问题是,假设你有一个由Fibonacci堆支持的Dijkstra算法。如果你没有Fibonacci堆可用并且不愿意花费72小时来构建,调试和测试一个,那么你仍然可以使用二进制堆来实现Dijkstra的算法;它只是将运行时间增加到O(m log n),因此这个版本的Johnson算法在O(mn log n)中运行。这不再总是比Floyd-Warshall渐近地快,因为如果m =Ω(n 2 )那么Floyd-Warshall在O(n 3 )中运行,而Johnson的算法运行在O(n 3 log n)中。然而,对于稀疏图,其中m = o(n 2 / log n),约翰逊算法的这种实现仍然比Floyd-Warshall渐近更好

简而言之:

  • 使用Fibonacci堆,Johnson的算法总是渐近渐近至少和Floyd-Warshall一样好,尽管编码起来比较困难。
  • 对于二进制堆,Johnson的算法通常渐近至少与Floyd-Warshall一样好,但在处理大而密集的图时不是一个好的选择。

希望这有帮助!

答案 1 :(得分:10)

在所有节点上运行Dijkstra的复杂性将为O(EV + V 2 logV)。如果E 3 )。 V 2

答案 2 :(得分:3)

这取决于。为所有节点运行Dijkstra会为您提供O(VE + V^2log V),而Floyd则为O(V^3)。如果E = O(V^2),则两者在理论上是相同的,而Floyd在实践中更快。如果你E = O(V),那么在理论上和实践上都要运行Dijkstra所有节点。

基本上,如果您希望拥有与节点数量相同的边数,则从所有节点运行Dijkstra,如果您希望拥有几乎完整的图形,则运行Floyd。

答案 3 :(得分:-2)

实际上没有Floyd-Warshall比Dijkstra的所有对最短路径更快(通常!!)