forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dijkstra_alternate.py
98 lines (83 loc) · 3.12 KB
/
dijkstra_alternate.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
from __future__ import annotations
class Graph:
def __init__(self, vertices: int) -> None:
"""
>>> graph = Graph(2)
>>> graph.vertices
2
>>> len(graph.graph)
2
>>> len(graph.graph[0])
2
"""
self.vertices = vertices
self.graph = [[0] * vertices for _ in range(vertices)]
def print_solution(self, distances_from_source: list[int]) -> None:
"""
>>> Graph(0).print_solution([]) # doctest: +NORMALIZE_WHITESPACE
Vertex Distance from Source
"""
print("Vertex \t Distance from Source")
for vertex in range(self.vertices):
print(vertex, "\t\t", distances_from_source[vertex])
def minimum_distance(
self, distances_from_source: list[int], visited: list[bool]
) -> int:
"""
A utility function to find the vertex with minimum distance value, from the set
of vertices not yet included in shortest path tree.
>>> Graph(3).minimum_distance([1, 2, 3], [False, False, True])
0
"""
# Initialize minimum distance for next node
minimum = 1e7
min_index = 0
# Search not nearest vertex not in the shortest path tree
for vertex in range(self.vertices):
if distances_from_source[vertex] < minimum and visited[vertex] is False:
minimum = distances_from_source[vertex]
min_index = vertex
return min_index
def dijkstra(self, source: int) -> None:
"""
Function that implements Dijkstra's single source shortest path algorithm for a
graph represented using adjacency matrix representation.
>>> Graph(4).dijkstra(1) # doctest: +NORMALIZE_WHITESPACE
Vertex Distance from Source
0 10000000
1 0
2 10000000
3 10000000
"""
distances = [int(1e7)] * self.vertices # distances from the source
distances[source] = 0
visited = [False] * self.vertices
for _ in range(self.vertices):
u = self.minimum_distance(distances, visited)
visited[u] = True
# Update dist value of the adjacent vertices
# of the picked vertex only if the current
# distance is greater than new distance and
# the vertex in not in the shortest path tree
for v in range(self.vertices):
if (
self.graph[u][v] > 0
and visited[v] is False
and distances[v] > distances[u] + self.graph[u][v]
):
distances[v] = distances[u] + self.graph[u][v]
self.print_solution(distances)
if __name__ == "__main__":
graph = Graph(9)
graph.graph = [
[0, 4, 0, 0, 0, 0, 0, 8, 0],
[4, 0, 8, 0, 0, 0, 0, 11, 0],
[0, 8, 0, 7, 0, 4, 0, 0, 2],
[0, 0, 7, 0, 9, 14, 0, 0, 0],
[0, 0, 0, 9, 0, 10, 0, 0, 0],
[0, 0, 4, 14, 10, 0, 2, 0, 0],
[0, 0, 0, 0, 0, 2, 0, 1, 6],
[8, 11, 0, 0, 0, 0, 1, 0, 7],
[0, 0, 2, 0, 0, 0, 6, 7, 0],
]
graph.dijkstra(0)