Bellman–Ford Algorithm
Algorithm · Stretch
Step through it: Weighted Shortest Path pattern
Step 1 of 6
Goal: the cheapest route from A to every place when roads have different costs: A→B 4, A→C 1, C→B 2, B→D 1. Keep a table of the best known cost to each place: 0 for A, unknown for the rest.
Step 2 of 6
Always finish the closest unfinished place first: A (cost 0). Try its roads: B costs 0 + 4 = 4 and C costs 0 + 1 = 1.
Step 3 of 6
The closest unfinished place is now C (1). The road C→B gives B a cost of 1 + 2 = 3, cheaper than 4, so update B.
Step 4 of 6
Closest unfinished: B (3). The road B→D gives D a cost of 3 + 1 = 4.
Step 5 of 6
The cheapest A to D is 4, via A, C, B, D. Finishing the closest place first guarantees no later road can beat it, as long as no cost is negative. A priority queue finds the closest place quickly. This is Dijkstra's algorithm.
Step 6 of 6
Your turn.
Complexity
Time Complexity
Worst-case: O(|V||E|)
Best-case: O(|E|)
Space Complexity
Worst-case: O(|V|)
The Bellman–Ford algorithm is an algorithm that computes shortest paths from a single source vertex to all of the other vertices in a weighted digraph. It is slower than Dijkstra's algorithm for the same problem, but more versatile, as it is capable of handling graphs in which some of the edge weights are negative numbers.
Code
/**
* @param {Graph} graph
* @param {GraphVertex} startVertex
* @return {{distances, previousVertices}}
*/
export default function bellmanFord(graph, startVertex) {
const distances = {};
const previousVertices = {};
// Init all distances with infinity assuming that currently we can't reach
// any of the vertices except start one.
distances[startVertex.getKey()] = 0;
graph.getAllVertices().forEach((vertex) => {
previousVertices[vertex.getKey()] = null;
if (vertex.getKey() !== startVertex.getKey()) {
distances[vertex.getKey()] = Infinity;
}
});
// We need (|V| - 1) iterations.
for (let iteration = 0; iteration < (graph.getAllVertices().length - 1); iteration += 1) {
// During each iteration go through all vertices.
Object.keys(distances).forEach((vertexKey) => {
const vertex = graph.getVertexByKey(vertexKey);
// Go through all vertex edges.
graph.getNeighbors(vertex).forEach((neighbor) => {
const edge = graph.findEdge(vertex, neighbor);
// Find out if the distance to the neighbor is shorter in this iteration
// then in previous one.
const distanceToVertex = distances[vertex.getKey()];
const distanceToNeighbor = distanceToVertex + edge.weight;
if (distanceToNeighbor < distances[neighbor.getKey()]) {
distances[neighbor.getKey()] = distanceToNeighbor;
previousVertices[neighbor.getKey()] = vertex;
}
});
});
}
return {
distances,
previousVertices,
};
}References
Practice
Weighted Shortest Path
- Network Delay TimeMedium
- Cheapest Flights Within K StopsMedium
- Path With Minimum EffortMedium
- Path with Maximum ProbabilityMedium
- Find the City With the Smallest Number of NeighborsMedium
- Minimum Cost to Reach Destination in TimeMedium
- Swim in Rising WaterHard
- Minimum Cost to Make at Least One Valid Path in a GridHard
Spotted a mistake or something unclear? Report it on GitHub.