Graph Theory - Bellman-Ford Algorithm



Bellman-Ford Algorithm

The Bellman-Ford Algorithm is used to find the shortest paths from a single source vertex to all other vertices in a weighted graph.

Unlike Dijkstra's algorithm, Bellman-Ford can handle graphs with negative edge weights, making it more versatile.

Bellman-Ford Algorithm Overview

The Bellman-Ford algorithm uses a dynamic programming approach to find the shortest paths. It iteratively relaxes the edges of the graph, updating the shortest path estimates, until no more improvements can be made or until a negative weight cycle is detected.

The steps of the Bellman-Ford algorithm are as follows −

  • Initialize the distance of the source node to zero and all other nodes to infinity.
  • For each vertex, repeatedly relax all edges. In each iteration, update the distances to the neighboring nodes if a shorter path is found.
  • After V-1 iterations (where V is the number of vertices), check for negative weight cycles by iterating through all edges again. If any distance can be updated, a negative weight cycle exists.
  • The algorithm ends when no more updates can be made or when a negative weight cycle is detected.

Example of Bellman-Ford Algorithm

Let us understand the algorithm with an example. Consider the following weighted graph −

Bellman-Ford Algorithm

The graph is represented as follows:

  • A is connected to B (weight 4) and C (weight 2).
  • B is connected to C (weight 1) and E (weight -3).
  • C is connected to B (weight 3) and D (weight 4).
  • D is connected to E (weight 2).
  • E is connected to D (weight -1).

We will run Bellman-Ford's algorithm starting from node A.

Initialize the distances as follows:

  • Distance to A = 0
  • Distance to B =
  • Distance to C =
  • Distance to D =
  • Distance to E =

Step 1: First Iteration

Relax all edges:

  • Distance to B = 4 (A B)
  • Distance to C = 2 (A C)
  • Distance to D =
  • Distance to E =

Step 2: Second Iteration

Relax all edges again:

  • Distance to B = 4 (unchanged)
  • Distance to C = 2 (unchanged)
  • Distance to D = 6 (C D with weight 4)
  • Distance to E = 1 (B E with weight -3)

Step 3: Third Iteration

Relax all edges again:

  • Distance to B = 4 (unchanged)
  • Distance to C = 2 (unchanged)
  • Distance to D = 0 (E D with weight -1)
  • Distance to E = 1 (unchanged)

Step 4: Fourth Iteration

Relax all edges again:

  • Distance to B = 4 (unchanged)
  • Distance to C = 2 (unchanged)
  • Distance to D = 0 (unchanged)
  • Distance to E = 1 (unchanged)

Checking for Negative Weight Cycles

After V-1 iterations, check for negative weight cycles. If any distance can be updated, a negative weight cycle exists. In this example, no distances can be updated, so there are no negative weight cycles.

Final Distances

The shortest distances from node A to all other nodes are −

  • Distance to A = 0
  • Distance to B = 4
  • Distance to C = 2
  • Distance to D = 0
  • Distance to E = 1

Complexity of Bellman-Ford Algorithm

The time complexity of the Bellman-Ford algorithm is O(VE), where V is the number of vertices and E is the number of edges. This is because we perform V-1 iterations of relaxing all edges and one additional iteration to check for negative weight cycles.

The space complexity of Bellman-Fords algorithm is O(V) since we need to store the distances for all vertices.

Applications of Bellman-Ford Algorithm

Bellman-Ford's algorithm has various real-world applications, such as −

  • Network Routing: Bellman-Ford is used in distance-vector routing protocols such as RIP (Routing Information Protocol) and BGP (Border Gateway Protocol).
  • Currency Arbitrage: It is used in financial markets to detect arbitrage opportunities by finding negative weight cycles in currency exchange graphs.
  • Resource Allocation: Bellman-Ford is also used in resource optimization problems where edge weights can be negative, such as in project scheduling and cost optimization.
  • Graph Analysis: It is used to find the shortest paths in graphs with negative weights, which can arise in various real-world problems.

Bellman-Ford Algorithm in Python

Following is an implementation of the Bellman-Ford algorithm in Python −

def bellman_ford(graph, start):
   # Initialize distances
   distances = {node: float('inf') for node in graph}
   distances[start] = 0

   # Relax edges repeatedly
   for _ in range(len(graph) - 1):
      for node in graph:
         for neighbor, weight in graph[node]:
            if distances[node] + weight < distances[neighbor]:
                  distances[neighbor] = distances[node] + weight

   # Check for negative weight cycles
   for node in graph:
      for neighbor, weight in graph[node]:
         if distances[node] + weight < distances[neighbor]:
            raise ValueError("Graph contains a negative weight cycle")

   return distances

# Example graph (Adjacency list representation)
graph = {
   'A': [('B', 4), ('C', 2)],
   'B': [('C', 1), ('D', 2), ('E', -3)],
   'C': [('B', 3), ('D', 4)],
   'D': [('E', 2)],
   'E': [('D', -1)]
}

# Executing Bellman-Ford algorithm starting from node A
distances = bellman_ford(graph, 'A')
print(distances)

This implementation calculates the shortest distances from node A to all other nodes in the graph −

{'A': 0, 'B': 4, 'C': 2, 'D': 0, 'E': 1}
Advertisements