An Implementation of Bellman-Ford algorithm in Python.
import math
from dataclasses import dataclass, field
from typing import Generic, TypeVar, Mapping, List
from itertools import count
T = TypeVar('T')
@dataclass
class Node(Generic[T]):
value: T
id: int = field(default_value=count().__next__)
NodeId = int
EdgeWeight = int
Edges = Mapping[NodeId, Mapping[NodeId, EdgeWeight]]
Nodes = Mapping[NodeId, Node]
Distances = Mapping[NodeId, int]
Previouses = Mapping[NodeId, NodeId]
def bellman_ford(source: Node, edges: Edges, nodes: Nodes) -> Tuple[Distances, Previouses]:
"""Solve single-source shortest path using Bellman Ford.
TODO: Return types, explain parameters.
"""
def list_edges() -> Tuple[NodeId, NodeId, EdgeWeight]:
for a_id in edges:
for b_id, weight in edges[a_id]:
yield a_id, b_id, weight
distances = {}
previouses = {}
for node_id,_ in nodes:
distance[node_id] = math.inf
previouses[node_id] = None
distance[source.id] = 0
# Find single-source shortest paths
for _ in range(len(nodes) - 1):
for a_id, b_id, weight in list_edges():
if distance[a_id] + weight < distance[b_id]:
distance[b_id] = distance[a_id] + weight
previouses[b_id] = a_id
# Test for negative cycle
for a_id, b_id, weight in list_edges():
if distance[a_id] + weight < distance[b_id]:
raise Exception('Negative cycle present.')
return distances, previouses