Floyd-Warshall Algorithm
The Floyd-Warshall Algorithm is a classic algorithm used to find the shortest paths between all pairs of vertices in a weighted graph. It is especially useful in dense graphs and is applicable to both directed and undirected graphs. The algorithm uses a dynamic programming approach to iteratively improve the estimation of shortest paths.
Given a graph with n vertices, the Floyd-Warshall algorithm calculates the shortest paths between every pair of vertices. The result is stored in a distance matrix where the value at row i and column j represents the shortest distance between vertex i and vertex j.
The core idea of the Floyd-Warshall algorithm is based on the principle of dynamic programming, where we incrementally build the solution by considering intermediate vertices.
The algorithm iterates through all pairs of vertices and attempts to improve the shortest path by checking if a path through an intermediate vertex offers a shorter path.
Let dist[][]
be a 2D array where dist[i][j]
holds the shortest distance from vertex i to vertex j.
Initialize dist[i][j]
to the weight of the edge from i to j. If no direct edge exists, set it to infinity (∞), except for dist[i][i]
which is 0.
For each vertex k, update the shortest path between every pair of vertices i and j by checking if going through k offers a shorter path:
After running the algorithm, dist[i][j]
will contain the shortest distance between vertices i and j.
dist
matrix.Let's consider a graph with 4 vertices and the following weighted adjacency matrix:
0 5 ∞ 10
∞ 0 3 ∞
∞ ∞ 0 1
∞ ∞ ∞ 0
Where:
0
indicates the distance from a vertex to itself.∞
(infinity) indicates no direct edge between the vertices.After applying the Floyd-Warshall algorithm, the shortest distance matrix will look like this:
0 5 8 9
∞ 0 3 4
∞ ∞ 0 1
∞ ∞ ∞ 0
INF = float('inf')
def floyd_warshall(graph):
# Get the number of vertices
n = len(graph)
# Initialize the distance matrix
dist = [row[:] for row in graph]
# Floyd-Warshall algorithm
for k in range(n):
for i in range(n):
for j in range(n):
if dist[i][j] > dist[i][k] + dist[k][j]:
dist[i][j] = dist[i][k] + dist[k][j]
return dist
# Example graph (adjacency matrix)
graph = [
[0, 5, INF, 10],
[INF, 0, 3, INF],
[INF, INF, 0, 1],
[INF, INF, INF, 0]
]
# Run Floyd-Warshall Algorithm
result = floyd_warshall(graph)
# Print the result
for row in result:
print(row)
Explanation:
INF
denotes that no direct edge exists between two vertices.k
, and the inner loops check each pair of vertices (i, j)
and update the distance matrix.
#include <iostream>
#include <vector>
#include <limits.h>
using namespace std;
#define INF INT_MAX
void floydWarshall(vector<vector<int>>& graph) {
int n = graph.size();
// Initialize the distance matrix
vector<vector<int>> dist = graph;
// 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 (dist[i][j] > dist[i][k] + dist[k][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
// Print the distance matrix
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (dist[i][j] == INF) {
cout << "INF ";
} else {
cout << dist[i][j] << " ";
}
}
cout << endl;
}
}
int main() {
// Example graph (adjacency matrix)
vector<vector<int>> graph = {
{0, 5, INF, 10},
{INF, 0, 3, INF},
{INF, INF, 0, 1},
{INF, INF, INF, 0}
};
// Run Floyd-Warshall algorithm
floydWarshall(graph);
return 0;
}
Explanation:
INF
(set to INT_MAX
in C++) represents an absence of an edge.Time Complexity:
The algorithm involves three nested loops over the vertices, resulting in a time complexity of O(n³), where n is the number of vertices. This is because, for each pair of vertices (i, j)
, we check if the shortest path can be improved by going through an intermediate vertex k
.
Space Complexity:
The space complexity is O(n²) because we store the distance matrix, which has dimensions of n x n.
All-Pairs Shortest Path Problem:
Graph Transitive Closure:
Negative Weight Cycle Detection:
Network Flow Problems: