Bellman-Ford Shortest Paths
Solves the single-source shortest-paths problem for a graph with both positive and negative edge weights.
Complexity: O(V E)
Defined in: <boost/graph/bellman_ford_shortest_paths.hpp>
Example
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/bellman_ford_shortest_paths.hpp>
#include <iostream>
#include <limits>
#include <vector>
struct Node {};
struct Edge { int weight; };
using namespace boost;
using Graph = adjacency_list<vecS, vecS, directedS, Node, Edge>;
using Vertex = graph_traits<Graph>::vertex_descriptor;
int main() {
Graph g{4};
add_edge(0, 1, Edge{1}, g);
add_edge(1, 2, Edge{-2}, g);
add_edge(0, 2, Edge{4}, g);
add_edge(2, 3, Edge{3}, g);
auto n = num_vertices(g);
std::vector<int> dist(n, (std::numeric_limits<int>::max)());
std::vector<Vertex> pred(n);
dist[0] = 0;
for (std::size_t i = 0; i < n; ++i)
pred[i] = i;
auto weight_map = get(&Edge::weight, g);
auto dist_map = make_iterator_property_map(dist.begin(), get(vertex_index, g));
auto pred_map = make_iterator_property_map(pred.begin(), get(vertex_index, g));
bellman_ford_shortest_paths(g, n, weight_map, pred_map, dist_map,
std::plus<int>(), std::less<int>(), default_bellman_visitor());
for (auto v : make_iterator_range(vertices(g)))
std::cout << "distance to " << v << " = " << dist[v] << "\n";
}
distance to 0 = 0
distance to 1 = 1
distance to 2 = -1
distance to 3 = 2
(1) Positional version
template <class EdgeListGraph, class Size, class WeightMap,
class PredecessorMap, class DistanceMap,
class BinaryFunction, class BinaryPredicate,
class BellmanFordVisitor>
bool bellman_ford_shortest_paths(
EdgeListGraph& g, Size N,
WeightMap weight, PredecessorMap pred, DistanceMap distance,
BinaryFunction combine, BinaryPredicate compare,
BellmanFordVisitor v);
| Direction | Parameter | Description |
|---|---|---|
IN |
|
A directed or undirected graph whose type must be a model of Edge List Graph. If a root vertex is provided, then the graph must also model Vertex List Graph. |
IN |
|
The number of vertices in the graph. The type |
IN |
|
The weight (also known as "length" or "cost") of each edge in the graph.
The |
OUT |
|
The predecessor map records the edges in the minimum spanning tree. Upon
completion of the algorithm, the edges (p[u],u) for all u in V are in
the minimum spanning tree. If p[u] = u then u is either the source
vertex or a vertex that is not reachable from the source. The
|
IN/OUT |
|
The shortest path weight from the source vertex to each vertex in the graph
|
IN |
|
This function object replaces the role of addition in the relaxation step. The first argument type must match the distance map’s value type and the second argument type must match the weight map’s value type. The result type must be the same as the distance map’s value type. |
IN |
|
This function object replaces the role of the less-than operator that compares distances in the relaxation step. The argument types must match the distance map’s value type. |
IN |
|
The visitor object, whose type must be a model of Bellman-Ford Visitor. The visitor object is passed by value [1]. |
(2) Named parameter version
template <class EdgeListGraph, class Size, class P, class T, class R>
bool bellman_ford_shortest_paths(
const EdgeListGraph& g, Size N,
const bgl_named_params<P, T, R>& params = all defaults);
template <class VertexAndEdgeListGraph, class P, class T, class R>
bool bellman_ford_shortest_paths(
const VertexAndEdgeListGraph& g,
const bgl_named_params<P, T, R>& params = all defaults);
| Direction | Parameter | Description |
|---|---|---|
IN |
|
A directed or undirected graph whose type must be a model of Edge List Graph. If a root vertex is provided, then the graph must also model Vertex List Graph. |
IN |
|
The number of vertices in the graph. The type |
IN |
|
Named parameters passed via |
| Direction | Named Parameter | Description / Default |
|---|---|---|
IN |
|
Edge weights (see (1) |
OUT |
|
Predecessor map (see (1) |
IN/OUT |
|
Distance map (see (1) |
IN |
|
The starting (or "root") vertex from which shortest paths will be computed.
When provided, the distance map need not be initialized (the algorithm will
perform the initialization itself). However, the graph must model
Vertex List Graph when this parameter is
provided. |
IN |
|
Visitor (see (1) |
IN |
|
Distance combination function (see (1) |
IN |
|
Distance comparison function (see (1) |
Description
solves the single-source shortest paths problem for a graph with both positive and negative edge weights. For the definition of the shortest paths problem see Section Shortest-Paths Algorithms. If you only need to solve the shortest paths problem for positive edge weights, Dijkstra’s algorithm provides a more efficient alternative. If all the edge weights are all equal to one then breadth-first search provides an even more efficient alternative.
Before calling the bellman_ford_shortest_paths() function, the user
must assign the source vertex a distance of zero and all other vertices a
distance of infinity unless you are providing a starting vertex. The
Bellman-Ford algorithm proceeds by looping through all of the edges in
the graph, applying the relaxation operation to each edge. In the
following pseudo-code, v is a vertex adjacent to u, w maps edges to
their weight, and d is a distance map that records the length of the
shortest path to each vertex seen so far. p is a predecessor map which
records the parent of each vertex, which will ultimately be the parent in
the shortest paths tree.
Relaxation
|
|
The algorithm repeats this loop \|V\| times after which it is
guaranteed that the distances to each vertex have been reduced to the
minimum possible unless there is a negative cycle in the graph. If there
is a negative cycle, then there will be edges in the graph that were not
properly minimized. That is, there will be edges (u,v) such that
w(u,v) + d[u] < d[v]. The algorithm loops over the edges in the graph
one final time to check if all the edges were minimized, returning true
if they were and returning false otherwise.
Pseudo-Code
BELLMAN-FORD(G)
// Optional initialization
for each vertex u in V
d[u] := infinity
p[u] := u
end for
for i := 1 to |V|-1
for each edge (u,v) in E // examine_edge
RELAX(u, v, w, d, p) // edge_relaxed / edge_not_relaxed
end for
end for
for each edge (u,v) in E
if (w(u,v) + d[u] < d[v]) // edge_not_minimized
return (false, , )
else
... // edge_minimized
end for
return (true, p, d)
There are two main options for obtaining output from the
bellman_ford_shortest_paths() function. If the user provides a distance
property map through the distance_map() parameter then the shortest
distance from the source vertex to every other vertex in the graph will
be recorded in the distance map (provided the function returns true).
The second option is recording the shortest paths tree in the
predecessor_map(). For each vertex u in V, p[u] will be the
predecessor of u in the shortest paths tree (unless p[u] = u, in
which case u is either the source vertex or a vertex unreachable from
the source). In addition to these two options, the user can provide her
own custom-made visitor that can take actions at any of the algorithm’s
event points.
Returns
Returns true if all edges were successfully minimized, indicating there
are no negative-weight cycles reachable from the source. Returns false
if a negative cycle is detected.
Visitor Event Points
-
vis.examine_edge(e, g)is invoked on every edge in the graph \|V\| times. -
vis.edge_relaxed(e, g)is invoked when the distance label for the target vertex is decreased. The edge (u,v) that participated in the last relaxation for vertex v is an edge in the shortest paths tree. -
vis.edge_not_relaxed(e, g)is invoked if the distance label for the target vertex is not decreased. -
vis.edge_minimized(e, g)is invoked during the second stage of the algorithm, during the test of whether each edge was minimized. If the edge is minimized then this function is invoked. -
vis.edge_not_minimized(e, g)is also invoked during the second stage of the algorithm, during the test of whether each edge was minimized. If the edge was not minimized, this function is invoked. This happens when there is a negative cycle in the graph.
Example
See example/bellman-example.cpp
for an example of using the Bellman-Ford algorithm.