All-Pairs Shortest-Paths Problem
The all-pairs shortest paths problem aims to find the shortest distance between every pair of vertices in a graph. Dynamic programming algorithms like Floyd-Warshall can solve this in O(V^3) time.
Java example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| // Floyd-Warshall algorithm
int[][] floydWarshall(int[][] graph) {
int V = graph.length;
int[][] dist = new int[V][V];
// Initialize distances
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
dist[i][j] = graph[i][j];
}
}
// Find shortest paths
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];
}
}
}
}
return dist;
}
|
C++ example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| // Floyd-Warshall algorithm
vector<vector<int>> floydWarshall(vector<vector<int>> graph) {
int V = graph.size();
vector<vector<int>> dist(V, vector<int>(V));
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
dist[i][j] = graph[i][j];
}
}
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];
}
}
}
}
return dist;
}
|
Python example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # Floyd-Warshall algorithm
def floyd_warshall(graph):
V = len(graph)
dist = [[float("inf") for _ in range(V)] for _ in range(V)]
for i in range(V):
for j in range(V):
dist[i][j] = graph[i][j]
for k in range(V):
for i in range(V):
for j in range(V):
if dist[i][k] + dist[k][j] < dist[i][j]:
dist[i][j] = dist[i][k] + dist[k][j]
return dist
|
Enables solving various graph analysis problems efficiently including presence of negative cycles. Useful for network routing, economics, and bioinformatics.
The All-Pairs Shortest-Paths problem is focused on finding the shortest paths between all pairs of vertices in a weighted graph. Algorithms like Floyd-Warshall and Johnson’s algorithm are often used for this. It’s useful in applications where you need to know the shortest distances between all pairs of nodes, not just from a single source.
Algorithm
- Initialization: Create a 2D matrix where the value at
(i, j)
is initialized to the weight of the edge from i
to j
, or infinity if no such edge exists. - Iteration: For each pair of vertices
(i, j)
, update the shortest path using all possible intermediate vertices. - Final Matrix: The final 2D matrix will have the shortest path from each vertex
i
to each vertex j
.
Java Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| public class AllPairsShortestPath {
public static int[][] floydWarshall(int[][] graph) {
int n = graph.length;
int[][] dist = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
dist[i][j] = graph[i][j];
if (i != j && graph[i][j] == 0) {
dist[i][j] = Integer.MAX_VALUE;
}
}
}
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (dist[i][k] != Integer.MAX_VALUE && dist[k][j] != Integer.MAX_VALUE &&
dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
return dist;
}
}
|
C++ Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| #include <vector>
#include <limits.h>
std::vector<std::vector<int>> floydWarshall(std::vector<std::vector<int>> graph) {
int n = graph.size();
std::vector<std::vector<int>> dist(n, std::vector<int>(n, 0));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
dist[i][j] = graph[i][j];
if (i != j && graph[i][j] == 0) {
dist[i][j] = INT_MAX;
}
}
}
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (dist[i][k] != INT_MAX && dist[k][j] != INT_MAX &&
dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
return dist;
}
|
Python Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| def floyd_warshall(graph):
n = len(graph)
dist = [[0 for _ in range(n)] for _ in range(n)]
for i in range(n):
for j in range(n):
dist[i][j] = graph[i][j]
if i != j and graph[i][j] == 0:
dist[i][j] = float('inf')
for k in range(n):
for i in range(n):
for j in range(n):
if dist[i][k] != float('inf') and dist[k][j] != float('inf') and \
dist[i][k] + dist[k][j] < dist[i][j]:
dist[i][j] = dist[i][k] + dist[k][j]
return dist
|
The time complexity for Floyd-Warshall is (O(V^3)). It’s not the most efficient for large graphs, but it’s straightforward and works for graphs with negative edge weights as long as there are no negative cycles.