Floyd-Warshall Algorithm¶
The Floyd-Warshall algorithm is a dynamic programming algorithm used to find the shortest paths between all pairs of vertices in a weighted graph (directed or undirected) with positive or negative edge weights (but no negative cycles).
Intuition¶
The core idea is to consider each vertex \(k\) as an intermediate point. For every pair of vertices \((i, j)\), we check if going through \(k\) results in a shorter path than the current known path from \(i\) to \(j\).
Equation¶
For each vertex \(k \in \{1, 2, ..., V\}\): \(dist[i][j] = \min(dist[i][j], dist[i][k] + dist[k][j])\)
Algorithm Steps¶
- Initialize a 2D distance matrix
dist[][]of size \(V \times V\).dist[i][j] = weight(i, j)if an edge exists.dist[i][i] = 0.dist[i][j] = ∞otherwise.
- Iterate through all vertices \(k\) from \(0\) to \(V-1\).
- For each \(k\), iterate through all pairs \((i, j)\) and update
dist[i][j]using the equation above.
Java Implementation¶
Uses an Adjacency Matrix representation, which is natural for this algorithm.
import java.util.*;
public class FloydWarshall {
final static int INF = 99999; // Use a value that won't overflow during addition
public static void floydWarshall(int[][] graph, int V) {
int[][] dist = new int[V][V];
// Initialize distance matrix
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
dist[i][j] = graph[i][j];
}
}
// Main algorithm
for (int k = 0; k < V; k++) {
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
printSolution(dist, V);
}
static void printSolution(int[][] dist, int V) {
System.out.println("Shortest distances between every pair of vertices:");
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (dist[i][j] == INF) System.out.print("INF ");
else System.out.print(dist[i][j] + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
int[][] graph = {
{0, 5, INF, 10},
{INF, 0, 3, INF},
{INF, INF, 0, 1},
{INF, INF, INF, 0}
};
floydWarshall(graph, 4);
}
}
Negative Cycle Detection¶
If after the algorithm finishes, any diagonal element dist[i][i] is negative, then the graph contains a negative cycle.
Sample Input and Output¶
Input (Matrix representation)¶
Output¶
Complexity¶
| Metric | Complexity | Description |
|---|---|---|
| Time | \(O(V^3)\) | Three nested loops iterating over \(V\) vertices. |
| Space | \(O(V^2)\) | To store the 2D distance matrix. |
Key Takeaways¶
- All-Pairs: Unlike Dijkstra (Source to all), this is All to All.
- Negative Weights: It handles negative weights correctly.
- Dynamic Programming: It builds the solution by considering increasing sets of intermediate vertices.
- Limitation: Avoid using it for very large graphs (\(V > 500\)) due to the \(O(V^3)\) time complexity.