1
+ import heapq
2
+ class Dijkstra (object ):
3
+ """Dijkstra object
4
+ Finds the optimal path between two nodes on
5
+ a graph."""
6
+
7
+ def __init__ (self ):
8
+ pass
9
+
10
+ def reverse_path (self , node ):
11
+ result = []
12
+ while node is not None :
13
+ result .insert (0 , node ['vertex' ])
14
+ node = node ['parent' ]
15
+ return result
16
+
17
+ def find_path (self , graph , start , end ):
18
+ """
19
+ Calculates the optimal path from start to end
20
+ on the graph. Weights are ignored.
21
+
22
+ :param graph: object contains `graphs` as per pygorithm.data_structures.WeightedUndirectedGraph
23
+ weights are ignored.
24
+ :param start: the start vertex (which is the same type of the verticies in the graph)
25
+ :param end: the end vertex (which is the same type of the vertices in the graph)
26
+ :return: a list starting with `start` and ending with `end`, or None if no path is possible.
27
+ """
28
+
29
+ open = []
30
+ closed = set ()
31
+
32
+ # the first element in the tuple is the distance from the source. This is used as the primary
33
+ # key for sorting. The second element in the tuple is just a counter and is used to avoid having
34
+ # to hash the dictionary when the distance from the source is not unique.
35
+
36
+ counter = 0
37
+ heapq .heappush (open , (0 , counter , { 'vertex' : start , 'parent' : None }))
38
+ counter += 1
39
+
40
+ while len (open ) > 0 :
41
+ current = heapq .heappop (open )
42
+ closed .update (current [2 ]['vertex' ])
43
+
44
+ if current [2 ]['vertex' ] == end :
45
+ return self .reverse_path (current [2 ])
46
+
47
+ neighbors = graph .graph [current [2 ]['vertex' ]]
48
+ for neighbor in neighbors :
49
+ if neighbor not in closed :
50
+ heapq .heappush (open , (current [0 ] + 1 , counter , { 'vertex' : neighbor , 'parent' : current [2 ] }))
51
+ counter += 1
52
+
53
+
54
+ return None
55
+
56
+ @staticmethod
57
+ def get_code (self ):
58
+ """
59
+ returns the code for the current class
60
+ """
61
+ return inspect .getsource (Dijkstra )
0 commit comments