Skip to content

Commit 710acd8

Browse files
mhihasanshermanhui
authored andcommitted
Add doctest and fix mypy type annotation in bellman ford (TheAlgorithms#4506)
1 parent 4560ec9 commit 710acd8

File tree

1 file changed

+51
-34
lines changed

1 file changed

+51
-34
lines changed

graphs/bellman_ford.py

+51-34
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,73 @@
11
from __future__ import annotations
22

33

4-
def printDist(dist, V):
5-
print("Vertex Distance")
6-
distances = ("INF" if d == float("inf") else d for d in dist)
7-
print("\t".join(f"{i}\t{d}" for i, d in enumerate(distances)))
4+
def print_distance(distance: list[float], src):
5+
print(f"Vertex\tShortest Distance from vertex {src}")
6+
for i, d in enumerate(distance):
7+
print(f"{i}\t\t{d}")
88

99

10-
def BellmanFord(graph: list[dict[str, int]], V: int, E: int, src: int) -> int:
10+
def check_negative_cycle(
11+
graph: list[dict[str, int]], distance: list[float], edge_count: int
12+
):
13+
for j in range(edge_count):
14+
u, v, w = [graph[j][k] for k in ["src", "dst", "weight"]]
15+
if distance[u] != float("inf") and distance[u] + w < distance[v]:
16+
return True
17+
return False
18+
19+
20+
def bellman_ford(
21+
graph: list[dict[str, int]], vertex_count: int, edge_count: int, src: int
22+
) -> list[float]:
1123
"""
1224
Returns shortest paths from a vertex src to all
1325
other vertices.
26+
>>> edges = [(2, 1, -10), (3, 2, 3), (0, 3, 5), (0, 1, 4)]
27+
>>> g = [{"src": s, "dst": d, "weight": w} for s, d, w in edges]
28+
>>> bellman_ford(g, 4, 4, 0)
29+
[0.0, -2.0, 8.0, 5.0]
30+
>>> g = [{"src": s, "dst": d, "weight": w} for s, d, w in edges + [(1, 3, 5)]]
31+
>>> bellman_ford(g, 4, 5, 0)
32+
Traceback (most recent call last):
33+
...
34+
Exception: Negative cycle found
1435
"""
15-
mdist = [float("inf") for i in range(V)]
16-
mdist[src] = 0.0
36+
distance = [float("inf")] * vertex_count
37+
distance[src] = 0.0
1738

18-
for i in range(V - 1):
19-
for j in range(E):
20-
u = graph[j]["src"]
21-
v = graph[j]["dst"]
22-
w = graph[j]["weight"]
39+
for i in range(vertex_count - 1):
40+
for j in range(edge_count):
41+
u, v, w = [graph[j][k] for k in ["src", "dst", "weight"]]
2342

24-
if mdist[u] != float("inf") and mdist[u] + w < mdist[v]:
25-
mdist[v] = mdist[u] + w
26-
for j in range(E):
27-
u = graph[j]["src"]
28-
v = graph[j]["dst"]
29-
w = graph[j]["weight"]
43+
if distance[u] != float("inf") and distance[u] + w < distance[v]:
44+
distance[v] = distance[u] + w
3045

31-
if mdist[u] != float("inf") and mdist[u] + w < mdist[v]:
32-
print("Negative cycle found. Solution not possible.")
33-
return
46+
negative_cycle_exists = check_negative_cycle(graph, distance, edge_count)
47+
if negative_cycle_exists:
48+
raise Exception("Negative cycle found")
3449

35-
printDist(mdist, V)
36-
return src
50+
return distance
3751

3852

3953
if __name__ == "__main__":
54+
import doctest
55+
56+
doctest.testmod()
57+
4058
V = int(input("Enter number of vertices: ").strip())
4159
E = int(input("Enter number of edges: ").strip())
4260

43-
graph = [dict() for j in range(E)]
61+
graph: list[dict[str, int]] = [dict() for j in range(E)]
4462

4563
for i in range(E):
46-
graph[i][i] = 0.0
64+
print("Edge ", i + 1)
65+
src, dest, weight = [
66+
int(x)
67+
for x in input("Enter source, destination, weight: ").strip().split(" ")
68+
]
69+
graph[i] = {"src": src, "dst": dest, "weight": weight}
4770

48-
for i in range(E):
49-
print("\nEdge ", i + 1)
50-
src = int(input("Enter source:").strip())
51-
dst = int(input("Enter destination:").strip())
52-
weight = float(input("Enter weight:").strip())
53-
graph[i] = {"src": src, "dst": dst, "weight": weight}
54-
55-
gsrc = int(input("\nEnter shortest path source:").strip())
56-
BellmanFord(graph, V, E, gsrc)
71+
source = int(input("\nEnter shortest path source:").strip())
72+
shortest_distance = bellman_ford(graph, V, E, source)
73+
print_distance(shortest_distance, 0)

0 commit comments

Comments
 (0)