1. Home
Data Structure

Data Structure Tutorial: Everything You Need to Know

Learn all about data structures with our comprehensive tutorial. Master the fundamentals and advance your skills in organizing and managing data efficiently.

  • 60
  • 14
right-top-arrow

Tutorial Playlist

58 Lessons
28

Bellman-Ford Algorithm Examples, Implementation, Applications & More

Updated on 09/08/2024444 Views

Introduction

Imagine a scenario where you are planning a road trip to multiple destinations. Your goal is to find the shortest route from your starting point to the destinations. The Bellman-Ford Algorithm does the same thing—i.e., it finds the shortest and quickest way to get from one point to another in a network.

Graphs hold a powerful place in computer science, showing relationships between diverse applications from network routing to social network analysis. These relationships are further quantified with weights, and that is where the Bellman-Ford Algorithm comes into play.

In this guide, we will help you understand this algorithm in detail. So, whether you have just started out or know about this algorithm, we ensure you will have a clear and complete understanding of the Bellman-Ford Algorithm by the end of this tutorial. So, let’s get started.

Overview

Named after the famous mathematicians Richard Bellman and Lester Ford, the Bellman-Ford Algorithm is a dynamic programming approach to find the shortest paths from a single source vertex to all other vertices in a weighted graph. This algorithm can handle graphs with negative weights where alternative algorithms might not work.

This all-in-one guide will walk you through the implementation, applications, how the algorithm works, drawbacks, and its time complexities.

How Does Bellman Ford Algorithm Work?

Let’s walk through a simple Bellman-Ford Algorithm example to understand how it works. Consider the following directed graph:

A --(1)--> B --(3)--> C

^ |

|___________|

(-1)

As you can see in this graph, the three vertices “A, B and C” are connected with weights mentioned in bracket (). Our goal is to find the shortest path from A to all other vertices.

Step 1: We will begin with setting distances to A, B, and C, i.e., A: 0, B: ∞ and C: ∞ and performing the initial relaxation

Step 2: The next step is to determine the number of iterations. To do so, we use “V-1,” where V is the number of vertices.

Step 3: In each iteration, the algorithm will go through all the edges and update the distance if a shorter path is discovered. If the new distance is less than the previous one, update the distance for each edge in each iteration. The distance to each node represents the total distance from the starting node to that specific node.

Iteration 1:

Relax edges:

A -> B: distance[B] = min(∞, 0 + 1) = 1

A -> C: distance[C] = min(∞, 0 + (-1)) = -1

B -> C: distance[C] = min(∞, 1 + 3) = 4

Updated distances: A: 0, B: 1, C: 4

Iteration 2:

Relax edges:

A -> B: distance[B] = min(1, 0 + 1) = 1

A -> C: distance[C] = min(-1, 0 + (-1)) = -1

B -> C: distance[C] = min(4, 1 + 3) = 4

Step 4: Check for negative weight cycles

As the graph is acyclic, so after two iterations, the algorithm will stop.

Hence, the final distances are A: 0, B: 1 and C: 4.

Further in this guide, we will understand the implementation of the Bellman-Ford Algorithm using a simple code.

Implementation of Bellman Ford Algorithm

Here is a simple Python implementation of the Bellman-Ford Algorithm:

def bellman_ford(graph, start):

# Step 1: Initialization

distances = {vertex: float('infinity') for vertex in graph}

distances[start] = 0

# Step 2-4: Iterative Relaxation

for _ in range(len(graph) - 1):

for vertex in graph:

for neighbor, weight in graph[vertex]:

if distances[vertex] + weight < distances[neighbor]:

distances[neighbor] = distances[vertex] + weight

# Step 5: Check for Negative Cycles (Optional)

for vertex in graph:

for neighbor, weight in graph[vertex]:

if distances[vertex] + weight < distances[neighbor]:

raise ValueError("Graph contains a negative weight cycle")

return distances

# Example Usage:

graph_example = {

'A': [('B', 1), ('C', -1)],

'B': [('C', 3)],

'C': []

}

start_vertex = 'A'

result_distances = bellman_ford(graph_example, start_vertex)

print(result_distances)

Negative Weights in the Bellman-Ford Algorithm

Negative weights in a graph are less than or equal to zero. Unlike other algorithms, Bellman-Ford can easily handle graphs with negative weights, making it ideal for various scenarios.

Here are certain aspects related to negative weight in the Bellman-Ford Algorithm:

Edges with Negative Weights

If you look at a traditional graph, you will find that the weights on edges are generally non-negative. But in certain scenarios, you can experience negative weights, too. A common situation is where traversing an edge results in a gain or cost, and that gain is negative. During the iterative relaxation process, the Bellman-Ford Algorithm can accommodate these negative weights.

Detecting Negative Weight

Bellman Ford Algorithm can detect any negative weight present in the graph. If after the V-1 iteration, an additional iteration is performed, and during this iteration, if further relaxation is possible, that means there is a negative weight in the graph.

A --(-2)--> B --(3)--> C

Here, you can see a negative weight between A and B. When you apply the Bellman-Ford Algorithm to this graph, it can easily handle the negative weight, and the final distances would be A: 0, B: -2 and C: 1

Negative Weight Cycles

Negative weight cycles can introduce complexity into a graph. Cycles in which the sum of the weights of the edges is negative are considered negative weight cycles.

Let us understand the negative weight cycle with a simple example:

A --2--> B --(-1)--> C --(-3)--> A

In this case, it is clear that the sum of the edges' weight is negative; hence, it is a negative weight cycle that could lead to an infinitely decreasing path. Bellman Ford Algorithm can detect the negative cycle easily.

Handling Negative Weight Cycles

Handling the negative weight cycle is crucial to prevent the graph from entering an infinite loop. Common ways to handle negative weight cycles include:

  • Marking affected vertices.
  • Setting distances to negative infinity.
  • Additional checks should be implemented to identify and address the issue.

Drawback of Bellman Ford Algorithm

Although this algorithm is quite powerful and helpful, it has certain limitations and challenges. Let’s address the significant drawbacks of the Bellman-Ford Algorithm here:

Slower Convergence

The Bellman-Ford Algorithm has a slower convergence rate than other algorithms like Dijkstra. Its time complexity is O(V * E), where V is the number of vertices and E is the number of edges, making it less effective for dense graphs.

Handling of Negative Weight Cycle

Though the Bellman-Ford Algorithm can handle the negative weight, it might fail when handling negative weight cycles. The algorithm might not provide meaningful results and may require you to take additional measures to handle this issue.

Multiple Shortest Paths

If a graph contains multiple paths with the same minimum distance, the algorithm might not provide unique results. It can provide different results depending upon the order in which edges are processed.

Redundant Iterations

There are cases where the Bellman-Ford Algorithm might perform more iterations than needed. Further iteration is not required when finding the shortest distance, as it won’t give any new results. But even then, the algorithm continues to perform the specified number of iterations.

No Priority Queue

The Bellman-Ford Algorithm does not use a priority queue, which makes it less efficient in some cases, such as dealing with large graphs.

Bellman Ford Algorithm Vs Dijkstra Algorithm

Let us understand the difference between the Bellman-Ford and Dijkstra Algorithm using a comparison table:

Feature

Bellman-Ford

Dijkstra

Graph types

Used for directed and undirected graph

Used for graphs with non-negative weights

Edge weights

Ideal for negative edge weights

Not suitable for negative edge weights

Time complexity

O(V * E), where V is vertices, and E is edges.

O((V + E) * log(V)), where V is vertices, and E is edges.

Initialization

Distances are initialized with infinity

Distances are initialized with infinity

Priority queue

Does not use a priority queue

Uses priority queue for efficiency

Handling negative cycles

Can detect and handle negative weight cycle

Cannot handle negative weight cycle

Applications of Bellman Ford Algorithm

Due to its ability to handle negative weights, the Bellman-Ford Algorithm offers applications in various domains. Following are the five typical applications of this algorithm:

Network routing

Bellman-Ford Algorithm can be used to find the shortest distance between networks, and it is commonly used in network routing protocols like RIP (Routing Information Protocol) and EIGRP (Enhanced Interior Gateway Routing Protocol).

Telecommunications network design

This algorithm is used to reduce the overall delay and cost associated with data transmission in telecommunication network.

Traffic engineering

In traffic engineering, the Bellman Ford Algorithm is used to find the most suitable route for vehicles considering road congestion, capacity and travel times.

Finance sector

Using the Bellman-Ford Algorithm in the finance sector can help detect arbitrage opportunities in currency exchange or stock markets.

Robotics path planning

This algorithm is essential for robotic path planning and assists robots in navigating through environments. It determines the most efficient paths while considering obstacles and optimizing the overall travel distance.

Bellman Ford Algorithm Pseudocode

Now, let us understand the Bellman-Ford Algorithm pseudocode:

function BellmanFord(Graph, source):

for each vertex v in Graph:

distance[v] = INFINITY

predecessor[v] = NULL

distance[source] = 0

for i from 1 to |V| - 1:

for each edge (u, v) in Graph:

if distance[u] + weight(u, v) < distance[v]:

distance[v] = distance[u] + weight(u, v)

predecessor[v] = u

for each edge (u, v) in Graph:

if distance[u] + weight(u, v) < distance[v]:

// Negative weight cycle detected

return "Graph contains a negative weight cycle"

return (distance, predecessor)

Where,

Graph- graph with vertices and weighted edges.

Source- source vertex from which the shortest paths are calculated.

Distance- minimum distance from the source to each vertex.

Predecessor- array to store the predecessor vertex on the shortest path to each vertex.

weight(u, v)- weight of the edge from vertex u to vertex v.

|V|- number of vertices in the graph.

Complexity of Bellman Ford Algorithm

Now, let’s talk about the time complexities of the Bellman-Ford Algorithm in the data structure. Here, we have shared about the worst-case, average-case and best-case time complexity:

Worst-Case Time Complexity

The worst-case time complexity of the Bellman-Ford Algorithm is determined by O(V * E), where V is the number of vertices and E is the number of edges. This case occurs when the maximum number of iterations is required to ensure convergence. Each iteration considers all edges for relaxation, leading to a total of (V-1) * E edge checks.

Average-Case Time Complexity

The average-case time complexity in most scenarios is also O(V * E). The algorithm influences the average case, which typically requires several iterations close to (V-1), where V is the number of vertices. This is because the shortest paths generally converge after a relatively small number of iterations in a well-behaved graph without negative weight cycles. However, the worst-case complexity dominates the average-case complexity.

Best-Case Time Complexity

In the best-case scenario, the Bellman-Ford algorithm can achieve a time complexity of O(V^2) when the algorithm converges after a small number of iterations. This best-case scenario can occur when the graph is well-behaved, with relatively few edges and a straightforward convergence of shortest paths.

Conclusion

That marks the end of our tutorial. We hope you now have a firm grasp of the Bellman-Ford Algorithm. The algorithm is a specific solution used in various domains and industries to find the shortest paths in graphs. Its ability to handle negative weights also gives it an upper hand where other algorithms might fail.

FAQs

1. What is the Bellman-Ford algorithm?

The Bellman-Ford Algorithm finds the shortest path between vertices in a graph. This algorithm is beneficial when negative weights are involved.

2. What is the difference between Bellman-Ford and Dijkstra?

The significant difference between Bellman-Ford and Dijkstra is that Bellman-Ford can detect and handle negative weights, while Dijkstra cannot. Also, Bellman-Ford does not use a priority queue, while Dijkstra does.

3.Is Bellman-Ford a greedy algorithm?

No, Bellman-Ford is not a greedy algorithm. It is a dynamic programming algorithm that explores all possible paths from the source vertex to all other vertices and updates the distance in each iteration.

4. What is the time complexity of Bellman-Ford?

The worst and average time complexity of Bellman-Ford is O(V * E), while the best time complexity is O(V^2).

5. What is the Dijkstra and Bellman-Ford algorithm?

Dijkstra is a greedy algorithm used to find the shortest distance between two vertices in non-negative weighted graphs. On the other hand, Bellman-Ford is a dynamic programming algorithm used to find the shortest path between non-negative and negative weighted graphs.

6. Why do we use the Bellman-Ford algorithm?

We use the Bellman-Ford algorithm to find the shortest path between two vertices in a graph.

7. Why is Dijkstra faster than Bellman-Ford?

Dijkstra uses a priority queue, which increases its efficiency and makes it faster than the Bellman-Ford algorithm.

8. What is called a greedy algorithm?

A greedy algorithm selects the best option at each decision point without considering the previous options.

9. What is the difference between Bellman-Ford and Floyd Warshall?

The critical difference between Bellman-Ford and Floyd Warshall is that unlike the former, the latter finds the shortest paths between all vertices pairs in a weighted graph with positive and negative edge weights.

Rohan Vats

Rohan Vats

Passionate about building large scale web apps with delightful experiences. In pursuit of transforming engineers into leaders.

Get Free Career Counselling
form image
+91
*
By clicking, I accept theT&Cand
Privacy Policy
image
right-top-arrowleft-top-arrow

upGrad Learner Support

Talk to our experts. We’re available 24/7.

text

Indian Nationals

1800 210 2020

text

Foreign Nationals

+918045604032

Disclaimer

upGrad does not grant credit; credits are granted, accepted or transferred at the sole discretion of the relevant educational institution offering the diploma or degree. We advise you to enquire further regarding the suitability of this program for your academic, professional requirements and job prospects before enr...