Skip to content

Commit 66c3c09

Browse files
committed
Added Dijkstras shortest path
1 parent 163a174 commit 66c3c09

File tree

3 files changed

+49
-11
lines changed

3 files changed

+49
-11
lines changed

graph.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ def add_edge(self, edge, wt=1, label=""):
6060
if (u!=v):
6161
self.node_neighbors[v].append(u)
6262
self.set_edge_properties((u, v), label=label, weight=wt)
63+
self.set_edge_properties((v, u), label=label, weight=wt)
6364
else:
6465
raise Exception("Edge (%s, %s) already added in the graph" % (u, v))
6566

graph_algorithms.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def BFS(gr, s):
1818
q.append(each)
1919
return nodes_explored
2020

21-
def shortest_path(gr, s):
21+
def shortest_hops(gr, s):
2222
""" Finds the shortest number of hops required
2323
to reach a node from s. Returns a dict with mapping:
2424
destination node from s -> no. of hops
@@ -138,3 +138,19 @@ def inner_DFS(digr, node, node_explored, finishing_times):
138138
global finishing_counter
139139
# adds nodes based on increasing order of finishing times
140140
finishing_times.append(node)
141+
142+
def shortest_path(digr, s):
143+
""" Finds the shortest path from s to every other vertex findable
144+
from s using Dijkstra's algorithm in O(mn) time """
145+
nodes_explored = [s]
146+
nodes_unexplored = DFS(digr, s) # all accessible nodes from s
147+
dist = {s:0}
148+
nodes_unexplored.remove(s)
149+
while len(nodes_unexplored) > 0:
150+
edge_frontier = [(u, v) for (u, v) in digr.edges() if u in nodes_explored
151+
and v in nodes_unexplored]
152+
min_dist = min([(dist[u] + digr.get_edge_weight((u, v)), v) for (u, v) in edge_frontier])
153+
nodes_explored.append(min_dist[1])
154+
nodes_unexplored.remove(min_dist[1])
155+
dist[min_dist[1]] = min_dist[0]
156+
return dist

graph_algorithms_test.py

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,17 @@ def test_dfs_directed_graph(self):
3939
self.assertEqual(len(DFS(self.digr, "c")), 7)
4040
self.assertEqual(len(DFS(self.digr, "f")), 1)
4141

42-
def test_shortest_path_undirected_graph(self):
43-
self.assertEqual(shortest_path(self.gr, "s")["c"], 2)
44-
self.assertEqual(shortest_path(self.gr, "c")["s"], 2)
45-
self.assertEqual(shortest_path(self.gr, "s")["s"], 0)
46-
self.assertEqual(shortest_path(self.gr, "c")["j"], float('inf'))
42+
def test_shortest_hops_undirected_graph(self):
43+
self.assertEqual(shortest_hops(self.gr, "s")["c"], 2)
44+
self.assertEqual(shortest_hops(self.gr, "c")["s"], 2)
45+
self.assertEqual(shortest_hops(self.gr, "s")["s"], 0)
46+
self.assertEqual(shortest_hops(self.gr, "c")["j"], float('inf'))
4747

48-
def test_shortest_path_directed_graph(self):
49-
self.assertEqual(shortest_path(self.digr, "s")["f"], 3)
50-
self.assertEqual(shortest_path(self.digr, "f")["s"], float('inf'))
51-
self.assertEqual(shortest_path(self.digr, "s")["s"], 0)
52-
self.assertEqual(shortest_path(self.digr, "s")["c"], float('inf'))
48+
def test_shortest_hops_directed_graph(self):
49+
self.assertEqual(shortest_hops(self.digr, "s")["f"], 3)
50+
self.assertEqual(shortest_hops(self.digr, "f")["s"], float('inf'))
51+
self.assertEqual(shortest_hops(self.digr, "s")["s"], 0)
52+
self.assertEqual(shortest_hops(self.digr, "s")["c"], float('inf'))
5353

5454
def test_undirected_connected_component(self):
5555
self.assertEqual(len(undirected_connected_components(self.gr)), 3)
@@ -79,5 +79,26 @@ def test_directed_connected_components(self):
7979
digr2.add_edges([("h", "j"), ("j", "k"), ("k", "h")])
8080
self.assertEqual(len(directed_connected_components(digr2)), 4)
8181

82+
def test_shortest_path_in_directed_graph(self):
83+
digr = digraph()
84+
digr.add_nodes(["a", "b", "c", "d", "e", "f"])
85+
digr.add_edge(("a", "b"), 7)
86+
digr.add_edge(("a", "c"), 9)
87+
digr.add_edge(("a", "f"), 14)
88+
digr.add_edge(("f", "e"), 9)
89+
digr.add_edge(("c", "f"), 2)
90+
digr.add_edge(("c", "d"), 11)
91+
digr.add_edge(("b", "c"), 10)
92+
digr.add_edge(("b", "d"), 15)
93+
digr.add_edge(("d", "e"), 6)
94+
self.assertEqual(shortest_path(digr, "a")["a"], 0)
95+
self.assertEqual(shortest_path(digr, "a")["b"], 7)
96+
self.assertEqual(shortest_path(digr, "a")["c"], 9)
97+
self.assertEqual(shortest_path(digr, "a")["d"], 20)
98+
self.assertEqual(shortest_path(digr, "a")["e"], 20)
99+
self.assertEqual(shortest_path(digr, "a")["f"], 11)
100+
101+
102+
82103
if __name__ == "__main__":
83104
unittest.main()

0 commit comments

Comments
 (0)