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