This documentation is being rewritten. If something looks off, please cross-check with the Boost 1.91.0 Boost.Graph docs and open an issue.

Push-Relabel Maximum Flow

Calculates the maximum flow of a network using the push-relabel algorithm.

Complexity: O(V3)
Defined in: <boost/graph/push_relabel_max_flow.hpp>

Example

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/push_relabel_max_flow.hpp>
#include <iostream>

using namespace boost;

using Traits = adjacency_list_traits<vecS, vecS, directedS>;
struct Edge {
    int capacity;
    int residual_capacity;
    Traits::edge_descriptor reverse;
};

using Graph = adjacency_list<vecS, vecS, directedS, no_property, Edge>;
using Descriptor = graph_traits<Graph>::edge_descriptor;
using Vertex = graph_traits<Graph>::vertex_descriptor;

void add_flow_edge(Graph& g, int from, int to, int cap) {
    Descriptor e = add_edge(from, to, g).first;
    Descriptor r = add_edge(to, from, g).first;
    g[e].capacity = cap; g[e].reverse = r;
    g[r].capacity = 0;   g[r].reverse = e;
}

int main() {
    Graph g(4);
    add_flow_edge(g, 0, 1, 10);
    add_flow_edge(g, 0, 2, 10);
    add_flow_edge(g, 1, 3, 5);
    add_flow_edge(g, 2, 3, 15);
    add_flow_edge(g, 1, 2, 4);

    int flow = push_relabel_max_flow(g, Vertex(0), Vertex(3),
        get(&Edge::capacity, g),
        get(&Edge::residual_capacity, g),
        get(&Edge::reverse, g),
        get(vertex_index, g));
    std::cout << "Push-relabel max flow: " << flow << "\n";
}
Push-relabel max flow: 19

(1) Positional version

template <class Graph,
          class CapacityEdgeMap, class ResidualCapacityEdgeMap,
          class ReverseEdgeMap, class VertexIndexMap>
typename property_traits<CapacityEdgeMap>::value_type push_relabel_max_flow(
    Graph& g,
    typename graph_traits<Graph>::vertex_descriptor src,
    typename graph_traits<Graph>::vertex_descriptor sink,
    CapacityEdgeMap cap, ResidualCapacityEdgeMap res,
    ReverseEdgeMap rev, VertexIndexMap index_map)
Direction Parameter Description

IN

Graph& g

A directed graph. The graph’s type must be a model of Vertex List Graph. For each edge (u,v) in the graph, the reverse edge (v,u) must also be in the graph.

IN

vertex_descriptor src

The source vertex for the flow network graph.

IN

vertex_descriptor sink

The sink vertex for the flow network graph.

IN

CapacityEdgeMap cap

The edge capacity property map. The type must be a model of a constant Lvalue Property Map. The key type of the map must be the graph’s edge descriptor type.

OUT

ResidualCapacityEdgeMap res

The edge residual capacity property map. The type must be a model of a mutable Lvalue Property Map. The key type of the map must be the graph’s edge descriptor type.

IN

ReverseEdgeMap rev

An edge property map that maps every edge (u,v) in the graph to the reverse edge (v,u). The map must be a model of constant Lvalue Property Map. The key type of the map must be the graph’s edge descriptor type.

IN

VertexIndexMap index_map

Maps each vertex of the graph to a unique integer in the range [0, num_vertices(g)). The map must be a model of constant Lvalue Property Map. The key type of the map must be the graph’s vertex descriptor type.


(2) Named parameter version

template <class Graph, class P, class T, class R>
typename property_traits<CapacityEdgeMap>::value_type push_relabel_max_flow(
    Graph& g,
    typename graph_traits<Graph>::vertex_descriptor src,
    typename graph_traits<Graph>::vertex_descriptor sink,
    const bgl_named_params<P, T, R>& params = all defaults)
Direction Parameter Description

IN

Graph& g

A directed graph. Must model Vertex List Graph. For each edge (u,v) in the graph, the reverse edge (v,u) must also be in the graph.

IN

vertex_descriptor src

The source vertex for the flow network graph.

IN

vertex_descriptor sink

The sink vertex for the flow network graph.

IN

params

Named parameters passed via bgl_named_params. The following are accepted:

Direction Named Parameter Description / Default

IN

capacity_map(EdgeCapacityMap cap)

The edge capacity property map. The type must be a model of a constant Lvalue Property Map. The key type of the map must be the graph’s edge descriptor type.
Default: get(edge_capacity, g)

OUT

residual_capacity_map(ResidualCapacityEdgeMap res)

The edge residual capacity property map. The type must be a model of a mutable Lvalue Property Map. The key type of the map must be the graph’s edge descriptor type.
Default: get(edge_residual_capacity, g)

IN

reverse_edge_map(ReverseEdgeMap rev)

An edge property map that maps every edge (u,v) in the graph to the reverse edge (v,u). The map must be a model of constant Lvalue Property Map. The key type of the map must be the graph’s edge descriptor type.
Default: get(edge_reverse, g)

IN

vertex_index_map(VertexIndexMap index_map)

Maps each vertex of the graph to a unique integer in the range [0, num_vertices(g)). The map must be a model of constant Lvalue Property Map. The key type of the map must be the graph’s vertex descriptor type.
Default: get(vertex_index, g). Note: if you use this default, make sure your graph has an internal vertex_index property. For example, adjacency_list with VertexList=listS does not have an internal vertex_index property.

Description

The push_relabel_max_flow() function implements the push-relabel algorithm to calculate the maximum flow of a network. See Section Network Flow Algorithms for a description of maximum flow. The calculated maximum flow will be the return value of the function. The function also calculates the flow values f(u,v) for all (u,v) in E, which are returned in the form of the residual capacity r(u,v) = c(u,v) - f(u,v).

There are several special requirements on the input graph and property map parameters for this algorithm. First, the directed graph G=(V,E) that represents the network must be augmented to include the reverse edge for every edge in E. That is, the input graph should be Gin = (V,{E U ET}). The ReverseEdgeMap argument rev must map each edge in the original graph to its reverse edge, that is (u,v) → (v,u) for all (u,v) in E. The CapacityEdgeMap argument cap must map each edge in E to a positive number, and each edge in ET to 0.

This algorithm was developed by Goldberg.

Returns

The maximum flow value, of type property_traits<CapacityEdgeMap>::value_type.

Example

This reads in an example maximum flow problem (a graph with edge capacities) from a file in the DIMACS format. The source for this example can be found in example/max_flow.cpp.

#include <boost/config.hpp>
#include <iostream>
#include <string>
#include <boost/graph/push_relabel_max_flow.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/read_dimacs.hpp>

int
main()
{
  using namespace boost;

  typedef adjacency_list_traits<vecS, vecS, directedS> Traits;
  typedef adjacency_list<vecS, vecS, directedS,
    property<vertex_name_t, std::string>,
    property<edge_capacity_t, long,
      property<edge_residual_capacity_t, long,
    property<edge_reverse_t, Traits::edge_descriptor> > >
  > Graph;

  Graph g;
  long flow;

  property_map<Graph, edge_capacity_t>::type
    capacity = get(edge_capacity, g);
  property_map<Graph, edge_reverse_t>::type
    rev = get(edge_reverse, g);
  property_map<Graph, edge_residual_capacity_t>::type
    residual_capacity = get(edge_residual_capacity, g);

  Traits::vertex_descriptor s, t;
  read_dimacs_max_flow(g, capacity, rev, s, t);

  flow = push_relabel_max_flow(g, s, t);

  std::cout << "c  The total flow:" << std::endl;
  std::cout << "s " << flow << std::endl << std::endl;

  std::cout << "c flow values:" << std::endl;
  graph_traits<Graph>::vertex_iterator u_iter, u_end;
  graph_traits<Graph>::out_edge_iterator ei, e_end;
  for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
    for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
      if (capacity[*ei] > 0)
        std::cout << "f " << *u_iter << " " << target(*ei, g) << " "
                  << (capacity[*ei] - residual_capacity[*ei]) << std::endl;
  return 0;
}

The output is:

c  The total flow:
s 4

c flow values:
f 0 1 4
f 1 2 4
f 2 3 2
f 2 4 2
f 3 1 0
f 3 6 2
f 4 5 3
f 5 6 0
f 5 7 3
f 6 4 1
f 6 7 1