Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Am I right about the differences between Floyd-Warshall, Dijkstra's and Bellman-Ford algorithms?

Tags:

I've been studying the three and I'm stating my inferences from them below. Could someone tell me if I have understood them accurately enough or not? Thank you.

  1. Dijkstra's algorithm is used only when you have a single source and you want to know the smallest path from one node to another, but fails in cases like this

  2. Floyd-Warshall's algorithm is used when any of all the nodes can be a source, so you want the shortest distance to reach any destination node from any source node. This only fails when there are negative cycles

(this is the most important one. I mean, this is the one I'm least sure about:)

3.Bellman-Ford is used like Dijkstra's, when there is only one source. This can handle negative weights and its working is the same as Floyd-Warshall's except for one source, right?

If you need to have a look, the corresponding algorithms are (courtesy Wikipedia):

Bellman-Ford:

 procedure BellmanFord(list vertices, list edges, vertex source)    // This implementation takes in a graph, represented as lists of vertices    // and edges, and modifies the vertices so that their distance and    // predecessor attributes store the shortest paths.     // Step 1: initialize graph    for each vertex v in vertices:        if v is source then v.distance := 0        else v.distance := infinity        v.predecessor := null     // Step 2: relax edges repeatedly    for i from 1 to size(vertices)-1:        for each edge uv in edges: // uv is the edge from u to v            u := uv.source            v := uv.destination            if u.distance + uv.weight < v.distance:                v.distance := u.distance + uv.weight                v.predecessor := u     // Step 3: check for negative-weight cycles    for each edge uv in edges:        u := uv.source        v := uv.destination        if u.distance + uv.weight < v.distance:            error "Graph contains a negative-weight cycle" 

Dijkstra:

 1  function Dijkstra(Graph, source):  2      for each vertex v in Graph:                                // Initializations  3          dist[v] := infinity ;                                  // Unknown distance function from   4                                                                 // source to v  5          previous[v] := undefined ;                             // Previous node in optimal path  6                                                                 // from source  7        8      dist[source] := 0 ;                                        // Distance from source to source  9      Q := the set of all nodes in Graph ;                       // All nodes in the graph are 10                                                                 // unoptimized - thus are in Q 11      while Q is not empty:                                      // The main loop 12          u := vertex in Q with smallest distance in dist[] ;    // Start node in first case 13          if dist[u] = infinity: 14              break ;                                            // all remaining vertices are 15                                                                 // inaccessible from source 16           17          remove u from Q ; 18          for each neighbor v of u:                              // where v has not yet been  19                                                                                 removed from Q. 20              alt := dist[u] + dist_between(u, v) ; 21              if alt < dist[v]:                                  // Relax (u,v,a) 22                  dist[v] := alt ; 23                  previous[v] := u ; 24                  decrease-key v in Q;                           // Reorder v in the Queue 25      return dist; 

Floyd-Warshall:

 1 /* Assume a function edgeCost(i,j) which returns the cost of the edge from i to j  2    (infinity if there is none).  3    Also assume that n is the number of vertices and edgeCost(i,i) = 0  4 */  5  6 int path[][];  7 /* A 2-dimensional matrix. At each step in the algorithm, path[i][j] is the shortest path  8    from i to j using intermediate vertices (1..k−1).  Each path[i][j] is initialized to  9    edgeCost(i,j). 10 */ 11 12 procedure FloydWarshall () 13    for k := 1 to n 14       for i := 1 to n 15          for j := 1 to n 16             path[i][j] = min ( path[i][j], path[i][k]+path[k][j] ); 
like image 385
GrowinMan Avatar asked Jul 28 '12 21:07

GrowinMan


People also ask

What is difference between Bellman-Ford and Floyd-Warshall algorithm?

The Bellman–Ford algorithm is an algorithm that computes shortest paths from a single source vertex to all of the other vertices in a weighted digraph whereas Floyd-Warshall computes shortest paths from each node to every other node.

What is the difference between Dijkstra and Floyd-Warshall algorithm?

Dijkstra's Algorithm is one example of a single-source shortest or SSSP algorithm, i.e., given a source vertex it finds shortest path from source to all other vertices. Floyd Warshall Algorithm is an example of all-pairs shortest path algorithm, meaning it computes the shortest path between all pair of nodes.

Is Dijkstra's and Floyd-Warshall algorithm's complexity same?

The complexity for running Dijkstra on all nodes will be O(EV + V2logV). This complexity is lower than O(V3) iff E < V2. This is true. Note however that Floyd-Warshall does very few operations in the inner-loop so in practice Floyd-Warshall will likely run faster than Dijkstra for All-Pairs Shortest Path.


1 Answers

You are correct about the first two questions, and about the goal of Floyd-Warshall (finding the shortest paths between all pairs), but not about the relationship between Bellman-Ford and Floyd-Warshall: Both algorithms use dynamic programming to find the shortest path, but FW isn't the same as running BF from each starting node to every other node.

In BF, the question is: What is the shortest path from the source to the target using at most k steps, and the running time is O(EV). If we were to run it to each other node, the running time would be O(EV^2).

In FW, the question is: what is the shortest path from i to j through k, for all nodes i,j,k. This leads to O(V^3) running time - better than BF for each starting node (by a factor of up to |V| for dense graphs).

One more note about negative cycles / weights: Dijkstra may simply fail to give the correct results. BF and FW won't fail - they will correctly state that there is no minimum weight path, since the negative weight is unbounded.

like image 103
Guy Adini Avatar answered Oct 04 '22 19:10

Guy Adini