Dijkstra vs. Floyd-Warshall: Finding optimal route on all node pairs
I am reading up on Dijkstra's algorithm and the Floyd-Warshall algorithm. I understand that Dijkstra's finds the optimal route from one node to all other nodes and Floyd-Warshall finds the optimal route for all node pairings.
My question is would Dijkstra's algorithm be more efficient than Floyd's if I run it on every single node in order to find th开发者_运维知识库e optimal route between all pairings.
Dijkstra's runtime is O(E + VlogV) where Floyd's is O(V3). If Dijkstra's fails, what would its runtime be in this case? Thanks!
As others have pointed out, Floyd-Warshall runs in time O(n3) and running a Dijkstra's search from each node to each other node, assuming you're using a Fibonacci heap to back your Dijkstra's implementation, takes O(mn + n2 log n). However, you cannot always safely run Dijkstra's on an arbitrary graph because Dijkstra's algorithm does not work with negative edge weights.
There is a truly remarkable algorithm called Johnson's algorithm that is a slight modification to running Dijkstra's algorithm from each node that allows that approach to work even if the graph contains negative edges (as long as there aren't any negative cycles). The algorithm works by first running Bellman-Ford on the graph to transform it to a graph with no negative edges, then using Dijkstra's algorithm starting at each vertex. Because Bellman-Ford runs in time O(mn), the overall asymptotic runtime is still O(mn + n2 log n), so if m = o(n2) (note that this is little-o of n), this approach is asymptotically faster than using Floyd-Warshall.
The one catch here is that this assumes that you have Dijkstra's algorithm backed by a Fibonacci heap. If you don't have Fibonacci heap available and aren't willing to put in the 72 hours necessary to build, debug, and test one, then you can still use a binary heap for Dijkstra's algorithm; it just increases the runtime to O(m log n), so this version of Johnson's algorithm runs in O(mn log n). This is no longer always asymptotically faster than Floyd-Warshall, because if m = Ω(n2) then Floyd-Warshall runs in O(n3) while Johnson's algorithm runs in O(n3 log n). However, for sparse graphs, where m = o(n2 / log n), this implementation of Johnson's algorithm is still asymptotically better than Floyd-Warshall
In short:
- With a Fibonacci heap, Johnson's algorithm is always asymptotically at least as good as Floyd-Warshall, though it's harder to code up.
- With a binary heap, Johnson's algorithm is usually asymptotically at least as good as Floyd-Warshall, but is not a good option when dealing with large, dense graphs.
Hope this helps!
The complexity for running Dijkstra on all nodes will be O(EV + V2logV). This complexity is lower than O(V3) iff E < V2.
It depends. Running Dijkstra for all nodes gives you O(VE + V^2log V)
, while Floyd's is O(V^3)
. If E = O(V^2)
, then the two are theoretically identical, with Floyd being faster in practice. If you E = O(V)
, then running Dijkstra for all nodes if better both in theory and in practice.
Basically, run Dijkstra from all nodes if you expect to have about as many edges as you have nodes, and run Floyd if you expect to have almost complete graphs.
No practically Floyd-Warshall is faster than Dijkstra's for all pair shortest path (generally!!)
精彩评论