|
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. |
9 | 3 |
|
| 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 |
10 | 27 |
|
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 |
19 | 28 |
|
| 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 |
20 | 48 |
|
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 |
25 | 49 |
|
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. |
29 | 54 |
|
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. |
37 | 58 |
|
38 | | - print_dist(mdist, i) |
| 59 | + Returns: |
| 60 | + A list containing the shortest distance from the source to each vertex. |
39 | 61 |
|
| 62 | + Raises: |
| 63 | + ValueError: If the source vertex index is invalid. |
40 | 64 |
|
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") |
44 | 78 |
|
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 |
46 | 82 |
|
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 |
49 | 88 |
|
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] |
56 | 92 |
|
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