Bellman-Ford Algorithm:
The Bellman-Ford algorithm is a single-source shortest-path algorithm that works by iteratively relaxing edges in the graph until the shortest path to all vertices is found. It is especially useful for graphs with negative edge weights, as it can detect negative cycles and return a suitable error message.
Floyd-Warshall Algorithm:
The Floyd-Warshall algorithm is a multi-source shortest path algorithm that works by computing the shortest path between all pairs of vertices in the graph using dynamic programming. It is known for its simplicity and ease of implementation, making it a popular choice in many applications.
In this article, we will compare and contrast the Bellman-Ford algorithm and the Floyd-Warshall algorithm, examining their respective strengths and weaknesses, time and space complexity, and implementation details.
As we know that both of these algorithms work on Directed Graphs, Let us take a common example to understand the approaches of these algorithms.
Bellman-ford’s Algorithm
The Bellman-Ford algorithm can be implemented as follows:
- Initialize the distance from the source vertex (i.e. 0) to all other vertices in the graph to infinity, except for the distance from the source vertex to itself, which is 0.
- For each vertex in the graph, repeat the following process |V|-1 times (where |V| is the number of vertices in the graph):
- For each edge (u, v) in the graph, where u is the source vertex and v is the destination vertex, relax the edge by updating the distance to v if the distance to u plus the weight of (u, v) is less than the current distance to v.
- After the (|V|-1)th iteration, check for the presence of negative cycles by iterating over all the edges in the graph and checking if any of them can still be relaxed. If so, then a negative cycle is present, and the algorithm returns a suitable error message.
Here’s how the algorithm would work:
- Initialize the distance from A to all other vertices to infinity, except for the distance from A to itself, which is 0: dist[0] = 0.
- Repeat the process of relaxing edges 5 times (|V|-1 = 6-1 = 5) to relax all edges in the graph.
- Check for negative cycles by iterating over all edges in the graph. In this case, there are no negative cycles, as all edges have been relaxed in the previous step.
Hence our distance from source 0 to each node will look like this,
Implementation of Bellman-Ford’s Algorithm:
// C++ code for the above approach: #include <bits/stdc++.h> using namespace std;
class Solution {
public :
void shortest_paths(vector<vector< int > >& grid, int V)
{
vector< int > dist(V, 1e9);
// Taking 0 as our source
dist[0] = 0;
// Relaxing V-1 times
for ( int i = 0; i < V; i++) {
// For each value in the given
// vector of [u, v, wt]
for ( auto it : grid) {
int u = it[0];
int v = it[1];
int wt = it[2];
// If there exist a better
// distance and pvs dist
// of u should not
// be infinite
if (dist[u] != 1e9
&& dist[u] + wt < dist[v]) {
dist[v] = dist[u] + wt;
}
}
}
// If negetive cycle exist then
// it will still reduce for
// Vth traversal
for ( auto it : grid) {
int u = it[0];
int v = it[1];
int wt = it[2];
if (dist[u] != 1e9 && dist[u] + wt < dist[v]) {
cout << "ERROR ALERT, Negetive Cycle exists"
<< endl;
}
}
cout << "The shortest distances from " << endl;
for ( int i = 0; i < V; i++) {
cout << " 0 to " << i << " ---> " << dist[i]
<< endl;
}
}
}; // Driver code int main()
{ int V = 6;
vector<vector< int > > grid
= { { 0, 1, 2 }, { 0, 3, 5 }, { 0, 4, 3 }, { 1, 0, 3 }, { 1, 5, 6 }, { 1, 2, 2 }, { 1, 3, 2 }, { 2, 5, 1 }, { 2, 3, 1 }, { 3, 4, 1 }, { 4, 3, 2 } };
Solution s1;
// Function call
s1.shortest_paths(grid, V);
return 0;
} |
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
class Solution {
public void shortestPaths(List<List<Integer>> grid, int V) {
int [] dist = new int [V];
Arrays.fill(dist, Integer.MAX_VALUE);
// Taking 0 as our source
dist[ 0 ] = 0 ;
// Relaxing V-1 times
for ( int i = 0 ; i < V; i++) {
// For each value in the given
// list of [u, v, wt]
for (List<Integer> it : grid) {
int u = it.get( 0 );
int v = it.get( 1 );
int wt = it.get( 2 );
// If there exists a better
// distance and the previous distance
// of u should not be infinite
if (dist[u] != Integer.MAX_VALUE
&& dist[u] + wt < dist[v]) {
dist[v] = dist[u] + wt;
}
}
}
// If a negative cycle exists, it will still reduce for
// Vth traversal
for (List<Integer> it : grid) {
int u = it.get( 0 );
int v = it.get( 1 );
int wt = it.get( 2 );
if (dist[u] != Integer.MAX_VALUE && dist[u] + wt < dist[v]) {
System.out.println( "ERROR ALERT, Negative Cycle exists" );
}
}
System.out.println( "The shortest distances from:" );
for ( int i = 0 ; i < V; i++) {
System.out.println( "0 to " + i + " ---> " + dist[i]);
}
}
} public class Main {
public static void main(String[] args) {
int V = 6 ;
List<List<Integer>> grid = new ArrayList<>();
grid.add(Arrays.asList( 0 , 1 , 2 ));
grid.add(Arrays.asList( 0 , 3 , 5 ));
grid.add(Arrays.asList( 0 , 4 , 3 ));
grid.add(Arrays.asList( 1 , 0 , 3 ));
grid.add(Arrays.asList( 1 , 5 , 6 ));
grid.add(Arrays.asList( 1 , 2 , 2 ));
grid.add(Arrays.asList( 1 , 3 , 2 ));
grid.add(Arrays.asList( 2 , 5 , 1 ));
grid.add(Arrays.asList( 2 , 3 , 1 ));
grid.add(Arrays.asList( 3 , 4 , 1 ));
grid.add(Arrays.asList( 4 , 3 , 2 ));
Solution s1 = new Solution();
// Function call
s1.shortestPaths(grid, V);
}
} |
# python code for the above approach: class Solution:
def shortest_paths( self , grid, V):
dist = [ float ( 'inf' )] * V
# Taking 0 as our source
dist[ 0 ] = 0
# Relaxing V-1 times
for i in range (V):
# For each value in the given
# list of [u, v, wt]
for u, v, wt in grid:
# If there exists a better
# distance and previous dist
# of u should not be infinite
if dist[u] ! = float ( 'inf' ) and dist[u] + wt < dist[v]:
dist[v] = dist[u] + wt
# If negative cycle exists then
# it will still reduce for
# Vth traversal
for u, v, wt in grid:
if dist[u] ! = float ( 'inf' ) and dist[u] + wt < dist[v]:
print ( "ERROR ALERT, Negative Cycle exists" )
print ( "The shortest distances from " )
for i in range (V):
print ( " 0 to" , i, "--->" , dist[i])
# Driver code if __name__ = = "__main__" :
V = 6
grid = [[ 0 , 1 , 2 ], [ 0 , 3 , 5 ], [ 0 , 4 , 3 ], [ 1 , 0 , 3 ], [ 1 , 5 , 6 ], [
1 , 2 , 2 ], [ 1 , 3 , 2 ], [ 2 , 5 , 1 ], [ 2 , 3 , 1 ], [ 3 , 4 , 1 ], [ 4 , 3 , 2 ]]
s1 = Solution()
# Function call
s1.shortest_paths(grid, V)
|
using System;
using System.Collections.Generic;
class Solution
{ public void ShortestPaths(List<List< int >> grid, int V)
{
List< int > dist = new List< int >( new int [V]);
// Initialize distances to maximum value
for ( int i = 0; i < V; i++)
{
dist[i] = int .MaxValue;
}
// Taking 0 as our source
dist[0] = 0;
// Relaxing V-1 times
for ( int i = 0; i < V - 1; i++)
{
// For each value in the given
// list of [u, v, wt]
foreach ( var it in grid)
{
int u = it[0];
int v = it[1];
int wt = it[2];
// If there exists a better
// distance and the previous dist
// of u should not be infinite
if (dist[u] != int .MaxValue
&& dist[u] + wt < dist[v])
{
dist[v] = dist[u] + wt;
}
}
}
// Check for negative cycles
for ( int i = 0; i < V; i++)
{
foreach ( var it in grid)
{
int u = it[0];
int v = it[1];
int wt = it[2];
if (dist[u] != int .MaxValue && dist[u] + wt < dist[v])
{
Console.WriteLine( "ERROR ALERT, Negative Cycle exists" );
return ;
}
}
}
Console.WriteLine( "The shortest distances from " );
for ( int i = 0; i < V; i++)
{
Console.WriteLine($ "0 to {i} ---> {(dist[i] == int.MaxValue ? " INF " : dist[i].ToString())}" );
}
}
} class Program
{ static void Main()
{
int V = 6;
List<List< int >> grid = new List<List< int >>
{
new List< int > { 0, 1, 2 },
new List< int > { 0, 3, 5 },
new List< int > { 0, 4, 3 },
new List< int > { 1, 0, 3 },
new List< int > { 1, 5, 6 },
new List< int > { 1, 2, 2 },
new List< int > { 1, 3, 2 },
new List< int > { 2, 5, 1 },
new List< int > { 2, 3, 1 },
new List< int > { 3, 4, 1 },
new List< int > { 4, 3, 2 }
};
Solution s1 = new Solution();
// Function call
s1.ShortestPaths(grid, V);
}
} |
class Solution { shortestPaths(grid, V) {
const dist = new Array(V).fill(1e9);
// Taking 0 as our source
dist[0] = 0;
// Relaxing V-1 times
for (let i = 0; i < V; i++) {
// For each value in the given vector of [u, v, wt]
for (const it of grid) {
const u = it[0];
const v = it[1];
const wt = it[2];
// If there exists a better distance and the previous distance
// of u should not be infinite
if (dist[u] !== 1e9 && dist[u] + wt < dist[v]) {
dist[v] = dist[u] + wt;
}
}
}
// If a negative cycle exists, it will still reduce for Vth traversal
for (const it of grid) {
const u = it[0];
const v = it[1];
const wt = it[2];
if (dist[u] !== 1e9 && dist[u] + wt < dist[v]) {
console.log( "ERROR ALERT, Negative Cycle exists" );
}
}
console.log( "The shortest distances from:" );
for (let i = 0; i < V; i++) {
console.log(`0 to ${i} ---> ${dist[i]}`);
}
}
} // Driver code const V = 6; const grid = [ [0, 1, 2],
[0, 3, 5],
[0, 4, 3],
[1, 0, 3],
[1, 5, 6],
[1, 2, 2],
[1, 3, 2],
[2, 5, 1],
[2, 3, 1],
[3, 4, 1],
[4, 3, 2]
]; const s1 = new Solution();
// Function call s1.shortestPaths(grid, V); |
The shortest distances from 0 to 0 ---> 0 0 to 1 ---> 2 0 to 2 ---> 4 0 to 3 ---> 4 0 to 4 ---> 3 0 to 5 ---> 5
Time complexity: O(|V||E|)
Auxiliary space: O(|V|)
Floyd-Warshall’s Algorithm
The Floyd-Warshall algorithm is used to find the shortest path between all pairs of nodes in a weighted graph. It works by maintaining a distance matrix where each entry (i, j) represents the shortest distance from node i to node j. The algorithm starts by initializing the distance matrix with the weights of the edges in the graph. Then, it iteratively updates the distance matrix by considering all possible intermediate nodes and choosing the path with the minimum total weight.
Implementation of Floyd-Warshall’s Algorithm:
// C++ code for the above approach: #include <bits/stdc++.h> using namespace std;
class Solution {
public :
void shortest_dist(vector<vector< int > >& matrix)
{
int N = matrix.size();
// changing value of -1
// to infinite
for ( int i = 0; i < N; i++) {
for ( int j = 0; j < N; j++) {
if (matrix[i][j] == -1) {
matrix[i][j] = 1e9;
}
// The distance of node to
// itself will be 0.
if (i == j) {
matrix[i][j] = 0;
}
}
}
// Assign the better distance
// (if exist) in the matrix
// one by one making each node
// as our intermediate node
for ( int via = 0; via < N; via++) {
for ( int i = 0; i < N; i++) {
for ( int j = 0; j < N; j++) {
matrix[i][j] = min(
matrix[i][j],
matrix[i][via] + matrix[via][j]);
}
}
}
// Replacing infinity to -1,
// after the work is done
for ( int i = 0; i < N; i++) {
for ( int j = 0; j < N; j++) {
if (matrix[i][j] == 1e9) {
matrix[i][j] = -1;
}
}
}
}
}; // Driver code int main()
{ vector<vector< int > > grid
= { { 0, 1, 2 }, { 0, 3, 5 }, { 0, 4, 3 }, { 1, 0, 3 }, { 1, 5, 6 }, { 1, 2, 2 }, { 1, 3, 2 }, { 2, 5, 1 }, { 2, 3, 1 }, { 3, 4, 1 }, { 4, 3, 2 } };
int V = 6;
vector<vector< int > > matrix(V, vector< int >(V, -1));
// creating matrix representation
for ( auto it : grid) {
int u = it[0];
int v = it[1];
int wt = it[2];
matrix[u][v] = wt;
}
Solution obj;
// Function call
obj.shortest_dist(matrix);
for ( auto row : matrix) {
for ( auto it : row) {
if (it == 1e9) {
it = -1;
}
cout << it << "\t" ;
}
cout << endl;
}
return 0;
} |
import java.util.Arrays;
public class Solution {
public void shortestDist( int [][] matrix) {
int N = matrix.length;
// Changing value of -1 to infinite
for ( int i = 0 ; i < N; i++) {
for ( int j = 0 ; j < N; j++) {
if (matrix[i][j] == - 1 ) {
matrix[i][j] = Integer.MAX_VALUE;
}
// The distance of node to itself will be 0
if (i == j) {
matrix[i][j] = 0 ;
}
}
}
// Assign the better distance (if exist) in the matrix
// one by one making each node as our intermediate node
for ( int via = 0 ; via < N; via++) {
for ( int i = 0 ; i < N; i++) {
for ( int j = 0 ; j < N; j++) {
if (matrix[i][via] != Integer.MAX_VALUE && matrix[via][j] != Integer.MAX_VALUE &&
matrix[i][j] > matrix[i][via] + matrix[via][j]) {
matrix[i][j] = matrix[i][via] + matrix[via][j];
}
}
}
}
// Replacing infinity to -1, after the work is done
for ( int i = 0 ; i < N; i++) {
for ( int j = 0 ; j < N; j++) {
if (matrix[i][j] == Integer.MAX_VALUE) {
matrix[i][j] = - 1 ;
}
}
}
}
// Driver code
public static void main(String[] args) {
int [][] grid = {
{ 0 , 1 , 2 }, { 0 , 3 , 5 }, { 0 , 4 , 3 }, { 1 , 0 , 3 }, { 1 , 5 , 6 },
{ 1 , 2 , 2 }, { 1 , 3 , 2 }, { 2 , 5 , 1 }, { 2 , 3 , 1 }, { 3 , 4 , 1 }, { 4 , 3 , 2 }
};
int V = 6 ;
int [][] matrix = new int [V][V];
// Initializing matrix representation
for ( int [] it : matrix) {
Arrays.fill(it, - 1 );
}
// Creating matrix representation
for ( int [] it : grid) {
int u = it[ 0 ];
int v = it[ 1 ];
int wt = it[ 2 ];
matrix[u][v] = wt;
}
Solution obj = new Solution();
// Function call
obj.shortestDist(matrix);
// Printing the result
for ( int [] row : matrix) {
for ( int it : row) {
if (it == - 1 ) {
System.out.print(it + "\t" );
} else {
System.out.print(it + "\t" );
}
}
System.out.println();
}
}
} |
# Python code for the above approach: class Solution:
def shortest_dist( self , matrix):
N = len (matrix)
# changing value of -1
# to infinite
for i in range (N):
for j in range (N):
if matrix[i][j] = = - 1 :
matrix[i][j] = float ( 'inf' )
# The distance of node to
# itself will be 0.
if i = = j:
matrix[i][j] = 0
# Assign the better distance
# (if exist) in the matrix
# one by one making each node
# as our intermediate node
for via in range (N):
for i in range (N):
for j in range (N):
matrix[i][j] = min (matrix[i][j], matrix[i][via] + matrix[via][j])
# Replacing infinity to -1,
# after the work is done
for i in range (N):
for j in range (N):
if matrix[i][j] = = float ( 'inf' ):
matrix[i][j] = - 1
# Driver code if __name__ = = "__main__" :
grid = [[ 0 , 1 , 2 ], [ 0 , 3 , 5 ], [ 0 , 4 , 3 ], [ 1 , 0 , 3 ], [ 1 , 5 , 6 ], [ 1 , 2 , 2 ], [ 1 , 3 , 2 ], [ 2 , 5 , 1 ], [ 2 , 3 , 1 ], [ 3 , 4 , 1 ], [ 4 , 3 , 2 ]]
V = 6
matrix = [[ - 1 for _ in range (V)] for _ in range (V)]
# Creating matrix representation
for it in grid:
u, v, wt = it[ 0 ], it[ 1 ], it[ 2 ]
matrix[u][v] = wt
obj = Solution()
# Function call
obj.shortest_dist(matrix)
for row in matrix:
for it in row:
if it = = - 1 :
it = - 1
print (it, end = "\t" )
print ()
# This code is contributed by Pushpesh raj |
using System;
using System.Collections.Generic;
public class Solution
{ public void ShortestDist(List<List< int >> matrix)
{
int N = matrix.Count;
// Convert -1 to infinite and set distance to self as 0
for ( int i = 0; i < N; i++)
{
for ( int j = 0; j < N; j++)
{
if (matrix[i][j] == -1)
matrix[i][j] = int .MaxValue;
if (i == j)
matrix[i][j] = 0;
}
}
// Applying Floyd-Warshall algorithm
for ( int k = 0; k < N; k++)
{
for ( int i = 0; i < N; i++)
{
for ( int j = 0; j < N; j++)
{
if (matrix[i][k] != int .MaxValue && matrix[k][j] != int .MaxValue &&
matrix[i][k] + matrix[k][j] < matrix[i][j])
{
matrix[i][j] = matrix[i][k] + matrix[k][j];
}
}
}
}
// Convert back to -1 from infinite
for ( int i = 0; i < N; i++)
{
for ( int j = 0; j < N; j++)
{
if (matrix[i][j] == int .MaxValue)
matrix[i][j] = -1;
}
}
}
} public class Program
{ public static void Main()
{
List<List< int >> grid = new List<List< int >>
{
new List< int > { 0, 1, 2 }, new List< int > { 0, 3, 5 }, new List< int > { 0, 4, 3 },
new List< int > { 1, 0, 3 }, new List< int > { 1, 5, 6 }, new List< int > { 1, 2, 2 },
new List< int > { 1, 3, 2 }, new List< int > { 2, 5, 1 }, new List< int > { 2, 3, 1 },
new List< int > { 3, 4, 1 }, new List< int > { 4, 3, 2 }
};
int V = 6;
List<List< int >> matrix = new List<List< int >>(V);
for ( int i = 0; i < V; i++)
{
matrix.Add( new List< int >( new int [V]));
for ( int j = 0; j < V; j++)
{
matrix[i][j] = -1;
}
}
// Create matrix representation
foreach ( var it in grid)
{
int u = it[0];
int v = it[1];
int wt = it[2];
matrix[u][v] = wt;
}
Solution obj = new Solution();
// Call the function
obj.ShortestDist(matrix);
// Print the matrix
foreach ( var row in matrix)
{
foreach ( var value in row)
{
Console.Write($ "{value}\t" );
}
Console.WriteLine();
}
}
} // This code is contributed by shivamgupta310570 |
class Solution { shortestDist(matrix) {
const N = matrix.length;
// Changing value of -1 to infinite
for (let i = 0; i < N; i++) {
for (let j = 0; j < N; j++) {
if (matrix[i][j] === -1) {
matrix[i][j] = Infinity;
}
// The distance of node to itself will be 0.
if (i === j) {
matrix[i][j] = 0;
}
}
}
// Assign the better distance (if exist) in the matrix
// one by one making each node as our intermediate node
for (let via = 0; via < N; via++) {
for (let i = 0; i < N; i++) {
for (let j = 0; j < N; j++) {
matrix[i][j] = Math.min(
matrix[i][j],
matrix[i][via] + matrix[via][j]
);
}
}
}
// Replacing infinity with -1 after the work is done
for (let i = 0; i < N; i++) {
for (let j = 0; j < N; j++) {
if (matrix[i][j] === Infinity) {
matrix[i][j] = -1;
}
}
}
}
} // Driver code const grid = [ [0, 1, 2], [0, 3, 5], [0, 4, 3], [1, 0, 3], [1, 5, 6],
[1, 2, 2], [1, 3, 2], [2, 5, 1], [2, 3, 1], [3, 4, 1], [4, 3, 2]
]; const V = 6; const matrix = Array.from({ length: V }, () => Array(V).fill(-1)); // Creating matrix representation for (const it of grid) {
const [u, v, wt] = it;
matrix[u][v] = wt;
} const obj = new Solution();
// Function call obj.shortestDist(matrix); for (const row of matrix) {
for (const it of row) {
if (it === -1) {
console.log( "-1\t" );
} else {
console.log(it + "\t" );
}
}
console.log();
} |
0 2 4 4 3 5 3 0 2 2 3 3 -1 -1 0 1 2 1 -1 -1 -1 0 1 -1 -1 -1 -1 2 0 -1 -1 -1 -1 -1 -1 0
Time complexity: O(N^3)
Auxiliary Space: O(N^2)