2
2
import heapq
3
3
import sys
4
4
5
- #First implementation of johnson algorithm
5
+
6
+ # First implementation of johnson algorithm
6
7
class JohnsonGraph :
7
8
def __init__ (self ):
8
9
self .edges = []
9
10
self .graph = {}
10
-
11
- #add vertices for a graph
11
+
12
+ # add vertices for a graph
12
13
def add_vertices (self , u ):
13
14
self .graph [u ] = []
14
-
15
- #assign weights for each edges formed of the directed graph
15
+
16
+ # assign weights for each edges formed of the directed graph
16
17
def add_edge (self , u , v , w ):
17
18
self .edges .append ((u , v , w ))
18
- self .graph [u ].append ((v ,w ))
19
+ self .graph [u ].append ((v , w ))
19
20
20
- #perform a dijkstra algorithm on a directed graph
21
+ # perform a dijkstra algorithm on a directed graph
21
22
def dijkstra (self , s ):
22
23
no_v = len (self .graph )
23
- distances = {vertex : sys .maxsize - 1 for vertex in self .graph }
24
- pq = [(0 ,s )]
25
-
24
+ distances = {vertex : sys .maxsize - 1 for vertex in self .graph }
25
+ pq = [(0 , s )]
26
+
26
27
distances [s ] = 0
27
28
while pq :
28
29
weight , v = heapq .heappop (pq )
29
-
30
+
30
31
if weight > distances [v ]:
31
32
continue
32
-
33
+
33
34
for node , w in self .graph [v ]:
34
- if distances [v ]+ w < distances [node ]:
35
- distances [node ] = distances [v ]+ w
36
- heapq .heappush (pq , (distances [node ], node ))
35
+ if distances [v ] + w < distances [node ]:
36
+ distances [node ] = distances [v ] + w
37
+ heapq .heappush (pq , (distances [node ], node ))
37
38
return distances
38
39
39
- #carry out the bellman ford algorithm for a node and estimate its distance vector
40
- def bellman_ford (self , s ):
40
+ # carry out the bellman ford algorithm for a node and estimate its distance vector
41
+ def bellman_ford (self , s ):
41
42
no_v = len (self .graph )
42
- distances = {vertex : sys .maxsize - 1 for vertex in self .graph }
43
+ distances = {vertex : sys .maxsize - 1 for vertex in self .graph }
43
44
distances [s ] = 0
44
-
45
+
45
46
for u in self .graph :
46
47
for u , v , w in self .edges :
47
- if distances [u ] != sys .maxsize - 1 and distances [u ]+ w < distances [v ]:
48
- distances [v ] = distances [u ]+ w
48
+ if distances [u ] != sys .maxsize - 1 and distances [u ] + w < distances [v ]:
49
+ distances [v ] = distances [u ] + w
49
50
50
51
return distances
51
-
52
- #perform the johnson algorithm to handle the negative weights that could not be handled by either the dijkstra
53
- #or the bellman ford algorithm efficiently
52
+
53
+ # perform the johnson algorithm to handle the negative weights that could not be handled by either the dijkstra
54
+ # or the bellman ford algorithm efficiently
54
55
def johnson_algo (self ):
55
-
56
56
self .add_vertices ("#" )
57
57
for v in self .graph :
58
58
if v != "#" :
59
59
self .add_edge ("#" , v , 0 )
60
-
60
+
61
61
n = self .bellman_ford ("#" )
62
-
62
+
63
63
for i in range (len (self .edges )):
64
64
u , v , weight = self .edges [i ]
65
65
self .edges [i ] = (u , v , weight + n [u ] - n [v ])
66
66
67
67
self .graph .pop ("#" )
68
68
self .edges = [(u , v , w ) for u , v , w in self .edges if u != "#" ]
69
-
69
+
70
70
for u in self .graph :
71
71
self .graph [u ] = [(v , weight ) for x , v , weight in self .edges if x == u ]
72
-
72
+
73
73
distances = []
74
74
for u in self .graph :
75
75
new_dist = self .dijkstra (u )
76
76
for v in self .graph :
77
- if new_dist [v ] < sys .maxsize - 1 :
77
+ if new_dist [v ] < sys .maxsize - 1 :
78
78
new_dist [v ] += n [v ] - n [u ]
79
79
distances .append (new_dist )
80
80
return distances
81
-
81
+
82
+
82
83
g = JohnsonGraph ()
83
- #this a complete connected graph
84
+ # this a complete connected graph
84
85
g .add_vertices ("A" )
85
86
g .add_vertices ("B" )
86
87
g .add_vertices ("C" )
@@ -97,4 +98,4 @@ def johnson_algo(self):
97
98
optimal_paths = g .johnson_algo ()
98
99
print ("Print all optimal paths of a graph using Johnson Algorithm" )
99
100
for i , row in enumerate (optimal_paths ):
100
- print (f"{ i } : { row } " )
101
+ print (f"{ i } : { row } " )
0 commit comments