Bellman Ford
This page provides introduction to Bellman Ford Algorithm.
Overview
Bellman ford is single source shortest path algorithm. Below is a table showing the types of graphs where Bellman Ford algorithm works.
Graph Type | Does Bellman ford's Algorithm Works? |
---|---|
Directed with positive weight edge | Yes |
Directed with negative weight edge | Yes(except when graph is negative weight cycle) |
Undirected with positive weight edge | Yes |
Undirected with negative weight edge | Yes(except when graph is negative weight cycle) |
Here is example of graph with negative weight cycle.
Run Bellman Ford
Let's apply the Bellman Ford algorithm to the directed graph shown below to calculate the distance of each node from the source node . The graph includes a negative weight edge, but no negative weight cycles.
We begin by iterating through each edge times, where represents the number of vertices in the graph. Distance of node from itself is .
Visiting edge gives us the distance of node from as , which is less than the existing value of infinity. Therefore, we update the distance for in the distance hashmap.
Visiting edge gives us the distance of node from as , which is less than the existing value of infinity. Therefore, we update the distance for in the distance hashmap.
Visiting edge gives us the distance of node from as , which is less than the existing value of infinity. Therefore, we update the distance for in the distance hashmap.
Visiting edge gives us the distance of node from as (the distance of node from in the distance map plus the distance of edge ). Since this is greater than the existing distance of node from , we don't update anything in the distance hashmap.
Visiting edge gives us the distance of node from as (the distance of node from node in the distance map plus the distance of edge ). Since this is greater than the existing distance of node from , we don't update anything in the distance hashmap.
Visiting edge gives us the distance of node from as (the distance of node from plus the distance of edge ). Since this is less than the existing value of infinity, we update the distance of node from in the distance hashmap.
Visiting edge gives us the distance of node from as (the distance of node from node plus the distance of edge ).
This concludes the iteration of visiting all edges. Let's begin with the iteration.
Visiting edge gives us the distance of node from as , which is greater than the existing distance of . Therefore, we don't update the distance in the hashmap.
Visiting edge gives us the distance of node from as , which is equal to the existing distance. Therefore, we don't update the distance in the hashmap.
Visiting edge gives us the distance of node from as , which is equal to the existing distance. Therefore, we don't update the distance in the hashmap.
Visiting edge gives us the distance of node from as (distance of from node + distance of edge ), which is less than the existing distance. Therefore, we update the distance of node in the hashmap.
Visiting edge gives us the distance of node from as (distance of from node + distance of edge ), which is greater than the existing distance. Therefore, we don't update the distance in the hashmap.
Visiting edge gives us the distance of node from as (distance of from node + distance of edge ), which is equal to the existing distance. Therefore, we don't update the distance in the hashmap.
Visiting edge gives us the distance of node from as (distance of from node + distance of edge ), which is equal to the existing distance. Therefore, we don't update the distance in the hashmap.
This concludes the iteration of visiting all edges. Continuing the and iterations yields similar results for the distance hashmap, as no further updates are made. At this point, the shortest distances from the source node to all other nodes have been finalized.
Why V - 1 Iterations
Let's say we have the following graph, and we are finding the shortest path from node using the Bellman Ford algorithm.
Now, if we apply the Bellman-Ford algorithm to the graph above, the first edge we iterate over will be . Since we don't yet know how to reach node , we can't update the distance hashmap.
Now, we iterate over the edge . Since the distance of from itself is already known, we can update the distance of node from node to .
This concludes the iteration, but we still haven't determined the distance of node from node . This happened because when we first iterated over edge , we didn't know the distance of node from node .
This demonstrates that the algorithm's effectiveness also depends on the order in which we iterate over the edges. Iterating over the edges times ensures that we have updated the shortest distances for all nodes, even if some connections were discovered in later iterations.
Therefore, in the Bellman Ford algorithm, we iterate over the edges times to ensure that all shortest paths are correctly updated.
- Java
class Edge {
char src;
char dest;
int distance;
Edge(char src, char dest, int distance) {
this.src = src;
this.dest = dest;
this.distance = distance;
}
}
public HashMap<Character, Integer> bellmanFord(int vertices, Edge[] graph) {
HashMap<Character, Integer> dist = new HashMap<>();
for(int i = 0; i < vertices; i++) {
char ch = 'A' + i;
dist.put(ch, Integer.MAX_VALUE);
}
// source node
dist.put('A', 0);
for(int i = 0; i < vertices - 1; i++) {
for(Edge e: graph) {
if(dist.get(e.src) != Integer.MAX_VALUE && dist.get(e.src) + e.distance < dist.get(e.dest)) {
dist.put(e.dest, dist.get(e.src) + e.distance);
}
}
}
// run the algorithm one more time to check if graph has negative weight cycle
for(Edge e: graph) {
// distance reduces futher meaning graph as negative weight cycle
if(dist.get(e.src) != Integer.MAX_VALUE && dist.get(e.src) + e.distance < dist.get(e.dest)) {
throw new Excepttion("Graph contains negative weight cycle");
}
}
return dist;
}
Complexity
Let's say there are vertices and edges in a graph.
Time Complexity
Bellman ford algorithm runs for times over all the edges, so time complexity is:
Space Complexity
The algorithm uses space to store the distances of all vertices in a hashmap, therefore the total space complexity will be as below:
Bellman Ford is useful for graphs with negative weights, but Dijkstra’s algorithm is typically preferred when all edge weights are non negative.