Skip to content

Commit 48910f0

Browse files
authored
Merge pull request #2107 from kosuri-indu/add/bellman-ford
Added: DP Algortihms - Bellman-Ford Algorithm
2 parents f5390b4 + 3e08a7c commit 48910f0

File tree

1 file changed

+277
-0
lines changed

1 file changed

+277
-0
lines changed
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
---
2+
id: bellman-ford-algorithm
3+
title: Bellman-Ford Algorithm
4+
sidebar_label: Bellman-Ford Algorithm
5+
tags: [python, java, c++, programming, algorithms, dynamic programming, graph, tutorial, in-depth]
6+
description: In this tutorial, we will learn about the Bellman-Ford Algorithm and its solution using Dynamic Programming in Python, Java, and C++ with detailed explanations and examples.
7+
---
8+
9+
# Bellman-Ford Algorithm
10+
11+
The Bellman-Ford algorithm is a classic algorithm for finding the shortest paths in a weighted graph with negative weights. It is capable of handling graphs with negative edge weights and can also detect negative weight cycles.
12+
13+
## Problem Statement
14+
15+
Given a graph and a source vertex, find the shortest paths from the source vertex to all other vertices in the graph.
16+
17+
### Intuition
18+
19+
The algorithm iteratively relaxes the edges of the graph. The idea is to improve the estimate of the shortest path step by step. It takes up to `|V| - 1` iterations, where `|V|` is the number of vertices, to ensure that the shortest paths are found. If we perform one more iteration and still find a shorter path, it indicates the presence of a negative weight cycle.
20+
21+
## Dynamic Programming Approach
22+
23+
Using dynamic programming, we maintain an array `dist` where `dist[i]` holds the shortest distance from the source vertex to vertex `i`.
24+
25+
## Pseudocode for Bellman-Ford Algorithm using DP
26+
27+
#### Initialize:
28+
29+
```markdown
30+
dist[source] = 0
31+
for i from 1 to |V| - 1:
32+
for each edge (u, v) with weight w:
33+
if dist[u] + w < dist[v]:
34+
dist[v] = dist[u] + w
35+
36+
for each edge (u, v) with weight w:
37+
if dist[u] + w < dist[v]:
38+
print("Graph contains a negative weight cycle")
39+
return
40+
```
41+
42+
### Example Output:
43+
44+
Given the graph:
45+
46+
- `Vertices: {0, 1, 2, 3}`
47+
- `Edges: {(0, 1, 1), (1, 2, 3), (2, 3, 2), (3, 1, -6)}`
48+
49+
The set can be partitioned into two subsets with equal sum.
50+
51+
### Output Explanation:
52+
53+
The shortest distances from the source vertex 0 to all other vertices are:
54+
55+
- `0 -> 1: 1`
56+
- `0 -> 2: 4`
57+
- `0 -> 3: 6`
58+
59+
By following the Bellman-Ford algorithm, the shortest path distances from the source vertex 0 to vertices 1, 2, and 3 are found to be 1, 4, and 6 respectively.
60+
61+
## Implementing Bellman-Ford Algorithm using DP
62+
63+
### Python Implementation
64+
65+
```python
66+
class Graph:
67+
def __init__(self, vertices):
68+
self.V = vertices
69+
self.graph = []
70+
71+
def add_edge(self, u, v, w):
72+
self.graph.append([u, v, w])
73+
74+
def bellman_ford(self, src):
75+
dist = [float("Inf")] * self.V
76+
dist[src] = 0
77+
78+
for _ in range(self.V - 1):
79+
for u, v, w in self.graph:
80+
if dist[u] != float("Inf") and dist[u] + w < dist[v]:
81+
dist[v] = dist[u] + w
82+
83+
for u, v, w in self.graph:
84+
if dist[u] != float("Inf") and dist[u] + w < dist[v]:
85+
print("Graph contains a negative weight cycle")
86+
return
87+
88+
print("Vertex Distance from Source")
89+
for i in range(self.V):
90+
print(f"{i}\t\t{dist[i]}")
91+
92+
g = Graph(4)
93+
g.add_edge(0, 1, 1)
94+
g.add_edge(1, 2, 3)
95+
g.add_edge(2, 3, 2)
96+
g.add_edge(3, 1, -6)
97+
98+
g.bellman_ford(0)
99+
```
100+
101+
### Java Implementation
102+
103+
```java
104+
import java.util.*;
105+
106+
class Graph {
107+
class Edge {
108+
int src, dest, weight;
109+
Edge() {
110+
src = dest = weight = 0;
111+
}
112+
};
113+
114+
int V, E;
115+
Edge edge[];
116+
117+
Graph(int v, int e) {
118+
V = v;
119+
E = e;
120+
edge = new Edge[e];
121+
for (int i = 0; i < e; ++i)
122+
edge[i] = new Edge();
123+
}
124+
125+
void BellmanFord(Graph graph, int src) {
126+
int V = graph.V, E = graph.E;
127+
int dist[] = new int[V];
128+
129+
Arrays.fill(dist, Integer.MAX_VALUE);
130+
dist[src] = 0;
131+
132+
for (int i = 1; i < V; ++i) {
133+
for (int j = 0; j < E; ++j) {
134+
int u = graph.edge[j].src;
135+
int v = graph.edge[j].dest;
136+
int weight = graph.edge[j].weight;
137+
if (dist[u] != Integer.MAX_VALUE && dist[u] + weight < dist[v])
138+
dist[v] = dist[u] + weight;
139+
}
140+
}
141+
142+
for (int j = 0; j < E; ++j) {
143+
int u = graph.edge[j].src;
144+
int v = graph.edge[j].dest;
145+
int weight = graph.edge[j].weight;
146+
if (dist[u] != Integer.MAX_VALUE && dist[u] + weight < dist[v])
147+
System.out.println("Graph contains a negative weight cycle");
148+
}
149+
150+
printArr(dist, V);
151+
}
152+
153+
void printArr(int dist[], int V) {
154+
System.out.println("Vertex Distance from Source");
155+
for (int i = 0; i < V; ++i)
156+
System.out.println(i + "\t\t" + dist[i]);
157+
}
158+
159+
public static void main(String[] args) {
160+
Graph graph = new Graph(4, 4);
161+
162+
graph.edge[0].src = 0;
163+
graph.edge[0].dest = 1;
164+
graph.edge[0].weight = 1;
165+
166+
graph.edge[1].src = 1;
167+
graph.edge[1].dest = 2;
168+
graph.edge[1].weight = 3;
169+
170+
graph.edge[2].src = 2;
171+
graph.edge[2].dest = 3;
172+
graph.edge[2].weight = 2;
173+
174+
graph.edge[3].src = 3;
175+
graph.edge[3].dest = 1;
176+
graph.edge[3].weight = -6;
177+
178+
graph.BellmanFord(graph, 0);
179+
}
180+
}
181+
```
182+
### C++ Implementation
183+
184+
```cpp
185+
#include <bits/stdc++.h>
186+
using namespace std;
187+
188+
struct Edge {
189+
int src, dest, weight;
190+
};
191+
192+
struct Graph {
193+
int V, E;
194+
struct Edge* edge;
195+
};
196+
197+
struct Graph* createGraph(int V, int E) {
198+
struct Graph* graph = (struct Graph*) malloc(sizeof(struct Graph));
199+
graph->V = V;
200+
graph->E = E;
201+
graph->edge = (struct Edge*) malloc(graph->E * sizeof(struct Edge));
202+
return graph;
203+
}
204+
205+
void printArr(int dist[], int n) {
206+
cout << "Vertex Distance from Source" << endl;
207+
for (int i = 0; i < n; ++i)
208+
cout << i << "\t\t" << dist[i] << endl;
209+
}
210+
211+
void BellmanFord(struct Graph* graph, int src) {
212+
int V = graph->V;
213+
int E = graph->E;
214+
int dist[V];
215+
216+
for (int i = 0; i < V; i++)
217+
dist[i] = INT_MAX;
218+
dist[src] = 0;
219+
220+
for (int i = 1; i <= V - 1; i++) {
221+
for (int j = 0; j < E; j++) {
222+
int u = graph->edge[j].src;
223+
int v = graph->edge[j].dest;
224+
int weight = graph->edge[j].weight;
225+
if (dist[u] != INT_MAX && dist[u] + weight < dist[v])
226+
dist[v] = dist[u] + weight;
227+
}
228+
}
229+
230+
for (int i = 0; i < E; i++) {
231+
int u = graph->edge[i].src;
232+
int v = graph->edge[i].dest;
233+
int weight = graph->edge[i].weight;
234+
if (dist[u] != INT_MAX && dist[u] + weight < dist[v]) {
235+
cout << "Graph contains a negative weight cycle" << endl;
236+
return;
237+
}
238+
}
239+
240+
printArr(dist, V);
241+
}
242+
243+
int main() {
244+
int V = 4;
245+
int E = 4;
246+
struct Graph* graph = createGraph(V, E);
247+
248+
graph->edge[0].src = 0;
249+
graph->edge[0].dest = 1;
250+
graph->edge[0].weight = 1;
251+
252+
graph->edge[1].src = 1;
253+
graph->edge[1].dest = 2;
254+
graph->edge[1].weight = 3;
255+
256+
graph->edge[2].src = 2;
257+
graph->edge[2].dest = 3;
258+
graph->edge[2].weight = 2;
259+
260+
graph->edge[3].src = 3;
261+
graph->edge[3].dest = 1;
262+
graph->edge[3].weight = -6;
263+
264+
BellmanFord(graph, 0);
265+
266+
return 0;
267+
}
268+
```
269+
270+
## Complexity Analysis
271+
272+
- Time Complexity: $O(V \times E)$, where V is the number of vertices and E is the number of edges.
273+
- Space Complexity: $O(V)$, for storing the distance array.
274+
275+
## Conclusion
276+
277+
The Bellman-Ford algorithm provides an efficient solution for finding the shortest paths in a graph with negative weights and can also detect negative weight cycles. This technique is useful in various applications, including network routing and financial modeling.

0 commit comments

Comments
 (0)