Boost Graph Library: Cycle Canceling for Min Cost Max Flow

# `cycle_canceling`

    // named parameter version
    template <class Graph, class P, class T, class R>
    void cycle_canceling(
            Graph &g,
            const bgl_named_params<P, T, R> & params  = all defaults)

    // non-named parameter version
    template <class Graph, class Pred, class Distance, class Reversed, class ResidualCapacity, class Weight>
    void cycle_canceling(const Graph & g, Weight weight, Reversed rev, ResidualCapacity residual_capacity, Pred pred, Distance distance)

The `cycle_canceling()` function calculates the minimum cost flow of a network with given flow. See Section Network Flow Algorithms for a description of maximum flow. For given flow values f(u,v) function minimizes flow cost in such a way, that for each v in V the sum u in V f(v,u) is preserved. Particularly if the input flow was the maximum flow, the function produces min cost max flow. The function 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 `WeightMap` has to map each edge from ET to -weight of its reversed edge. Note that edges from E can have negative weights.

If weights in the graph are nonnegative, the `successive_shortest_path_nonnegative_weights()` might be better choice for min cost max flow.

The algorithm is described in Network Flows.

In each round algorithm augments the negative cycle (in terms of weight) in the residual graph. If there is no negative cycle in the network, the cost is optimized.

Note that, although we mention capacity in the problem description, the actual algorithm doesn't have to now it.

In order to find the cost of the result flow use: `find_flow_cost()`.

### Where Defined

`boost/graph/successive_shortest_path_nonnegative_weights.hpp`

### Parameters

IN: `Graph& g`

> A directed graph. The graph's type must be a model of VertexListGraph and IncidenceGraph For each edge (u,v) in the graph, the reverse edge (v,u) must also be in the graph.

### Named Parameters

IN/OUT: `residual_capacity_map(ResidualCapacityEdgeMap res)`

> This maps edges to their residual capacity. 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: `weight_map(WeightMap w)`

> The weight (also know as ``length'' or ``cost'') of each edge in the graph. The `WeightMap` type must be a model of Readable Property Map. The key type for this property map must be the edge descriptor of the graph. The value type for the weight map must be Addable with the distance map's value type.
> Default: `get(edge_weight, g)`

UTIL: `predecessor_map(PredEdgeMap pred)`

> Use by the algorithm to store augmenting paths. The map must be a model of mutable Lvalue Property Map. The key type must be the graph's vertex descriptor type and the value type must be the graph's edge descriptor type.
> Default: an `iterator_property_map` created from a `std::vector` of edge descriptors of size `num_vertices(g)` and using the `i_map` for the index map.

UTIL: `distance_map(DistanceMap d_map)`

> The shortest path weight from the source vertex `s` to each vertex in the graph `g` is recorded in this property map. The shortest path weight is the sum of the edge weights along the shortest path. The type `DistanceMap` must be a model of Read/Write Property Map. The vertex descriptor type of the graph needs to be usable as the key type of the distance map. Default: `iterator_property_map` created from a `std::vector` of the `WeightMap`'s value type of size `num_vertices(g)` and using the `i_map` for the index map.

IN: `vertex_index_map(VertexIndexMap i_map)`

> Maps each vertex of the graph to a unique integer in the range `[0, num_vertices(g))`. This property map is only needed if the default for the distance or predecessor map is used. The vertex index map must be a model of Readable 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.

### Complexity

In the integer capacity and weight case, if C is the initial cost of the flow, then the complexity is O(C * |V| * |E|), where O(|E|* |V|) is the complexity of the bellman ford shortest paths algorithm and C is upper bound on number of iteration. In many real world cases number of iterations is much smaller than C.

### Example

The program in `example/cycle_canceling_example.cpp`.

### See Also

`successive_shortest_path_nonnegative_weights()`
`find_flow_cost()`.

Copyright © 2013 | Piotr Wygocki, University of Warsaw (wygos at mimuw.edu.pl)