From 77e1ea26accbde71d22d518f98f26066a343b41f Mon Sep 17 00:00:00 2001 From: yashwanth-adimulam Date: Wed, 30 Oct 2024 11:48:41 +0530 Subject: [PATCH 1/2] making dijkstra_2 better --- graphs/dijkstra_2.py | 126 ++++++++++++++++++++++++++++--------------- 1 file changed, 84 insertions(+), 42 deletions(-) diff --git a/graphs/dijkstra_2.py b/graphs/dijkstra_2.py index f548463ff7bd..fe3b4e8cc8f6 100644 --- a/graphs/dijkstra_2.py +++ b/graphs/dijkstra_2.py @@ -1,58 +1,100 @@ -def print_dist(dist, v): - print("\nVertex Distance") - for i in range(v): - if dist[i] != float("inf"): - print(i, "\t", int(dist[i]), end="\t") - else: - print(i, "\t", "INF", end="\t") - print() +from typing import List +def print_distances(distances: List[float]) -> None: + print("\nVertex Distance") + for vertex, distance in enumerate(distances): + print(f"{vertex}\t{int(distance) if distance != float('inf') else 'INF'}") -def min_dist(mdist, vset, v): - min_val = float("inf") - min_ind = -1 - for i in range(v): - if (not vset[i]) and mdist[i] < min_val: - min_ind = i - min_val = mdist[i] - return min_ind +def find_min_distance(distances: List[float], visited: List[bool]) -> int: + min_distance = float("inf") + min_index = -1 + + for i in range(len(distances)): + if not visited[i] and distances[i] < min_distance: + min_distance = distances[i] + min_index = i + + return min_index +def dijkstra(graph: List[List[float]], num_vertices: int, source: int) -> List[float]: + distances = [float("inf")] * num_vertices + visited = [False] * num_vertices + distances[source] = 0 -def dijkstra(graph, v, src): - mdist = [float("inf") for _ in range(v)] - vset = [False for _ in range(v)] - mdist[src] = 0.0 + for _ in range(num_vertices - 1): + u = find_min_distance(distances, visited) + visited[u] = True - for _ in range(v - 1): - u = min_dist(mdist, vset, v) - vset[u] = True + for v in range(num_vertices): + if (not visited[v] and graph[u][v] != float("inf") + and distances[u] + graph[u][v] < distances[v]): + distances[v] = distances[u] + graph[u][v] - for i in range(v): - if ( - (not vset[i]) - and graph[u][i] != float("inf") - and mdist[u] + graph[u][i] < mdist[i] - ): - mdist[i] = mdist[u] + graph[u][i] + return distances - print_dist(mdist, i) +def is_connected(graph: List[List[float]], num_vertices: int) -> bool: + visited = [False] * num_vertices + stack = [0] # Start DFS from the first vertex + visited[0] = True + + while stack: + node = stack.pop() + for neighbor in range(num_vertices): + if graph[node][neighbor] != float("inf") and not visited[neighbor]: + visited[neighbor] = True + stack.append(neighbor) + return all(visited) -if __name__ == "__main__": +def main() -> None: V = int(input("Enter number of vertices: ").strip()) - E = int(input("Enter number of edges: ").strip()) - - graph = [[float("inf") for i in range(V)] for j in range(V)] - + if V <= 0: + print("Error: The number of vertices must be greater than 0.") + return + + E = int(input("Enter number of edges (must be >= V-1): ").strip()) + if E < V - 1: + print(f"Error: The number of edges must be at least {V - 1} for a connected graph.") + return + + graph = [[float("inf")] * V for _ in range(V)] + for i in range(V): graph[i][i] = 0.0 for i in range(E): - print("\nEdge ", i + 1) - src = int(input("Enter source:").strip()) - dst = int(input("Enter destination:").strip()) - weight = float(input("Enter weight:").strip()) + print(f"\nEdge {i + 1}") + src = int(input(f"Enter source (0 to {V - 1}): ").strip()) + dst = int(input(f"Enter destination (0 to {V - 1}): ").strip()) + + if src < 0 or src >= V or dst < 0 or dst >= V: + print("Error: Source and destination must be valid vertex indices.") + return + + weight = float(input("Enter weight (non-negative): ").strip()) + if weight < 0: + print("Error: Weight must be non-negative.") + return + + if src == dst: + print("Warning: Self-loop detected; it will be allowed but consider its implications.") + + # Handle duplicate edges: (optionally overwrite or warn) + if graph[src][dst] != float("inf"): + print("Warning: Duplicate edge detected; the weight will be updated.") + graph[src][dst] = weight - gsrc = int(input("\nEnter shortest path source:").strip()) - dijkstra(graph, V, gsrc) + if not is_connected(graph, V): + print("Warning: The graph is not connected. Dijkstra's algorithm may not yield valid results for all vertices.") + + gsrc = int(input(f"\nEnter shortest path source (0 to {V - 1}): ").strip()) + if gsrc < 0 or gsrc >= V: + print("Error: Source must be a valid vertex index.") + return + + distances = dijkstra(graph, V, gsrc) + print_distances(distances) + +if __name__ == "__main__": + main() From 2b1e000e02d4fbed220a08c44c1dd9be317587c2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:09:50 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- graphs/dijkstra_2.py | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/graphs/dijkstra_2.py b/graphs/dijkstra_2.py index fe3b4e8cc8f6..c699d20e1aa9 100644 --- a/graphs/dijkstra_2.py +++ b/graphs/dijkstra_2.py @@ -1,21 +1,24 @@ from typing import List + def print_distances(distances: List[float]) -> None: print("\nVertex Distance") for vertex, distance in enumerate(distances): print(f"{vertex}\t{int(distance) if distance != float('inf') else 'INF'}") + def find_min_distance(distances: List[float], visited: List[bool]) -> int: min_distance = float("inf") min_index = -1 - + for i in range(len(distances)): if not visited[i] and distances[i] < min_distance: min_distance = distances[i] min_index = i - + return min_index + def dijkstra(graph: List[List[float]], num_vertices: int, source: int) -> List[float]: distances = [float("inf")] * num_vertices visited = [False] * num_vertices @@ -26,17 +29,21 @@ def dijkstra(graph: List[List[float]], num_vertices: int, source: int) -> List[f visited[u] = True for v in range(num_vertices): - if (not visited[v] and graph[u][v] != float("inf") - and distances[u] + graph[u][v] < distances[v]): + if ( + not visited[v] + and graph[u][v] != float("inf") + and distances[u] + graph[u][v] < distances[v] + ): distances[v] = distances[u] + graph[u][v] return distances + def is_connected(graph: List[List[float]], num_vertices: int) -> bool: visited = [False] * num_vertices stack = [0] # Start DFS from the first vertex visited[0] = True - + while stack: node = stack.pop() for neighbor in range(num_vertices): @@ -46,19 +53,22 @@ def is_connected(graph: List[List[float]], num_vertices: int) -> bool: return all(visited) + def main() -> None: V = int(input("Enter number of vertices: ").strip()) if V <= 0: print("Error: The number of vertices must be greater than 0.") return - + E = int(input("Enter number of edges (must be >= V-1): ").strip()) if E < V - 1: - print(f"Error: The number of edges must be at least {V - 1} for a connected graph.") + print( + f"Error: The number of edges must be at least {V - 1} for a connected graph." + ) return - + graph = [[float("inf")] * V for _ in range(V)] - + for i in range(V): graph[i][i] = 0.0 @@ -66,18 +76,20 @@ def main() -> None: print(f"\nEdge {i + 1}") src = int(input(f"Enter source (0 to {V - 1}): ").strip()) dst = int(input(f"Enter destination (0 to {V - 1}): ").strip()) - + if src < 0 or src >= V or dst < 0 or dst >= V: print("Error: Source and destination must be valid vertex indices.") return - + weight = float(input("Enter weight (non-negative): ").strip()) if weight < 0: print("Error: Weight must be non-negative.") return - + if src == dst: - print("Warning: Self-loop detected; it will be allowed but consider its implications.") + print( + "Warning: Self-loop detected; it will be allowed but consider its implications." + ) # Handle duplicate edges: (optionally overwrite or warn) if graph[src][dst] != float("inf"): @@ -86,7 +98,9 @@ def main() -> None: graph[src][dst] = weight if not is_connected(graph, V): - print("Warning: The graph is not connected. Dijkstra's algorithm may not yield valid results for all vertices.") + print( + "Warning: The graph is not connected. Dijkstra's algorithm may not yield valid results for all vertices." + ) gsrc = int(input(f"\nEnter shortest path source (0 to {V - 1}): ").strip()) if gsrc < 0 or gsrc >= V: @@ -96,5 +110,6 @@ def main() -> None: distances = dijkstra(graph, V, gsrc) print_distances(distances) + if __name__ == "__main__": main()