An algorithm for finding the shortest path in a weighted graph. In short:
- iterate through all vertices V-1 times (since a path can have at most V-1 edges)
- check for negative-weight cycles
Steps:
- begin with an edge list for the graph
- create a dict to store min distances
- to source: 0
- to all other nodes: infinite
- for each vertex, repeat the following V-1 times:
- for each edge (u, v) with weight w, if the distance to u plus w is less than the distance to v, update the distance to v.
- after V-1 iterations, check for negative-weight cycles by verifying if a further relaxation is possible.
def bellman_ford(graph, V, src):
dist = [float('inf')] * V
dist[src] = 0
for _ in range(V - 1):
for u, v, w in graph:
if dist[u] != float('inf') and dist[u] + w < dist[v]:
dist[v] = dist[u] + w
# Check for negative-weight cycles
for u, v, w in graph:
if dist[u] != float('inf') and dist[u] + w < dist[v]:
return "Graph contains a negative weight cycle"
return dist
# Example usage
graph = [
(0, 1, -1), (0, 2, 4), (1, 2, 3),
(1, 3, 2), (1, 4, 2), (3, 2, 5),
(3, 1, 1), (4, 3, -3)
]
V = 5
src = 0
print(bellman_ford(graph, V, src))
SPFA
def spfa(graph, source):
# Initialize distances to all vertices as infinite and source's distance as 0
dist = {v: float('inf') for v in graph}
dist[source] = 0
# Initialize queue and enqueue source vertex
queue = deque([source])
in_queue = {v: False for v in graph}
in_queue[source] = True
while queue:
u = queue.popleft()
in_queue[u] = False
# Relax all adjacent vertices of u
for v, weight in graph[u]:
if dist[u] + weight < dist[v]:
dist[v] = dist[u] + weight
if not in_queue[v]:
queue.append(v)
in_queue[v] = True
return dist
# Example usage
if __name__ == "__main__":
graph = defaultdict(list)
graph[0].extend([(1, 4), (2, 5)])
graph[1].extend([(2, -3), (3, 2)])
graph[2].extend([(3, 4)])
graph[3].extend([]) # No outgoing edges from vertex 3
source = 0
distances = spfa(graph, source)
print("Shortest distances from source vertex", source)
for vertex in distances:
print(f"Vertex {vertex}: {distances[vertex]}")