1
1
# floyd_warshall.py
2
2
"""
3
- The problem is to find and return the shortest distance between all pairs of vertices
3
+ The problem is to find and return the shortest distance between all pairs of vertices
4
4
in a weighted directed graph that can have negative edge weights.
5
5
6
6
https://docs.python.org/3/library/doctest.html
7
7
8
8
"""
9
9
10
-
11
- def floyd_warshall (graph : list [list [float ]], vertex : int ) -> tuple :
12
- # 1. For all edges from v to n, distance[i][j] = weight(edge(i, j)).
13
-
14
- # 2. distance[i][j] = min(distance[i][j], distance[i][k] + distance[k][j]).
15
-
16
- # 3. Step 2 is true for each pair of vertices.Repeat for k vertex in the graph.
17
-
18
- # 4. Whenever distance[i][j] is given a new minimum value,
10
+ def floyd_warshall (graph :list [list [float ]], vertex :int ) -> tuple :
11
+ #1. For all edges from v to n, distance[i][j] = weight(edge(i, j)).
12
+
13
+ #2. distance[i][j] = min(distance[i][j], distance[i][k] + distance[k][j]).
14
+
15
+ #3. Step 2 is true for each pair of vertices.Repeat for k vertex in the graph.
16
+
17
+ #4. Whenever distance[i][j] is given a new minimum value,
19
18
# next vertex[i][j] = next vertex[i][k].
20
-
19
+
21
20
"""
22
21
:param graph: 2D array calculated from weight[edge[i, j]]
23
-
22
+
24
23
:param v: number of vertices
25
-
24
+
26
25
:return: shortest distance between all vertex pairs
27
-
26
+
28
27
distance[u][v] will contain the shortest distance from vertex u to v.
29
-
28
+
30
29
# doctests:
31
-
30
+
32
31
>>> graph = [[0, 3, float('inf')], [2, 0, float('inf')],[float('inf'), 7, 0]]
33
32
>>> floyd_warshall(graph, 3)[0]
34
33
[[0, 3, inf], [2, 0, inf], [9, 7, 0]]
35
-
34
+
36
35
>>> graph = [[0, 1, 4],[float('inf'), 0, 2],[float('inf'), float('inf'), 0]]
37
36
>>> floyd_warshall(graph, 3)[0]
38
37
[[0, 1, 3], [inf, 0, 2], [inf, inf, 0]]
39
-
38
+
40
39
>>> graph = [[0, 0, 0],[0, 0, 0],[0, 0, 0]]
41
40
>>> floyd_warshall(graph, 3)[0]
42
41
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
43
-
42
+
44
43
#Graph with all edge weights = infinity
45
-
44
+
46
45
>>> graph = [[float('inf'), float('inf'), float('inf')],
47
46
... [float('inf'), float('inf'), float('inf')],
48
47
... [float('inf'), float('inf'), float('inf')]]
49
48
>>> floyd_warshall(graph, 3)[0]
50
49
[[inf, inf, inf], [inf, inf, inf], [inf, inf, inf]]
51
-
52
-
50
+
51
+
53
52
#Handling negetive weighted graph:
54
-
53
+
55
54
>>> graph = [[0, -2, float('inf')],[float('inf'), 0, 3],[4, float('inf'), 0]]
56
55
>>> floyd_warshall(graph, 3)[0]
57
56
[[0, -2, 1], [7, 0, 3], [4, 2, 0]]
58
-
59
-
57
+
58
+
60
59
#Handling negetive weighted cycle:
61
-
60
+
62
61
>>> graph = [[0, -1, float('inf')],[float('inf'), 0, -2],[-3, float('inf'), 0]]
63
62
>>> floyd_warshall(graph, 3)[0]
64
63
[[-6, -7, -9], [-5, -6, -8], [-9, -10, -12]]
65
-
66
-
67
- #Number of vertex in function arguement should match number of vertex in graph:
68
-
64
+
65
+
66
+ #Number of vertex in function argument should match number of vertex in graph:
67
+
69
68
>>> graph = [[0, -1, float('inf')],[float('inf'), 0, -2]]
70
69
>>> floyd_warshall(graph, 3)[0]
71
70
Traceback (most recent call last):
72
71
...
73
72
IndexError: list index out of range
74
-
75
-
73
+
74
+
76
75
#Graph data type should be a 2D list:
77
-
76
+
78
77
>>> graph = "strings not allowed"
79
78
>>> floyd_warshall(graph, 3)[0]
80
79
Traceback (most recent call last):
@@ -88,24 +87,22 @@ def floyd_warshall(graph: list[list[float]], vertex: int) -> tuple:
88
87
for j in range (vertex ):
89
88
dist [i ][j ] = graph [i ][j ]
90
89
# check vertex k against all other vertices (i, j)
91
-
90
+
92
91
for k in range (vertex ):
93
92
# looping through rows of graph array
94
-
93
+
95
94
for i in range (vertex ):
96
95
# looping through columns of graph array
97
-
96
+
98
97
for j in range (vertex ):
99
98
if (
100
99
dist [i ][k ] != float ("inf" )
101
100
and dist [k ][j ] != float ("inf" )
102
101
and dist [i ][k ] + dist [k ][j ] < dist [i ][j ]
103
- ):
102
+ ):
104
103
dist [i ][j ] = dist [i ][k ] + dist [k ][j ]
105
104
return dist , vertex
106
105
107
-
108
- if __name__ == "__main__" :
106
+ if __name__ == "__main__" :
109
107
import doctest
110
-
111
108
doctest .testmod ()
0 commit comments