mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-04-07 06:15:55 +00:00
Improved Bellman-Ford Algorithm : Added Path Reconstruction With Better Output Representation
This commit is contained in:
parent
f8a94a8b00
commit
4a30fcd84d
@ -17,22 +17,28 @@ def print_distance_and_paths(distance: list[float], paths: list[list[int]], src:
|
||||
print(f"{vertex}\t\t{dist}\t\t\t\t{path_str}")
|
||||
|
||||
|
||||
def check_negative_cycle(graph: list[Edge], distance: list[float], predecessor: list[int]) -> bool:
|
||||
def check_negative_cycle(graph: list[Edge], distance: list[float],
|
||||
predecessor: list[int]) -> bool:
|
||||
"""
|
||||
Checks if there is a negative weight cycle reachable from the source vertex.
|
||||
If found, return True, indicating a negative cycle.
|
||||
"""
|
||||
for edge in graph:
|
||||
if distance[edge.src] != float("inf") and distance[edge.src] + edge.weight < distance[edge.dst]:
|
||||
if (distance[edge.src] != float("inf") and
|
||||
distance[edge.src] + edge.weight
|
||||
< distance[edge.dst]):
|
||||
# Update predecessors to indicate a cycle for affected paths
|
||||
predecessor[edge.dst] = -1 # Use -1 as a marker for negative cycle detection
|
||||
# Use -1 as a marker for negative cycle detection
|
||||
predecessor[edge.dst] = -1
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def reconstruct_paths(predecessor: list[int], vertex_count: int, src: int) -> list[list[int]]:
|
||||
def reconstruct_paths(predecessor: list[int],
|
||||
vertex_count: int, src: int) -> list[list[int]]:
|
||||
"""
|
||||
Reconstructs the shortest paths from the source vertex to each vertex using the predecessor list.
|
||||
Reconstructs the shortest paths from the source vertex to
|
||||
each vertex using the predecessor list.
|
||||
"""
|
||||
paths = [[] for _ in range(vertex_count)]
|
||||
for vertex in range(vertex_count):
|
||||
@ -50,9 +56,11 @@ def reconstruct_paths(predecessor: list[int], vertex_count: int, src: int) -> li
|
||||
return paths
|
||||
|
||||
|
||||
def bellman_ford(graph: list[Edge], vertex_count: int, src: int) -> tuple[list[float], list[list[int]]]:
|
||||
def bellman_ford(graph: list[Edge],
|
||||
vertex_count: int, src: int) -> tuple[list[float], list[list[int]]]:
|
||||
"""
|
||||
Returns the shortest paths from a vertex src to all other vertices, including path reconstruction.
|
||||
Returns the shortest paths from a vertex src to all other vertices,
|
||||
including path reconstruction.
|
||||
"""
|
||||
distance = [float("inf")] * vertex_count
|
||||
predecessor = [None] * vertex_count # Keeps track of the path predecessors
|
||||
@ -61,7 +69,8 @@ def bellman_ford(graph: list[Edge], vertex_count: int, src: int) -> tuple[list[f
|
||||
# Step 1: Relax edges repeatedly
|
||||
for _ in range(vertex_count - 1):
|
||||
for edge in graph:
|
||||
if distance[edge.src] != float("inf") and distance[edge.src] + edge.weight < distance[edge.dst]:
|
||||
if (distance[edge.src] != float("inf") and
|
||||
distance[edge.src] + edge.weight < distance[edge.dst]):
|
||||
distance[edge.dst] = distance[edge.src] + edge.weight
|
||||
predecessor[edge.dst] = edge.src
|
||||
|
||||
@ -88,7 +97,8 @@ if __name__ == "__main__":
|
||||
|
||||
for i in range(E):
|
||||
print(f"Edge {i + 1}")
|
||||
src, dest, weight = map(int, input("Enter source, destination, weight: ").strip().split())
|
||||
src, dest, weight = map(int,
|
||||
input("Enter source, destination, weight: ").strip().split())
|
||||
if src < 0 or src >= V or dest < 0 or dest >= V:
|
||||
print(f"Invalid vertices: src and dest should be between 0 and {V - 1}")
|
||||
continue
|
||||
@ -101,6 +111,4 @@ if __name__ == "__main__":
|
||||
shortest_distance, paths = bellman_ford(graph, V, source)
|
||||
print_distance_and_paths(shortest_distance, paths, source)
|
||||
except ValueError:
|
||||
print("Please enter valid integer inputs.")
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print("Invalid input. Please enter valid integers.")
|
||||
|
Loading…
x
Reference in New Issue
Block a user