Skip to content

Commit 1b9b968

Browse files
authored
Johnsons Algo For Shortest Path in Python
1 parent 2bab95d commit 1b9b968

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed

johnsons_algo.py

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# Part of Cosmos by OpenGenus Foundation
2+
3+
'''
4+
def Johnsons():
5+
data = list()
6+
source = list()
7+
destination = list()
8+
edgecost = list()
9+
test = 0
10+
vertices = 0
11+
edges = 0
12+
data = readfile()
13+
vertexlist = list()
14+
distance = list()
15+
vertices, edges, source, destination, edgecost, vertexlist, distance = setdata(data)
16+
predecessor = list()
17+
d = list()
18+
d, predecessor = intialize(distance)
19+
#relaxation
20+
source, destination, edgecost, d, predecessor = relax(vertices, source, destination, edgecost, d, predecessor,edges)
21+
#change weights
22+
vertexlist.reverse()
23+
source, destination, edgecost, d = reweight(vertices, source, destination, edgecost, d,edges)
24+
output(source, destination, edgecost)
25+
for x in vertexlist:
26+
print('Running Dijkstra on vertex ' + str(x))
27+
Dijkstra(vertexlist,x,source, destination, edgecost, predecessor, edges,vertices)
28+
29+
'''
30+
31+
32+
33+
34+
from heapq import heappush, heappop
35+
from datetime import datetime
36+
from copy import deepcopy
37+
graph = {
38+
'a' : {'b':-2},
39+
'b' : {'c':-1},
40+
'c' : {'x':2, 'a':4, 'y':-3},
41+
'z' : {'x':1, 'y':-4},
42+
'x' : {},
43+
'y' : {},
44+
}
45+
46+
inf = float('inf')
47+
dist = {}
48+
49+
def read_graph(file,n):
50+
graph = dict()
51+
with open(file) as f:
52+
for l in f:
53+
(u, v, w) = l.split()
54+
if int(u) not in graph:
55+
graph[int(u)] = dict()
56+
graph[int(u)][int(v)] = int(w)
57+
for i in range(n):
58+
if i not in graph:
59+
graph[i] = dict()
60+
return graph
61+
62+
def dijkstra(graph, s):
63+
n = len(graph.keys())
64+
dist = dict()
65+
Q = list()
66+
67+
for v in graph:
68+
dist[v] = inf
69+
dist[s] = 0
70+
71+
heappush(Q, (dist[s], s))
72+
73+
while Q:
74+
d, u = heappop(Q)
75+
if d < dist[u]:
76+
dist[u] = d
77+
for v in graph[u]:
78+
if dist[v] > dist[u] + graph[u][v]:
79+
dist[v] = dist[u] + graph[u][v]
80+
heappush(Q, (dist[v], v))
81+
return dist
82+
83+
def initialize_single_source(graph, s):
84+
for v in graph:
85+
dist[v] = inf
86+
dist[s] = 0
87+
88+
def relax(graph, u, v):
89+
if dist[v] > dist[u] + graph[u][v]:
90+
dist[v] = dist[u] + graph[u][v]
91+
92+
def bellman_ford(graph, s):
93+
initialize_single_source(graph, s)
94+
edges = [(u, v) for u in graph for v in graph[u].keys()]
95+
number_vertices = len(graph)
96+
for i in range(number_vertices-1):
97+
for (u, v) in edges:
98+
relax(graph, u, v)
99+
for (u, v) in edges:
100+
if dist[v] > dist[u] + graph[u][v]:
101+
return False # there exists a negative cycle
102+
return True
103+
104+
def add_extra_node(graph):
105+
graph[0] = dict()
106+
for v in graph.keys():
107+
if v != 0:
108+
graph[0][v] = 0
109+
110+
def reweighting(graph_new):
111+
add_extra_node(graph_new)
112+
if not bellman_ford(graph_new, 0):
113+
# graph contains negative cycles
114+
return False
115+
for u in graph_new:
116+
for v in graph_new[u]:
117+
if u != 0:
118+
graph_new[u][v] += dist[u] - dist[v]
119+
del graph_new[0]
120+
return graph_new
121+
122+
def johnsons(graph_new):
123+
graph = reweighting(graph_new)
124+
if not graph:
125+
return False
126+
final_distances = {}
127+
for u in graph:
128+
final_distances[u] = dijkstra(graph, u)
129+
130+
for u in final_distances:
131+
for v in final_distances[u]:
132+
final_distances[u][v] += dist[v] - dist[u]
133+
return final_distances
134+
135+
def compute_min(final_distances):
136+
return min(final_distances[u][v] for u in final_distances for v in final_distances[u])
137+
138+
if __name__ == "__main__":
139+
# graph = read_graph("graph.txt", 1000)
140+
graph_new = deepcopy(graph)
141+
t1 = datetime.utcnow()
142+
final_distances = johnsons(graph_new)
143+
if not final_distances:
144+
print("Negative cycle")
145+
else:
146+
print(compute_min(final_distances))
147+
print(datetime.utcnow() - t1)
148+
149+

0 commit comments

Comments
 (0)