Bellman Ford Algorithm
Bellman Ford Algorithm
nodes in a weighted graph. It is capable of handling graphs with negative edge weights and can
detect negative weight cycles. The algorithm works by relaxing all edges repeatedly for V−1
iterations, where V is the number of vertices in the graph.
Here is a numerical example of the Bellman-Ford Algorithm applied to find the shortest path in
a network flow problem, from one node to all nodes, with negative edges allowed. The Bellman-
Ford algorithm is particularly useful for graphs with negative edge weights, unlike Dijkstra’s
algorithm, which assumes all edge weights are non-negative.
Example 1
Consider the following directed graph with weights (some edges have negative weights):
From To Weight
S A 10
S E 8
A C 2
B A 1
C B -2
D A -4
D C -1
E D 1
1
Goal
Find the shortest path from S (source node) to all other nodes.
Step-by-Step Execution
Step 1: Initialization
1. Set the distance to the source A as 0.
2. Set the distance to all other nodes as ∞\infinity (indicating they are initially unreachable).
3. Create a table to track distances and predecessors:
S 0 -
A ∞ -
B ∞ -
C ∞ -
D ∞ -
E ∞ -
Iteration 1
Relax edge S→A:
dist(A) = min(∞,0+10) = 10, predecessor = S.
Relax edge S→E:
dist(E) = min(∞,0+8) = 8, predecessor = S.
Relax edge A→C:
dist(C) = min(∞,10+2) = 12, predecessor = A.
Relax edge E→D:
dist(D) = min(∞,8+1) = 9, predecessor = E.
2
Relax edge C→B:
dist(B) = min(∞,12-2) = 10, predecessor = C.
S 0 -
A 10 S
B 10 C
C 12 D
D 9 E
E 8 S
Iteration 2
Relax all edges again.
S 0 -
A 5 S
B 10 C
C 8 D
D 9 E
E 8 S
Iteration 3
Relax all edges again.
S 0 -
A 5 S
3
Node Distance Predecessor
B 5 C
C 7 D
D 9 E
E 8 S
Iteration 4
Relax all edges again.
No changes occur.
S 0 -
A 5 S
B 5 C
C 7 D
D 9 E
E 8 S
Iteration 5
Relax all edges again.
No changes occur.
S 0 -
A 5 S
B 5 C
C 7 D
D 9 E
E 8 S
4
Node Distance Predecessor
Shortest Paths
S → A: Distance = 5.
S → B: Distance = 5.
S → C: Distance = 7.
S → D: Distance = 9.
S → E: Distance = 8.
Python Code
class Graph:
def __init__(self, vertices):
self.V = vertices
self.edges = []
5
# Step 1: Initialize distances from the source to all vertices as
infinite
dist = {i: float("Inf") for i in range(self.V)}
dist[src] = 0 # Distance to source is 0
Python Output
csharp
CopyEdit
Vertex Distance from Source:
0 0
1 5
2 5
3 7
4 9
5 8
Example 2
Consider the following directed graph with weights (some edges have negative weights):
6
From To Weight
S A 10
S E 8
A C 2
B A 1
C B -2
D A -12
D C -1
Goal
Find the shortest path from S (source node) to all other nodes.
Step-by-Step Execution
From To Weight
S A 10
S E 8
A C 2
B A 1
C B -2
D A -12
D C -1
E D 1
Vertex Mapping
S=0
A=1
B=2
C=3
D=4
E=5
7
Step 2: Initialize Distances
Distance to S (0) = 0
Distance to all others = ∞
Iteration 1
S → A: 0 + 10 = 10 (Update A)
S → E: 0 + 8 = 8 (Update E)
A → C: 10 + 2 = 12 (Update C)
C → B: 12 + (-2) = 10 (Update B)
E → D: 8 + 1 = 9 (Update D)
D → A: 9 + (-12) = -3 (Update A)
D → C: 9 + (-1) = 8 (Update C)
B → A: 10 + 1 = 11 (No update since A = -3)
Vertex Distance
S (0) 0
A (1) -3
B (2) 10
C (3) 8
D (4) 9
E (5) 8
Iteration 2
8
A → C: -3 + 2 = -1 (Update C)
C → B: -1 + (-2) = -3 (Update B)
B → A: -3 + 1 = -2 (No update)
D → A: 9 + (-12) = -3 (No update)
D → C: 9 + (-1) = 8 (No update)
Vertex Distance
S (0) 0
A (1) -3
B (2) -3
C (3) -1
D (4) 9
E (5) 8
Iteration 3
A → C: -3 + 2 = -1 (No update)
C → B: -1 + (-2) = -3 (No update)
B → A: -3 + 1 = -2 (No update)
D → A: 9 + (-12) = -3 (No update)
Vertex Distance
S (0) 0
A (1) -3
B (2) -3
C (3) -1
D (4) 9
E (5) 8
Iteration 4 & 5
9
Final Corrected Shortest Distances from S
Python Code
python
CopyEdit
class Graph:
def __init__(self, vertices):
self.V = vertices
self.edges = []
for u, v, w in self.edges:
if dist[u] != float("Inf") and dist[u] + w < dist[v]:
print("Graph contains a negative weight cycle!")
return
# Define the graph with 6 vertices (S=0, A=1, B=2, C=3, D=4, E=5)
g = Graph(6)
10
g.add_edge(0, 1, 10) # S → A
g.add_edge(0, 5, 8) # S → E
g.add_edge(1, 3, 2) # A → C
g.add_edge(2, 1, 1) # B → A
g.add_edge(3, 2, -2) # C → B
g.add_edge(4, 1, -12) # D → A
g.add_edge(4, 3, -1) # D → C
g.add_edge(5, 4, 1) # E → D
Python Output
csharp
CopyEdit
Vertex Distance from Source:
0 0
1 -3
2 -3
3 -1
4 9
5 8
Example 3
Consider the following directed graph with weights (some edges have negative weights):
From To Weight
A B 4
A C 1
B C -3
B D 2
C D 3
D E 2
E B -5
Goal
Find the shortest path from S (source node) to all other nodes.
11
Step-by-Step Execution
Edge Weight
A→B 4
A→C 1
B → C -3
B→D 2
C→D 3
D→E 2
E→B -5
Distance to A = 0
Distance to all other vertices = ∞
Iteration 1
A → B: 0 + 4 = 4 (Update B)
A → C: 0 + 1 = 1 (Update C)
12
B → C: 4 + (-3) = 1 (No update)
B → D: 4 + 2 = 6 (Update D)
C → D: 1 + 3 = 4 (Update D)
D → E: 4 + 2 = 6 (Update E)
E → B: 6 + (-5) = 1 (Update B)
Vertex Distance
A (0) 0
B (1) 1
C (2) 1
D (3) 4
E (4) 6
Iteration 2
A → B: No update
A → C: No update
B → C: 1 + (-3) = -2 (Update C)
B → D: 1 + 2 = 3 (Update D)
C → D: -2 + 3 = 1 (Update D)
D → E: 1 + 2 = 3 (Update E)
E → B: 3 + (-5) = -2 (Update B)
Vertex Distance
A (0) 0
B (1) -2
C (2) -2
D (3) 1
E (4) 3
Iteration 3
B → C: -2 + (-3) = -5 (Update C)
B → D: -2 + 2 = 0 (Update D)
C → D: -5 + 3 = -2 (Update D)
D → E: -2 + 2 = 0 (Update E)
E → B: 0 + (-5) = -5 (Update B)
13
Vertex Distance
A (0) 0
B (1) -5
C (2) -5
D (3) -2
E (4) 0
Iteration 4
B → C: -5 + (-3) = -8 (Update C)
B → D: -5 + 2 = -3 (Update D)
C → D: -8 + 3 = -5 (Update D)
D → E: -5 + 2 = -3 (Update E)
E → B: -3 + (-5) = -8 (Update B)
Vertex Distance
A (0) 0
B (1) -8
C (2) -8
D (3) -5
E (4) -3
Final Conclusion
Since a negative weight cycle was detected (B → C → B keeps decreasing), this is an infinite
loop and shortest paths cannot be determined.
Python Code
14
class Graph:
def __init__(self, vertices):
self.V = vertices # Number of vertices
self.edges = [] # List of edges
Python Output
Example 4
mathematica
15
Copy code
Vertices: {A, B, C, D, E}
1. Initialization:
o Set the distance to the source node (A) to 0.
o Set the distance to all other nodes to infinity (∞).
2. Relax all edges:
o Repeat V−1 times (where V is the number of vertices).
o For each edge (u,v), if the distance to u plus the edge weight is smaller than the
current distance to v, update the distance to v.
3. Check for Negative Weight Cycles:
o After V−1 iterations, check for negative weight cycles by going through each
edge again.
o If any edge can still be relaxed, it indicates a negative weight cycle.
python
Copy code
# Bellman-Ford Algorithm Implementation
return distances
16
# Define the graph edges and vertices
edges = [
('A', 'B', 4),
('A', 'C', 1),
('B', 'C', -2),
('B', 'D', 5),
('C', 'D', 8),
('C', 'E', -3),
('D', 'E', 3)
]
if distances:
print(f"Shortest distances from {source}:")
for vertex, distance in distances.items():
print(f"Distance from {source} to {vertex}: {distance}")
1. Initialization: We initialize the distances from the source vertex (A) to all other vertices
as infinity, except for the source vertex which is set to 0.
2. Relaxation: We perform V−1 iterations, and in each iteration, we check all edges and
update the shortest distances to each vertex.
3. Negative Weight Cycle Detection: After the relaxation steps, we go through the edges
once more to check if any distance can still be updated. If so, it means the graph contains
a negative weight cycle.
Output:
vbnet
Copy code
Shortest distances from A:
Distance from A to A: 0
Distance from A to B: 4
Distance from A to C: 1
Distance from A to D: 9
Distance from A to E: -2
17
1. Initialization:
mathematica
Copy code
Distances: A=0, B=∞, C=∞, D=∞, E=∞
mathematica
Copy code
Distances: A=0, B=4, C=1, D=9, E=-2
If there were any negative weight cycles, the algorithm would detect them after the relaxation
steps and print:
sql
Copy code
Graph contains negative weight cycle
Conclusion
The Bellman-Ford algorithm is capable of handling graphs with negative weights and can detect
negative weight cycles, making it more flexible than Dijkstra's algorithm for certain types of
graphs.
Example 5
Consider a directed graph with 5 vertices (0, 1, 2, 3, 4) and the following edges with weights:
18
(0, 1, -1)
(0, 2, 4)
(1, 2, 3)
(1, 3, 2)
(1, 4, 2)
(3, 2, 5)
(3, 1, 1)
(4, 3, -3)
1. Initialize distances: Set the distance to the source vertex (0) to 0, and all other vertices to
infinity (∞).
bash
CopyEdit
Distance from source (0): [0, ∞, ∞, ∞, ∞]
2. Relax all edges: For each vertex, iterate through all the edges and update the distances if
a shorter path is found.
Repeat this process for V-1 times (where V is the number of vertices, so in this case, we
will repeat the process 4 times).
3. Check for negative weight cycles: After V-1 iterations, if any distance can be updated,
then there is a negative weight cycle in the graph.
We have a graph with 5 vertices (0, 1, 2, 3, 4) and the following weighted directed edges:
(0, 1, -1)
(0, 2, 4)
(1, 2, 3)
(1, 3, 2)
(1, 4, 2)
(3, 2, 5)
(3, 1, 1)
(4, 3, -3)
We will use vertex 0 as the source vertex to calculate the shortest paths to all other vertices.
Step 1: Initialization
19
We initialize the distances to all vertices from the source as follows:
Here, 0 means the distance to the source vertex itself is 0, and infinity (∞) means that initially, all
other vertices are unreachable.
The main part of the Bellman-Ford algorithm is relaxing the edges. Relaxing an edge means
updating the distance of a vertex if we find a shorter path via an edge.
We repeat the relaxation process for V-1 iterations (where V is the number of vertices). In this
case, V = 5, so we perform the relaxation for 4 iterations.
Iteration 1:
20
6. Edge (3, 2, 5):
o Current distance to vertex 2: 2
o Distance to vertex 2 via vertex 3: 1 + 5 = 6
o Since 6 > 2, no update is made.
o Distance array remains the same: [0, -1, 2, 1, 1]
7. Edge (3, 1, 1):
o Current distance to vertex 1: -1
o Distance to vertex 1 via vertex 3: 1 + 1 = 2
o Since 2 > -1, no update is made.
o Distance array remains the same: [0, -1, 2, 1, 1]
8. Edge (4, 3, -3):
o Current distance to vertex 3: 1
o Distance to vertex 3 via vertex 4: 1 + (-3) = -2
o Since -2 < 1, we update the distance to vertex 3.
o New distance array: [0, -1, 2, -2, 1]
csharp
CopyEdit
[0, -1, 2, -2, 1]
Iteration 2:
csharp
CopyEdit
[0, -1, 2, -2, 1]
Iterations 3 and 4:
Since no further updates are made in these iterations (the distances stay the same), the algorithm
terminates early.
21
Step 3: Check for Negative Weight Cycles
After the V-1 iterations (4 iterations in this case), we check whether any distance can still be
updated. If we find an edge where the distance to the destination can still be improved, it
indicates the presence of a negative weight cycle.
In our example, there are no such updates, so the graph does not contain a negative weight cycle.
Final Output
yaml
CopyEdit
Vertex 0: 0
Vertex 1: -1
Vertex 2: 2
Vertex 3: -2
Vertex 4: 1
Conclusion
The Bellman-Ford algorithm successfully computes the shortest paths from the source
vertex (0) to all other vertices.
The algorithm handles negative edge weights and does not detect any negative weight
cycles in this graph.
Python Code
python
CopyEdit
class Edge:
def __init__(self, u, v, weight):
self.u = u
self.v = v
self.weight = weight
22
for _ in range(vertices - 1):
for edge in edges:
if distances[edge.u] != float("inf") and distances[edge.u] +
edge.weight < distances[edge.v]:
distances[edge.v] = distances[edge.u] + edge.weight
return distances
# Run Bellman-Ford
distances = bellman_ford(vertices, edges, source)
if distances:
print("Shortest distances from source vertex 0:")
for i in range(vertices):
print(f"Vertex {i}: {distances[i]}")
Python Output
yaml
CopyEdit
Shortest distances from source vertex 0:
Vertex 0: 0
Vertex 1: -1
Vertex 2: 2
Vertex 3: -2
Vertex 4: 1
Explanation
The algorithm calculates the shortest distances from vertex 0 to all other vertices.
23
The final distances are:
o From 0 to 0: 0
o From 0 to 1: -1
o From 0 to 2: 2
o From 0 to 3: -2
o From 0 to 4: 1
The algorithm correctly handles negative weights, and after V-1 iterations, the shortest paths are
found. If there were any negative weight cycles, the algorithm would report it.
24