Skip to content

Commit 6584024

Browse files
Add doctests and type hints to graphs/dijkstra_2.py to improve coverage
1 parent a71618f commit 6584024

1 file changed

Lines changed: 80 additions & 45 deletions

File tree

graphs/dijkstra_2.py

Lines changed: 80 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,93 @@
1-
def print_dist(dist, v):
2-
print("\nVertex Distance")
3-
for i in range(v):
4-
if dist[i] != float("inf"):
5-
print(i, "\t", int(dist[i]), end="\t")
6-
else:
7-
print(i, "\t", "INF", end="\t")
8-
print()
1+
"""
2+
Dijkstra's Algorithm Implementation.
93
4+
This module provides an implementation of Dijkstra's algorithm to find the
5+
shortest paths from a source vertex to all other vertices in a weighted directed graph.
6+
7+
The graph is represented using an adjacency matrix where `float("inf")` represents
8+
no direct edge between two vertices.
9+
10+
Example:
11+
>>> graph = [
12+
... [0, 4, float("inf"), float("inf"), float("inf"), float("inf"), float("inf"), 8, float("inf")],
13+
... [4, 0, 8, float("inf"), float("inf"), float("inf"), float("inf"), 11, float("inf")],
14+
... [float("inf"), 8, 0, 7, float("inf"), 4, float("inf"), float("inf"), 2],
15+
... [float("inf"), float("inf"), 7, 0, 9, 14, float("inf"), float("inf"), float("inf")],
16+
... [float("inf"), float("inf"), float("inf"), 9, 0, 10, float("inf"), float("inf"), float("inf")],
17+
... [float("inf"), float("inf"), 4, 14, 10, 0, 2, float("inf"), float("inf")],
18+
... [float("inf"), float("inf"), float("inf"), float("inf"), float("inf"), 2, 0, 1, 6],
19+
... [8, 11, float("inf"), float("inf"), float("inf"), float("inf"), 1, 0, 7],
20+
... [float("inf"), float("inf"), 2, float("inf"), float("inf"), float("inf"), 6, 7, 0],
21+
... ]
22+
>>> dijkstra(graph, 0)
23+
[0, 4, 12, 19, 21, 11, 9, 8, 14]
24+
"""
25+
26+
from typing import List
1027

11-
def min_dist(mdist, vset, v):
12-
min_val = float("inf")
13-
min_ind = -1
14-
for i in range(v):
15-
if (not vset[i]) and mdist[i] < min_val:
16-
min_ind = i
17-
min_val = mdist[i]
18-
return min_ind
1928

29+
def _min_dist(dist: List[float], visited: List[bool]) -> int:
30+
"""
31+
Find the vertex with the minimum distance value from the set of
32+
vertices that have not yet been visited.
33+
34+
Args:
35+
dist: List of current shortest distances from the source.
36+
visited: Boolean list indicating visited vertices.
37+
38+
Returns:
39+
Index of the vertex with the minimum distance value.
40+
"""
41+
min_val = float("inf")
42+
min_index = -1
43+
for i, d in enumerate(dist):
44+
if not visited[i] and d < min_val:
45+
min_val = d
46+
min_index = i
47+
return min_index
2048

21-
def dijkstra(graph, v, src):
22-
mdist = [float("inf") for _ in range(v)]
23-
vset = [False for _ in range(v)]
24-
mdist[src] = 0.0
2549

26-
for _ in range(v - 1):
27-
u = min_dist(mdist, vset, v)
28-
vset[u] = True
50+
def dijkstra(graph: List[List[float]], src: int) -> List[float]:
51+
"""
52+
Compute shortest paths from a source vertex to all other vertices
53+
using Dijkstra's algorithm.
2954
30-
for i in range(v):
31-
if (
32-
(not vset[i])
33-
and graph[u][i] != float("inf")
34-
and mdist[u] + graph[u][i] < mdist[i]
35-
):
36-
mdist[i] = mdist[u] + graph[u][i]
55+
Args:
56+
graph: Adjacency matrix representing the weighted graph.
57+
src: Source vertex index.
3758
38-
print_dist(mdist, i)
59+
Returns:
60+
A list containing the shortest distance from the source to each vertex.
3961
62+
Raises:
63+
ValueError: If the source vertex index is invalid.
4064
41-
if __name__ == "__main__":
42-
V = int(input("Enter number of vertices: ").strip())
43-
E = int(input("Enter number of edges: ").strip())
65+
Example:
66+
>>> graph = [
67+
... [0, 4, float("inf"), float("inf")],
68+
... [4, 0, 8, float("inf")],
69+
... [float("inf"), 8, 0, 7],
70+
... [float("inf"), float("inf"), 7, 0],
71+
... ]
72+
>>> dijkstra(graph, 0)
73+
[0, 4, 12, 19]
74+
"""
75+
num_vertices = len(graph)
76+
if src < 0 or src >= num_vertices:
77+
raise ValueError("Source vertex index out of range")
4478

45-
graph = [[float("inf") for i in range(V)] for j in range(V)]
79+
dist = [float("inf")] * num_vertices
80+
visited = [False] * num_vertices
81+
dist[src] = 0.0
4682

47-
for i in range(V):
48-
graph[i][i] = 0.0
83+
for _ in range(num_vertices - 1):
84+
u = _min_dist(dist, visited)
85+
if u == -1:
86+
break # Remaining vertices are unreachable
87+
visited[u] = True
4988

50-
for i in range(E):
51-
print("\nEdge ", i + 1)
52-
src = int(input("Enter source:").strip())
53-
dst = int(input("Enter destination:").strip())
54-
weight = float(input("Enter weight:").strip())
55-
graph[src][dst] = weight
89+
for v in range(num_vertices):
90+
if not visited[v] and graph[u][v] != float("inf") and dist[u] + graph[u][v] < dist[v]:
91+
dist[v] = dist[u] + graph[u][v]
5692

57-
gsrc = int(input("\nEnter shortest path source:").strip())
58-
dijkstra(graph, V, gsrc)
93+
return [int(d) if d != float("inf") else float("inf") for d in dist]

0 commit comments

Comments
 (0)