[#sec:push_relabel_max_flow]
= Push-Relabel Maximum Flow

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

*Complexity:* _O(V^3^)_ +
*Defined in:* `<boost/graph/push_relabel_max_flow.hpp>`

== Example

[source,cpp]
----
include::example$algorithms/network_flow/push_relabel.cpp[]
----

[,text]
----
include::example$algorithms/network_flow/push_relabel.txt[]
----

'''

=== (1) Positional version

[source,cpp]
----
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)
----

[cols="1,2,5"]
|===
| Direction | Parameter | Description

| IN
| `Graph& g`
| A directed graph. The graph's type must be a model of
  xref:concepts/VertexListGraph.adoc[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
  link:../../property_map/doc/LvaluePropertyMap.html[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 link:../../property_map/doc/LvaluePropertyMap.html[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
  link:../../property_map/doc/LvaluePropertyMap.html[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
  link:../../property_map/doc/LvaluePropertyMap.html[Lvalue Property Map].
  The key type of the map must be the graph's vertex descriptor type.

|===

'''

=== (2) Named parameter version

[source,cpp]
----
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)
----

[cols="1,2,5"]
|===
| Direction | Parameter | Description

| IN
| `Graph& g`
| A directed graph. Must model xref:concepts/VertexListGraph.adoc[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:
|===

[cols="1,2,5"]
|===
| Direction | Named Parameter | Description / Default

| IN
| `capacity_map(EdgeCapacityMap cap)`
| The edge capacity property map. The type must be a model of a constant
  link:../../property_map/doc/LvaluePropertyMap.html[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 link:../../property_map/doc/LvaluePropertyMap.html[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
  link:../../property_map/doc/LvaluePropertyMap.html[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
  link:../../property_map/doc/LvaluePropertyMap.html[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
https://en.wikipedia.org/wiki/Push%E2%80%93relabel_maximum_flow_algorithm[push-relabel algorithm]
to calculate the maximum flow of a network. See Section
xref:about/graph_theory_review.adoc#sec:network-flow-algorithms[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 _G~in~ =
(V,{E U E^T^})_. 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 _E^T^_ to 0.

This algorithm was developed by
xref:about/bibliography.adoc#goldberg85:_new_max_flow_algor[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 link:../example/max_flow.cpp[`example/max_flow.cpp`].

[source,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
....

