Skip to content

Commit 401ed00

Browse files
committed
Added doctest and more explanation about Dijkstra execution.
1 parent 0d61539 commit 401ed00

File tree

1 file changed

+94
-23
lines changed

1 file changed

+94
-23
lines changed

graphs/dijkstra.py

Lines changed: 94 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,50 @@
11
"""pseudo-code"""
22

33
"""
4-
DIJKSTRA(graph G, start vertex s,destination vertex d):
5-
// all nodes initially unexplored
6-
let H = min heap data structure, initialized with 0 and s [here 0 indicates the distance from start vertex]
7-
while H is non-empty:
8-
remove the first node and cost of H, call it U and cost
9-
if U is not explored
10-
mark U as explored
11-
if U is d:
12-
return cost // total cost from start to destination vertex
13-
for each edge(U, V): c=cost of edge(u,V) // for V in graph[U]
14-
if V unexplored:
15-
next=cost+c
16-
add next,V to H (at the end)
4+
DIJKSTRA(graph G, start vertex s, destination vertex d):
5+
6+
//all nodes initially unexplored
7+
8+
1 - let H = min heap data structure, initialized with 0 and s [here 0 indicates
9+
the distance from start vertex s]
10+
2 - while H is non-empty:
11+
3 - remove the first node and cost of H, call it U and cost
12+
4 - if U has been previously explored:
13+
5 - go to the while loop, line 2 //Once a node is explored there is no need
14+
to make it again
15+
6 - mark U as explored
16+
7 - if U is d:
17+
8 - return cost // total cost from start to destination vertex
18+
9 - for each edge(U, V): c=cost of edge(U,V) // for V in graph[U]
19+
10 - if V explored:
20+
11 - go to next V in line 9
21+
12 - total_cost = cost + c
22+
13 - add (total_cost,V) to H
23+
24+
You can think at cost as a distance where Dijkstra finds the shortest distance
25+
between vertexes s and v in a graph G. The use of a min heap as H guarantees
26+
that if a vertex has already been explored there will be no other path with
27+
shortest distance, that happens because heapq.heappop will always return the
28+
next vertex with the shortest distance, considering that the heap stores not
29+
only the distance between previous vertex and current vertex but the entire
30+
distance between each vertex that makes up the path from start vertex to target
31+
vertex.
1732
"""
33+
1834
import heapq
1935

2036

2137
def dijkstra(graph, start, end):
38+
"""Return the cost of the shortest path between vertexes start and end.
39+
40+
>>> dijkstra(G, "E", "C")
41+
6
42+
>>> dijkstra(G2, "E", "F")
43+
3
44+
>>> dijkstra(G3, "E", "F")
45+
3
46+
"""
47+
2248
heap = [(0, start)] # cost from start node,end node
2349
visited = set()
2450
while heap:
@@ -28,20 +54,65 @@ def dijkstra(graph, start, end):
2854
visited.add(u)
2955
if u == end:
3056
return cost
31-
for v, c in G[u]:
57+
for v, c in graph[u]:
3258
if v in visited:
3359
continue
3460
next = cost + c
3561
heapq.heappush(heap, (next, v))
36-
return (-1, -1)
62+
return -1
63+
64+
65+
G = {
66+
"A": [["B", 2], ["C", 5]],
67+
"B": [["A", 2], ["D", 3], ["E", 1], ["F", 1]],
68+
"C": [["A", 5], ["F", 3]],
69+
"D": [["B", 3]],
70+
"E": [["B", 4], ["F", 3]],
71+
"F": [["C", 3], ["E", 3]],
72+
}
73+
74+
"""
75+
Layout of G2:
76+
77+
E -- 1 --> B -- 1 --> C -- 1 --> D -- 1 --> F
78+
\ /\
79+
\ ||
80+
----------------- 3 --------------------
81+
"""
82+
G2 = {
83+
"B": [["C", 1]],
84+
"C": [["D", 1]],
85+
"D": [["F", 1]],
86+
"E": [["B", 1], ["F", 3]],
87+
"F": [],
88+
}
89+
90+
"""
91+
Layout of G3:
92+
93+
E -- 1 --> B -- 1 --> C -- 1 --> D -- 1 --> F
94+
\ /\
95+
\ ||
96+
-------- 2 ---------> G ------- 1 ------
97+
"""
98+
G3 = {
99+
"B": [["C", 1]],
100+
"C": [["D", 1]],
101+
"D": [["F", 1]],
102+
"E": [["B", 1], ["G", 2]],
103+
"F": [],
104+
"G": [["F", 1]],
105+
}
106+
107+
shortDistance = dijkstra(G, "E", "C")
108+
print(shortDistance) # E -- 3 --> F -- 3 --> C == 6
37109

110+
shortDistance = dijkstra(G2, "E", "F")
111+
print(shortDistance) # E -- 3 --> F == 3
38112

39-
G = {'A': [['B', 2], ['C', 5]],
40-
'B': [['A', 2], ['D', 3], ['E', 1]],
41-
'C': [['A', 5], ['F', 3]],
42-
'D': [['B', 3]],
43-
'E': [['B', 1], ['F', 3]],
44-
'F': [['C', 3], ['E', 3]]}
113+
shortDistance = dijkstra(G3, "E", "F")
114+
print(shortDistance) # E -- 2 --> G -- 1 --> F == 3
45115

46-
shortDistance = dijkstra(G, 'E', 'C')
47-
print(shortDistance)
116+
if __name__ == "__main__":
117+
import doctest
118+
doctest.testmod()

0 commit comments

Comments
 (0)