Floyd-Warshall Algorithm
Introduction
The Floyd–Warshall algorithm is a dynamic programming algorithm used to find the shortest paths between all pairs of vertices in a weighted graph. It can handle graphs with positive and negative-edge weights but does not work with graphs containing negative cycles. The algorithm is particularly useful for dense graphs and is often used in network routing protocols.
Explanation
The Floyd–Warshall algorithm works by iteratively improving the shortest path estimates between all pairs of vertices.
- Create a distance matrix
distwheredist[i][j]is the weight of the edge from vertexito vertexj. If there is no edge, set it to infinity. Setdist[i][i] = 0for all verticesi. - For each vertex
k, iterate through all pairs of vertices(i, j)and update the distance matrix: \[ \text{dist}[i][j] = \min(\text{dist}[i][j], \text{dist}[i][k] + \text{dist}[k][j]) \]
The interactive demo below uses the same recurrence. At step $k$, the matrix allows paths whose internal vertices are contained in the first $k$ vertices of the order
\[ A,B,C,D. \]
For example, when $k=C$, the entry from $B$ to $D$ improves because
\[ \mathrm{dist}[B][C]+\mathrm{dist}[C][D] = -3+4=1. \]
Proof of Correctness
Order the vertices as
\[ 1,2,\ldots,V. \]
Let $D_k[i][j]$ be the minimum weight of a path from $i$ to $j$ whose internal vertices are contained in
\[ \Set{1,2,\ldots,k}. \]
The Floyd–Warshall invariant is that after finishing the iteration for $k$, the matrix entry dist[i][j] is exactly $D_k[i][j]$.
Proof. For $k=0$, no internal vertex is allowed. Thus the best path from $i$ to $j$ is either the direct edge $i\to j$, the empty path when $i=j$, or no path. This is exactly the initialization of the distance matrix.
Assume the invariant holds after iteration $k-1$. Consider a shortest path counted by $D_k[i][j]$. Either it does not use vertex $k$ as an internal vertex, in which case its weight is $D_{k-1}[i][j]$, or it uses $k$. In the second case, split the path at $k$. The subpath from $i$ to $k$ and the subpath from $k$ to $j$ have internal vertices only in
\[ \Set{1,2,\ldots,k-1}. \]
Hence the best such path has weight
\[ D_{k-1}[i][k]+D_{k-1}[k][j]. \]
Therefore
\[ D_k[i][j] =\min\left(D_{k-1}[i][j],D_{k-1}[i][k]+D_{k-1}[k][j]\right). \]
This is exactly the update performed by the algorithm. By induction, after $k=V$ all vertices are allowed as internal vertices, so every shortest path is considered.
If a negative cycle is reachable from $i$ and can reach $j$, the shortest distance from $i$ to $j$ is not well-defined as a finite value. This is why the usual shortest-path interpretation assumes no negative cycles.
Complexity
The time complexity of the Floyd–Warshall algorithm is $O(V^3)$, where $V$ is the number of vertices in the graph. This is because the algorithm consists of three nested loops, each iterating over all vertices. The space complexity is $O(V^2)$ due to the distance matrix.
Code
Let’s see the sample code.
const int MAX;
const int INF;
int dist[MAX][MAX];
int N; // Number of vertices
void init(){
for(int i=1; i<=N; i++) for(int j=1; j<=N; j++)
dist[i][j] = (i==j)?0:INF;
}
void FloydWarshall(){
for(int k=1; k<=N; k++)
for(int i=1; i<=N; i++) for(int j=1; j<=N; j++)
dist[i][j] = min(dist[i][j],dist[i][k]+dist[k][j]);
}
Applications
The Floyd–Warshall algorithm is widely used in various applications, including:
- Optimizing network routing protocols.
- Finding the transitive closure of a directed graph.
- Inverting real-valued matrices. (Gauss–Jordan elimination)