lemon/network_simplex.h
author hegyi
Tue, 08 Apr 2008 11:39:40 +0000
changeset 2602 1c7790d9e025
parent 2588 4d3bc1d04c1d
child 2619 30fb4d68b0e8
permissions -rw-r--r--
Rel.07 NEWS - 3. round
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2008
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 #ifndef LEMON_NETWORK_SIMPLEX_H
    20 #define LEMON_NETWORK_SIMPLEX_H
    21 
    22 /// \ingroup min_cost_flow
    23 ///
    24 /// \file
    25 /// \brief Network simplex algorithm for finding a minimum cost flow.
    26 
    27 #include <vector>
    28 #include <limits>
    29 
    30 #include <lemon/graph_adaptor.h>
    31 #include <lemon/graph_utils.h>
    32 #include <lemon/smart_graph.h>
    33 #include <lemon/math.h>
    34 
    35 namespace lemon {
    36 
    37   /// \addtogroup min_cost_flow
    38   /// @{
    39 
    40   /// \brief Implementation of the network simplex algorithm for
    41   /// finding a minimum cost flow.
    42   ///
    43   /// \ref NetworkSimplex implements the network simplex algorithm for
    44   /// finding a minimum cost flow.
    45   ///
    46   /// \tparam Graph The directed graph type the algorithm runs on.
    47   /// \tparam LowerMap The type of the lower bound map.
    48   /// \tparam CapacityMap The type of the capacity (upper bound) map.
    49   /// \tparam CostMap The type of the cost (length) map.
    50   /// \tparam SupplyMap The type of the supply map.
    51   ///
    52   /// \warning
    53   /// - Edge capacities and costs should be \e non-negative \e integers.
    54   /// - Supply values should be \e signed \e integers.
    55   /// - The value types of the maps should be convertible to each other.
    56   /// - \c CostMap::Value must be signed type.
    57   ///
    58   /// \note \ref NetworkSimplex provides six different pivot rule
    59   /// implementations that significantly affect the efficiency of the
    60   /// algorithm.
    61   /// By default a combined pivot rule is used, which is the fastest
    62   /// implementation according to our benchmark tests.
    63   /// Another pivot rule can be selected using \ref run() function
    64   /// with the proper parameter.
    65   ///
    66   /// \author Peter Kovacs
    67 
    68   template < typename Graph,
    69              typename LowerMap = typename Graph::template EdgeMap<int>,
    70              typename CapacityMap = typename Graph::template EdgeMap<int>,
    71              typename CostMap = typename Graph::template EdgeMap<int>,
    72              typename SupplyMap = typename Graph::template NodeMap<int> >
    73   class NetworkSimplex
    74   {
    75     typedef typename CapacityMap::Value Capacity;
    76     typedef typename CostMap::Value Cost;
    77     typedef typename SupplyMap::Value Supply;
    78 
    79     typedef SmartGraph SGraph;
    80     GRAPH_TYPEDEFS(typename SGraph);
    81 
    82     typedef typename SGraph::template EdgeMap<Capacity> SCapacityMap;
    83     typedef typename SGraph::template EdgeMap<Cost> SCostMap;
    84     typedef typename SGraph::template NodeMap<Supply> SSupplyMap;
    85     typedef typename SGraph::template NodeMap<Cost> SPotentialMap;
    86 
    87     typedef typename SGraph::template NodeMap<int> IntNodeMap;
    88     typedef typename SGraph::template NodeMap<bool> BoolNodeMap;
    89     typedef typename SGraph::template NodeMap<Node> NodeNodeMap;
    90     typedef typename SGraph::template NodeMap<Edge> EdgeNodeMap;
    91     typedef typename SGraph::template EdgeMap<int> IntEdgeMap;
    92 
    93     typedef typename Graph::template NodeMap<Node> NodeRefMap;
    94     typedef typename Graph::template EdgeMap<Edge> EdgeRefMap;
    95 
    96   public:
    97 
    98     /// The type of the flow map.
    99     typedef typename Graph::template EdgeMap<Capacity> FlowMap;
   100     /// The type of the potential map.
   101     typedef typename Graph::template NodeMap<Cost> PotentialMap;
   102 
   103   public:
   104 
   105     /// Enum type to select the pivot rule used by \ref run().
   106     enum PivotRuleEnum {
   107       FIRST_ELIGIBLE_PIVOT,
   108       BEST_ELIGIBLE_PIVOT,
   109       BLOCK_SEARCH_PIVOT,
   110       LIMITED_SEARCH_PIVOT,
   111       CANDIDATE_LIST_PIVOT,
   112       COMBINED_PIVOT
   113     };
   114 
   115   private:
   116 
   117     /// \brief Map adaptor class for handling reduced edge costs.
   118     ///
   119     /// Map adaptor class for handling reduced edge costs.
   120     class ReducedCostMap : public MapBase<Edge, Cost>
   121     {
   122     private:
   123 
   124       const SGraph &_gr;
   125       const SCostMap &_cost_map;
   126       const SPotentialMap &_pot_map;
   127 
   128     public:
   129 
   130       ///\e
   131       ReducedCostMap( const SGraph &gr,
   132                       const SCostMap &cost_map,
   133                       const SPotentialMap &pot_map ) :
   134         _gr(gr), _cost_map(cost_map), _pot_map(pot_map) {}
   135 
   136       ///\e
   137       Cost operator[](const Edge &e) const {
   138         return _cost_map[e] + _pot_map[_gr.source(e)]
   139                            - _pot_map[_gr.target(e)];
   140       }
   141 
   142     }; //class ReducedCostMap
   143 
   144   private:
   145 
   146     /// \brief Implementation of the "First Eligible" pivot rule for the
   147     /// \ref NetworkSimplex "network simplex" algorithm.
   148     ///
   149     /// This class implements the "First Eligible" pivot rule
   150     /// for the \ref NetworkSimplex "network simplex" algorithm.
   151     class FirstEligiblePivotRule
   152     {
   153     private:
   154 
   155       NetworkSimplex &_ns;
   156       EdgeIt _next_edge;
   157 
   158     public:
   159 
   160       /// Constructor.
   161       FirstEligiblePivotRule(NetworkSimplex &ns) :
   162         _ns(ns), _next_edge(ns._graph) {}
   163 
   164       /// Finds the next entering edge.
   165       bool findEnteringEdge() {
   166         for (EdgeIt e = _next_edge; e != INVALID; ++e) {
   167           if (_ns._state[e] * _ns._red_cost[e] < 0) {
   168             _ns._in_edge = e;
   169             _next_edge = ++e;
   170             return true;
   171           }
   172         }
   173         for (EdgeIt e(_ns._graph); e != _next_edge; ++e) {
   174           if (_ns._state[e] * _ns._red_cost[e] < 0) {
   175             _ns._in_edge = e;
   176             _next_edge = ++e;
   177             return true;
   178           }
   179         }
   180         return false;
   181       }
   182     }; //class FirstEligiblePivotRule
   183 
   184     /// \brief Implementation of the "Best Eligible" pivot rule for the
   185     /// \ref NetworkSimplex "network simplex" algorithm.
   186     ///
   187     /// This class implements the "Best Eligible" pivot rule
   188     /// for the \ref NetworkSimplex "network simplex" algorithm.
   189     class BestEligiblePivotRule
   190     {
   191     private:
   192 
   193       NetworkSimplex &_ns;
   194 
   195     public:
   196 
   197       /// Constructor.
   198       BestEligiblePivotRule(NetworkSimplex &ns) : _ns(ns) {}
   199 
   200       /// Finds the next entering edge.
   201       bool findEnteringEdge() {
   202         Cost min = 0;
   203         for (EdgeIt e(_ns._graph); e != INVALID; ++e) {
   204           if (_ns._state[e] * _ns._red_cost[e] < min) {
   205             min = _ns._state[e] * _ns._red_cost[e];
   206             _ns._in_edge = e;
   207           }
   208         }
   209         return min < 0;
   210       }
   211     }; //class BestEligiblePivotRule
   212 
   213     /// \brief Implementation of the "Block Search" pivot rule for the
   214     /// \ref NetworkSimplex "network simplex" algorithm.
   215     ///
   216     /// This class implements the "Block Search" pivot rule
   217     /// for the \ref NetworkSimplex "network simplex" algorithm.
   218     class BlockSearchPivotRule
   219     {
   220     private:
   221 
   222       NetworkSimplex &_ns;
   223       EdgeIt _next_edge, _min_edge;
   224       int _block_size;
   225 
   226       static const int MIN_BLOCK_SIZE = 10;
   227 
   228     public:
   229 
   230       /// Constructor.
   231       BlockSearchPivotRule(NetworkSimplex &ns) :
   232         _ns(ns), _next_edge(ns._graph), _min_edge(ns._graph)
   233       {
   234         _block_size = 2 * int(sqrt(countEdges(_ns._graph)));
   235         if (_block_size < MIN_BLOCK_SIZE) _block_size = MIN_BLOCK_SIZE;
   236       }
   237 
   238       /// Finds the next entering edge.
   239       bool findEnteringEdge() {
   240         Cost curr, min = 0;
   241         int cnt = 0;
   242         for (EdgeIt e = _next_edge; e != INVALID; ++e) {
   243           if ((curr = _ns._state[e] * _ns._red_cost[e]) < min) {
   244             min = curr;
   245             _min_edge = e;
   246           }
   247           if (++cnt == _block_size) {
   248             if (min < 0) break;
   249             cnt = 0;
   250           }
   251         }
   252         if (min == 0) {
   253           for (EdgeIt e(_ns._graph); e != _next_edge; ++e) {
   254             if ((curr = _ns._state[e] * _ns._red_cost[e]) < min) {
   255               min = curr;
   256               _min_edge = e;
   257             }
   258             if (++cnt == _block_size) {
   259               if (min < 0) break;
   260               cnt = 0;
   261             }
   262           }
   263         }
   264         _ns._in_edge = _min_edge;
   265         _next_edge = ++_min_edge;
   266         return min < 0;
   267       }
   268     }; //class BlockSearchPivotRule
   269 
   270     /// \brief Implementation of the "Limited Search" pivot rule for the
   271     /// \ref NetworkSimplex "network simplex" algorithm.
   272     ///
   273     /// This class implements the "Limited Search" pivot rule
   274     /// for the \ref NetworkSimplex "network simplex" algorithm.
   275     class LimitedSearchPivotRule
   276     {
   277     private:
   278 
   279       NetworkSimplex &_ns;
   280       EdgeIt _next_edge, _min_edge;
   281       int _sample_size;
   282 
   283       static const int SAMPLE_SIZE_FACTOR = 15;
   284       static const int MIN_SAMPLE_SIZE = 10;
   285 
   286     public:
   287 
   288       /// Constructor.
   289       LimitedSearchPivotRule(NetworkSimplex &ns) :
   290         _ns(ns), _next_edge(ns._graph), _min_edge(ns._graph)
   291       {
   292         _sample_size = countEdges(_ns._graph) *
   293                        SAMPLE_SIZE_FACTOR / 10000;
   294         if (_sample_size < MIN_SAMPLE_SIZE)
   295           _sample_size = MIN_SAMPLE_SIZE;
   296       }
   297 
   298       /// Finds the next entering edge.
   299       bool findEnteringEdge() {
   300         Cost curr, min = 0;
   301         int cnt = 0;
   302         for (EdgeIt e = _next_edge; e != INVALID; ++e) {
   303           if ((curr = _ns._state[e] * _ns._red_cost[e]) < min) {
   304             min = curr;
   305             _min_edge = e;
   306           }
   307           if (curr < 0 && ++cnt == _sample_size) break;
   308         }
   309         if (min == 0) {
   310           for (EdgeIt e(_ns._graph); e != _next_edge; ++e) {
   311             if ((curr = _ns._state[e] * _ns._red_cost[e]) < min) {
   312               min = curr;
   313               _min_edge = e;
   314             }
   315             if (curr < 0 && ++cnt == _sample_size) break;
   316           }
   317         }
   318         _ns._in_edge = _min_edge;
   319         _next_edge = ++_min_edge;
   320         return min < 0;
   321       }
   322     }; //class LimitedSearchPivotRule
   323 
   324     /// \brief Implementation of the "Candidate List" pivot rule for the
   325     /// \ref NetworkSimplex "network simplex" algorithm.
   326     ///
   327     /// This class implements the "Candidate List" pivot rule
   328     /// for the \ref NetworkSimplex "network simplex" algorithm.
   329     class CandidateListPivotRule
   330     {
   331     private:
   332 
   333       NetworkSimplex &_ns;
   334 
   335       // The list of candidate edges.
   336       std::vector<Edge> _candidates;
   337       // The maximum length of the edge list.
   338       int _list_length;
   339       // The maximum number of minor iterations between two major
   340       // itarations.
   341       int _minor_limit;
   342 
   343       int _minor_count;
   344       EdgeIt _next_edge;
   345 
   346       static const int LIST_LENGTH_FACTOR = 20;
   347       static const int MINOR_LIMIT_FACTOR = 10;
   348       static const int MIN_LIST_LENGTH = 10;
   349       static const int MIN_MINOR_LIMIT = 2;
   350 
   351     public:
   352 
   353       /// Constructor.
   354       CandidateListPivotRule(NetworkSimplex &ns) :
   355         _ns(ns), _next_edge(ns._graph)
   356       {
   357         int edge_num = countEdges(_ns._graph);
   358         _minor_count = 0;
   359         _list_length = edge_num * LIST_LENGTH_FACTOR / 10000;
   360         if (_list_length < MIN_LIST_LENGTH)
   361           _list_length = MIN_LIST_LENGTH;
   362         _minor_limit = _list_length * MINOR_LIMIT_FACTOR / 100;
   363         if (_minor_limit < MIN_MINOR_LIMIT)
   364           _minor_limit = MIN_MINOR_LIMIT;
   365       }
   366 
   367       /// Finds the next entering edge.
   368       bool findEnteringEdge() {
   369         Cost min, curr;
   370         if (_minor_count < _minor_limit && _candidates.size() > 0) {
   371           // Minor iteration
   372           ++_minor_count;
   373           Edge e;
   374           min = 0;
   375           for (int i = 0; i < int(_candidates.size()); ++i) {
   376             e = _candidates[i];
   377             if ((curr = _ns._state[e] * _ns._red_cost[e]) < min) {
   378               min = curr;
   379               _ns._in_edge = e;
   380             }
   381           }
   382           if (min < 0) return true;
   383         }
   384 
   385         // Major iteration
   386         _candidates.clear();
   387         EdgeIt e = _next_edge;
   388         min = 0;
   389         for ( ; e != INVALID; ++e) {
   390           if ((curr = _ns._state[e] * _ns._red_cost[e]) < 0) {
   391             _candidates.push_back(e);
   392             if (curr < min) {
   393               min = curr;
   394               _ns._in_edge = e;
   395             }
   396             if (int(_candidates.size()) == _list_length) break;
   397           }
   398         }
   399         if (int(_candidates.size()) < _list_length) {
   400           for (e = EdgeIt(_ns._graph); e != _next_edge; ++e) {
   401             if ((curr = _ns._state[e] * _ns._red_cost[e]) < 0) {
   402               _candidates.push_back(e);
   403               if (curr < min) {
   404                 min = curr;
   405                 _ns._in_edge = e;
   406               }
   407               if (int(_candidates.size()) == _list_length) break;
   408             }
   409           }
   410         }
   411         if (_candidates.size() == 0) return false;
   412         _minor_count = 1;
   413         _next_edge = ++e;
   414         return true;
   415       }
   416     }; //class CandidateListPivotRule
   417 
   418   private:
   419 
   420     // State constants for edges
   421     enum EdgeStateEnum {
   422       STATE_UPPER = -1,
   423       STATE_TREE  =  0,
   424       STATE_LOWER =  1
   425     };
   426 
   427     // Constant for the combined pivot rule.
   428     static const int COMBINED_PIVOT_MAX_DEG = 5;
   429 
   430   private:
   431 
   432     // The directed graph the algorithm runs on
   433     SGraph _graph;
   434     // The original graph
   435     const Graph &_graph_ref;
   436     // The original lower bound map
   437     const LowerMap *_lower;
   438     // The capacity map
   439     SCapacityMap _capacity;
   440     // The cost map
   441     SCostMap _cost;
   442     // The supply map
   443     SSupplyMap _supply;
   444     bool _valid_supply;
   445 
   446     // Edge map of the current flow
   447     SCapacityMap _flow;
   448     // Node map of the current potentials
   449     SPotentialMap _potential;
   450 
   451     // The depth node map of the spanning tree structure
   452     IntNodeMap _depth;
   453     // The parent node map of the spanning tree structure
   454     NodeNodeMap _parent;
   455     // The pred_edge node map of the spanning tree structure
   456     EdgeNodeMap _pred_edge;
   457     // The thread node map of the spanning tree structure
   458     NodeNodeMap _thread;
   459     // The forward node map of the spanning tree structure
   460     BoolNodeMap _forward;
   461     // The state edge map
   462     IntEdgeMap _state;
   463     // The root node of the starting spanning tree
   464     Node _root;
   465 
   466     // The reduced cost map
   467     ReducedCostMap _red_cost;
   468 
   469     // Members for handling the original graph
   470     FlowMap *_flow_result;
   471     PotentialMap *_potential_result;
   472     bool _local_flow;
   473     bool _local_potential;
   474     NodeRefMap _node_ref;
   475     EdgeRefMap _edge_ref;
   476 
   477     // The entering edge of the current pivot iteration.
   478     Edge _in_edge;
   479 
   480     // Temporary nodes used in the current pivot iteration.
   481     Node join, u_in, v_in, u_out, v_out;
   482     Node right, first, second, last;
   483     Node stem, par_stem, new_stem;
   484     // The maximum augment amount along the found cycle in the current
   485     // pivot iteration.
   486     Capacity delta;
   487 
   488   public :
   489 
   490     /// \brief General constructor (with lower bounds).
   491     ///
   492     /// General constructor (with lower bounds).
   493     ///
   494     /// \param graph The directed graph the algorithm runs on.
   495     /// \param lower The lower bounds of the edges.
   496     /// \param capacity The capacities (upper bounds) of the edges.
   497     /// \param cost The cost (length) values of the edges.
   498     /// \param supply The supply values of the nodes (signed).
   499     NetworkSimplex( const Graph &graph,
   500                     const LowerMap &lower,
   501                     const CapacityMap &capacity,
   502                     const CostMap &cost,
   503                     const SupplyMap &supply ) :
   504       _graph(), _graph_ref(graph), _lower(&lower), _capacity(_graph),
   505       _cost(_graph), _supply(_graph), _flow(_graph),
   506       _potential(_graph), _depth(_graph), _parent(_graph),
   507       _pred_edge(_graph), _thread(_graph), _forward(_graph),
   508       _state(_graph), _red_cost(_graph, _cost, _potential),
   509       _flow_result(0), _potential_result(0),
   510       _local_flow(false), _local_potential(false),
   511       _node_ref(graph), _edge_ref(graph)
   512     {
   513       // Checking the sum of supply values
   514       Supply sum = 0;
   515       for (typename Graph::NodeIt n(_graph_ref); n != INVALID; ++n)
   516         sum += supply[n];
   517       if (!(_valid_supply = sum == 0)) return;
   518 
   519       // Copying _graph_ref to _graph
   520       _graph.reserveNode(countNodes(_graph_ref) + 1);
   521       _graph.reserveEdge(countEdges(_graph_ref) + countNodes(_graph_ref));
   522       copyGraph(_graph, _graph_ref)
   523         .edgeMap(_cost, cost)
   524         .nodeRef(_node_ref)
   525         .edgeRef(_edge_ref)
   526         .run();
   527 
   528       // Removing non-zero lower bounds
   529       for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e) {
   530         _capacity[_edge_ref[e]] = capacity[e] - lower[e];
   531       }
   532       for (typename Graph::NodeIt n(_graph_ref); n != INVALID; ++n) {
   533         Supply s = supply[n];
   534         for (typename Graph::InEdgeIt e(_graph_ref, n); e != INVALID; ++e)
   535           s += lower[e];
   536         for (typename Graph::OutEdgeIt e(_graph_ref, n); e != INVALID; ++e)
   537           s -= lower[e];
   538         _supply[_node_ref[n]] = s;
   539       }
   540     }
   541 
   542     /// \brief General constructor (without lower bounds).
   543     ///
   544     /// General constructor (without lower bounds).
   545     ///
   546     /// \param graph The directed graph the algorithm runs on.
   547     /// \param capacity The capacities (upper bounds) of the edges.
   548     /// \param cost The cost (length) values of the edges.
   549     /// \param supply The supply values of the nodes (signed).
   550     NetworkSimplex( const Graph &graph,
   551                     const CapacityMap &capacity,
   552                     const CostMap &cost,
   553                     const SupplyMap &supply ) :
   554       _graph(), _graph_ref(graph), _lower(NULL), _capacity(_graph),
   555       _cost(_graph), _supply(_graph), _flow(_graph),
   556       _potential(_graph), _depth(_graph), _parent(_graph),
   557       _pred_edge(_graph), _thread(_graph), _forward(_graph),
   558       _state(_graph), _red_cost(_graph, _cost, _potential),
   559       _flow_result(0), _potential_result(0),
   560       _local_flow(false), _local_potential(false),
   561       _node_ref(graph), _edge_ref(graph)
   562     {
   563       // Checking the sum of supply values
   564       Supply sum = 0;
   565       for (typename Graph::NodeIt n(_graph_ref); n != INVALID; ++n)
   566         sum += supply[n];
   567       if (!(_valid_supply = sum == 0)) return;
   568 
   569       // Copying _graph_ref to graph
   570       copyGraph(_graph, _graph_ref)
   571         .edgeMap(_capacity, capacity)
   572         .edgeMap(_cost, cost)
   573         .nodeMap(_supply, supply)
   574         .nodeRef(_node_ref)
   575         .edgeRef(_edge_ref)
   576         .run();
   577     }
   578 
   579     /// \brief Simple constructor (with lower bounds).
   580     ///
   581     /// Simple constructor (with lower bounds).
   582     ///
   583     /// \param graph The directed graph the algorithm runs on.
   584     /// \param lower The lower bounds of the edges.
   585     /// \param capacity The capacities (upper bounds) of the edges.
   586     /// \param cost The cost (length) values of the edges.
   587     /// \param s The source node.
   588     /// \param t The target node.
   589     /// \param flow_value The required amount of flow from node \c s
   590     /// to node \c t (i.e. the supply of \c s and the demand of \c t).
   591     NetworkSimplex( const Graph &graph,
   592                     const LowerMap &lower,
   593                     const CapacityMap &capacity,
   594                     const CostMap &cost,
   595                     typename Graph::Node s,
   596                     typename Graph::Node t,
   597                     typename SupplyMap::Value flow_value ) :
   598       _graph(), _graph_ref(graph), _lower(&lower), _capacity(_graph),
   599       _cost(_graph), _supply(_graph), _flow(_graph),
   600       _potential(_graph), _depth(_graph), _parent(_graph),
   601       _pred_edge(_graph), _thread(_graph), _forward(_graph),
   602       _state(_graph), _red_cost(_graph, _cost, _potential),
   603       _flow_result(0), _potential_result(0),
   604       _local_flow(false), _local_potential(false),
   605       _node_ref(graph), _edge_ref(graph)
   606     {
   607       // Copying _graph_ref to graph
   608       copyGraph(_graph, _graph_ref)
   609         .edgeMap(_cost, cost)
   610         .nodeRef(_node_ref)
   611         .edgeRef(_edge_ref)
   612         .run();
   613 
   614       // Removing non-zero lower bounds
   615       for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e) {
   616         _capacity[_edge_ref[e]] = capacity[e] - lower[e];
   617       }
   618       for (typename Graph::NodeIt n(_graph_ref); n != INVALID; ++n) {
   619         Supply sum = 0;
   620         if (n == s) sum =  flow_value;
   621         if (n == t) sum = -flow_value;
   622         for (typename Graph::InEdgeIt e(_graph_ref, n); e != INVALID; ++e)
   623           sum += lower[e];
   624         for (typename Graph::OutEdgeIt e(_graph_ref, n); e != INVALID; ++e)
   625           sum -= lower[e];
   626         _supply[_node_ref[n]] = sum;
   627       }
   628       _valid_supply = true;
   629     }
   630 
   631     /// \brief Simple constructor (without lower bounds).
   632     ///
   633     /// Simple constructor (without lower bounds).
   634     ///
   635     /// \param graph The directed graph the algorithm runs on.
   636     /// \param capacity The capacities (upper bounds) of the edges.
   637     /// \param cost The cost (length) values of the edges.
   638     /// \param s The source node.
   639     /// \param t The target node.
   640     /// \param flow_value The required amount of flow from node \c s
   641     /// to node \c t (i.e. the supply of \c s and the demand of \c t).
   642     NetworkSimplex( const Graph &graph,
   643                     const CapacityMap &capacity,
   644                     const CostMap &cost,
   645                     typename Graph::Node s,
   646                     typename Graph::Node t,
   647                     typename SupplyMap::Value flow_value ) :
   648       _graph(), _graph_ref(graph), _lower(NULL), _capacity(_graph),
   649       _cost(_graph), _supply(_graph, 0), _flow(_graph),
   650       _potential(_graph), _depth(_graph), _parent(_graph),
   651       _pred_edge(_graph), _thread(_graph), _forward(_graph),
   652       _state(_graph), _red_cost(_graph, _cost, _potential),
   653       _flow_result(0), _potential_result(0),
   654       _local_flow(false), _local_potential(false),
   655       _node_ref(graph), _edge_ref(graph)
   656     {
   657       // Copying _graph_ref to graph
   658       copyGraph(_graph, _graph_ref)
   659         .edgeMap(_capacity, capacity)
   660         .edgeMap(_cost, cost)
   661         .nodeRef(_node_ref)
   662         .edgeRef(_edge_ref)
   663         .run();
   664       _supply[_node_ref[s]] =  flow_value;
   665       _supply[_node_ref[t]] = -flow_value;
   666       _valid_supply = true;
   667     }
   668 
   669     /// Destructor.
   670     ~NetworkSimplex() {
   671       if (_local_flow) delete _flow_result;
   672       if (_local_potential) delete _potential_result;
   673     }
   674 
   675     /// \brief Sets the flow map.
   676     ///
   677     /// Sets the flow map.
   678     ///
   679     /// \return \c (*this)
   680     NetworkSimplex& flowMap(FlowMap &map) {
   681       if (_local_flow) {
   682         delete _flow_result;
   683         _local_flow = false;
   684       }
   685       _flow_result = &map;
   686       return *this;
   687     }
   688 
   689     /// \brief Sets the potential map.
   690     ///
   691     /// Sets the potential map.
   692     ///
   693     /// \return \c (*this)
   694     NetworkSimplex& potentialMap(PotentialMap &map) {
   695       if (_local_potential) {
   696         delete _potential_result;
   697         _local_potential = false;
   698       }
   699       _potential_result = &map;
   700       return *this;
   701     }
   702 
   703     /// \name Execution control
   704     /// The only way to execute the algorithm is to call the run()
   705     /// function.
   706 
   707     /// @{
   708 
   709     /// \brief Runs the algorithm.
   710     ///
   711     /// Runs the algorithm.
   712     ///
   713     /// \param pivot_rule The pivot rule that is used during the
   714     /// algorithm.
   715     ///
   716     /// The available pivot rules:
   717     ///
   718     /// - FIRST_ELIGIBLE_PIVOT The next eligible edge is selected in
   719     /// a wraparound fashion in every iteration
   720     /// (\ref FirstEligiblePivotRule).
   721     ///
   722     /// - BEST_ELIGIBLE_PIVOT The best eligible edge is selected in
   723     /// every iteration (\ref BestEligiblePivotRule).
   724     ///
   725     /// - BLOCK_SEARCH_PIVOT A specified number of edges are examined in
   726     /// every iteration in a wraparound fashion and the best eligible
   727     /// edge is selected from this block (\ref BlockSearchPivotRule).
   728     ///
   729     /// - LIMITED_SEARCH_PIVOT A specified number of eligible edges are
   730     /// examined in every iteration in a wraparound fashion and the best
   731     /// one is selected from them (\ref LimitedSearchPivotRule).
   732     ///
   733     /// - CANDIDATE_LIST_PIVOT In major iterations a candidate list is
   734     /// built from eligible edges and it is used for edge selection in
   735     /// the following minor iterations (\ref CandidateListPivotRule).
   736     ///
   737     /// - COMBINED_PIVOT This is a combined version of the two fastest
   738     /// pivot rules.
   739     /// For rather sparse graphs \ref LimitedSearchPivotRule
   740     /// "Limited Search" implementation is used, otherwise
   741     /// \ref BlockSearchPivotRule "Block Search" pivot rule is used.
   742     /// According to our benchmark tests this combined method is the
   743     /// most efficient.
   744     ///
   745     /// \return \c true if a feasible flow can be found.
   746     bool run(PivotRuleEnum pivot_rule = COMBINED_PIVOT) {
   747       return init() && start(pivot_rule);
   748     }
   749 
   750     /// @}
   751 
   752     /// \name Query Functions
   753     /// The result of the algorithm can be obtained using these
   754     /// functions.
   755     /// \n run() must be called before using them.
   756 
   757     /// @{
   758 
   759     /// \brief Returns a const reference to the edge map storing the
   760     /// found flow.
   761     ///
   762     /// Returns a const reference to the edge map storing the found flow.
   763     ///
   764     /// \pre \ref run() must be called before using this function.
   765     const FlowMap& flowMap() const {
   766       return *_flow_result;
   767     }
   768 
   769     /// \brief Returns a const reference to the node map storing the
   770     /// found potentials (the dual solution).
   771     ///
   772     /// Returns a const reference to the node map storing the found
   773     /// potentials (the dual solution).
   774     ///
   775     /// \pre \ref run() must be called before using this function.
   776     const PotentialMap& potentialMap() const {
   777       return *_potential_result;
   778     }
   779 
   780     /// \brief Returns the flow on the given edge.
   781     ///
   782     /// Returns the flow on the given edge.
   783     ///
   784     /// \pre \ref run() must be called before using this function.
   785     Capacity flow(const typename Graph::Edge& edge) const {
   786       return (*_flow_result)[edge];
   787     }
   788 
   789     /// \brief Returns the potential of the given node.
   790     ///
   791     /// Returns the potential of the given node.
   792     ///
   793     /// \pre \ref run() must be called before using this function.
   794     Cost potential(const typename Graph::Node& node) const {
   795       return (*_potential_result)[node];
   796     }
   797 
   798     /// \brief Returns the total cost of the found flow.
   799     ///
   800     /// Returns the total cost of the found flow. The complexity of the
   801     /// function is \f$ O(e) \f$.
   802     ///
   803     /// \pre \ref run() must be called before using this function.
   804     Cost totalCost() const {
   805       Cost c = 0;
   806       for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e)
   807         c += (*_flow_result)[e] * _cost[_edge_ref[e]];
   808       return c;
   809     }
   810 
   811     /// @}
   812 
   813   private:
   814 
   815     /// \brief Extends the underlaying graph and initializes all the
   816     /// node and edge maps.
   817     bool init() {
   818       if (!_valid_supply) return false;
   819 
   820       // Initializing result maps
   821       if (!_flow_result) {
   822         _flow_result = new FlowMap(_graph_ref);
   823         _local_flow = true;
   824       }
   825       if (!_potential_result) {
   826         _potential_result = new PotentialMap(_graph_ref);
   827         _local_potential = true;
   828       }
   829 
   830       // Initializing state and flow maps
   831       for (EdgeIt e(_graph); e != INVALID; ++e) {
   832         _flow[e] = 0;
   833         _state[e] = STATE_LOWER;
   834       }
   835 
   836       // Adding an artificial root node to the graph
   837       _root = _graph.addNode();
   838       _parent[_root] = INVALID;
   839       _pred_edge[_root] = INVALID;
   840       _depth[_root] = 0;
   841       _supply[_root] = 0;
   842       _potential[_root] = 0;
   843 
   844       // Adding artificial edges to the graph and initializing the node
   845       // maps of the spanning tree data structure
   846       Node last = _root;
   847       Edge e;
   848       Cost max_cost = std::numeric_limits<Cost>::max() / 4;
   849       for (NodeIt u(_graph); u != INVALID; ++u) {
   850         if (u == _root) continue;
   851         _thread[last] = u;
   852         last = u;
   853         _parent[u] = _root;
   854         _depth[u] = 1;
   855         if (_supply[u] >= 0) {
   856           e = _graph.addEdge(u, _root);
   857           _flow[e] = _supply[u];
   858           _forward[u] = true;
   859           _potential[u] = -max_cost;
   860         } else {
   861           e = _graph.addEdge(_root, u);
   862           _flow[e] = -_supply[u];
   863           _forward[u] = false;
   864           _potential[u] = max_cost;
   865         }
   866         _cost[e] = max_cost;
   867         _capacity[e] = std::numeric_limits<Capacity>::max();
   868         _state[e] = STATE_TREE;
   869         _pred_edge[u] = e;
   870       }
   871       _thread[last] = _root;
   872 
   873       return true;
   874     }
   875 
   876     /// Finds the join node.
   877     Node findJoinNode() {
   878       Node u = _graph.source(_in_edge);
   879       Node v = _graph.target(_in_edge);
   880       while (u != v) {
   881         if (_depth[u] == _depth[v]) {
   882           u = _parent[u];
   883           v = _parent[v];
   884         }
   885         else if (_depth[u] > _depth[v]) u = _parent[u];
   886         else v = _parent[v];
   887       }
   888       return u;
   889     }
   890 
   891     /// \brief Finds the leaving edge of the cycle. Returns \c true if
   892     /// the leaving edge is not the same as the entering edge.
   893     bool findLeavingEdge() {
   894       // Initializing first and second nodes according to the direction
   895       // of the cycle
   896       if (_state[_in_edge] == STATE_LOWER) {
   897         first  = _graph.source(_in_edge);
   898         second = _graph.target(_in_edge);
   899       } else {
   900         first  = _graph.target(_in_edge);
   901         second = _graph.source(_in_edge);
   902       }
   903       delta = _capacity[_in_edge];
   904       bool result = false;
   905       Capacity d;
   906       Edge e;
   907 
   908       // Searching the cycle along the path form the first node to the
   909       // root node
   910       for (Node u = first; u != join; u = _parent[u]) {
   911         e = _pred_edge[u];
   912         d = _forward[u] ? _flow[e] : _capacity[e] - _flow[e];
   913         if (d < delta) {
   914           delta = d;
   915           u_out = u;
   916           u_in = first;
   917           v_in = second;
   918           result = true;
   919         }
   920       }
   921       // Searching the cycle along the path form the second node to the
   922       // root node
   923       for (Node u = second; u != join; u = _parent[u]) {
   924         e = _pred_edge[u];
   925         d = _forward[u] ? _capacity[e] - _flow[e] : _flow[e];
   926         if (d <= delta) {
   927           delta = d;
   928           u_out = u;
   929           u_in = second;
   930           v_in = first;
   931           result = true;
   932         }
   933       }
   934       return result;
   935     }
   936 
   937     /// Changes \c flow and \c state edge maps.
   938     void changeFlows(bool change) {
   939       // Augmenting along the cycle
   940       if (delta > 0) {
   941         Capacity val = _state[_in_edge] * delta;
   942         _flow[_in_edge] += val;
   943         for (Node u = _graph.source(_in_edge); u != join; u = _parent[u]) {
   944           _flow[_pred_edge[u]] += _forward[u] ? -val : val;
   945         }
   946         for (Node u = _graph.target(_in_edge); u != join; u = _parent[u]) {
   947           _flow[_pred_edge[u]] += _forward[u] ? val : -val;
   948         }
   949       }
   950       // Updating the state of the entering and leaving edges
   951       if (change) {
   952         _state[_in_edge] = STATE_TREE;
   953         _state[_pred_edge[u_out]] =
   954           (_flow[_pred_edge[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
   955       } else {
   956         _state[_in_edge] = -_state[_in_edge];
   957       }
   958     }
   959 
   960     /// Updates \c thread and \c parent node maps.
   961     void updateThreadParent() {
   962       Node u;
   963       v_out = _parent[u_out];
   964 
   965       // Handling the case when join and v_out coincide
   966       bool par_first = false;
   967       if (join == v_out) {
   968         for (u = join; u != u_in && u != v_in; u = _thread[u]) ;
   969         if (u == v_in) {
   970           par_first = true;
   971           while (_thread[u] != u_out) u = _thread[u];
   972           first = u;
   973         }
   974       }
   975 
   976       // Finding the last successor of u_in (u) and the node after it
   977       // (right) according to the thread index
   978       for (u = u_in; _depth[_thread[u]] > _depth[u_in]; u = _thread[u]) ;
   979       right = _thread[u];
   980       if (_thread[v_in] == u_out) {
   981         for (last = u; _depth[last] > _depth[u_out]; last = _thread[last]) ;
   982         if (last == u_out) last = _thread[last];
   983       }
   984       else last = _thread[v_in];
   985 
   986       // Updating stem nodes
   987       _thread[v_in] = stem = u_in;
   988       par_stem = v_in;
   989       while (stem != u_out) {
   990         _thread[u] = new_stem = _parent[stem];
   991 
   992         // Finding the node just before the stem node (u) according to
   993         // the original thread index
   994         for (u = new_stem; _thread[u] != stem; u = _thread[u]) ;
   995         _thread[u] = right;
   996 
   997         // Changing the parent node of stem and shifting stem and
   998         // par_stem nodes
   999         _parent[stem] = par_stem;
  1000         par_stem = stem;
  1001         stem = new_stem;
  1002 
  1003         // Finding the last successor of stem (u) and the node after it
  1004         // (right) according to the thread index
  1005         for (u = stem; _depth[_thread[u]] > _depth[stem]; u = _thread[u]) ;
  1006         right = _thread[u];
  1007       }
  1008       _parent[u_out] = par_stem;
  1009       _thread[u] = last;
  1010 
  1011       if (join == v_out && par_first) {
  1012         if (first != v_in) _thread[first] = right;
  1013       } else {
  1014         for (u = v_out; _thread[u] != u_out; u = _thread[u]) ;
  1015         _thread[u] = right;
  1016       }
  1017     }
  1018 
  1019     /// Updates \c pred_edge and \c forward node maps.
  1020     void updatePredEdge() {
  1021       Node u = u_out, v;
  1022       while (u != u_in) {
  1023         v = _parent[u];
  1024         _pred_edge[u] = _pred_edge[v];
  1025         _forward[u] = !_forward[v];
  1026         u = v;
  1027       }
  1028       _pred_edge[u_in] = _in_edge;
  1029       _forward[u_in] = (u_in == _graph.source(_in_edge));
  1030     }
  1031 
  1032     /// Updates \c depth and \c potential node maps.
  1033     void updateDepthPotential() {
  1034       _depth[u_in] = _depth[v_in] + 1;
  1035       _potential[u_in] = _forward[u_in] ?
  1036         _potential[v_in] - _cost[_pred_edge[u_in]] :
  1037         _potential[v_in] + _cost[_pred_edge[u_in]];
  1038 
  1039       Node u = _thread[u_in], v;
  1040       while (true) {
  1041         v = _parent[u];
  1042         if (v == INVALID) break;
  1043         _depth[u] = _depth[v] + 1;
  1044         _potential[u] = _forward[u] ?
  1045           _potential[v] - _cost[_pred_edge[u]] :
  1046           _potential[v] + _cost[_pred_edge[u]];
  1047         if (_depth[u] <= _depth[v_in]) break;
  1048         u = _thread[u];
  1049       }
  1050     }
  1051 
  1052     /// Executes the algorithm.
  1053     bool start(PivotRuleEnum pivot_rule) {
  1054       switch (pivot_rule) {
  1055         case FIRST_ELIGIBLE_PIVOT:
  1056           return start<FirstEligiblePivotRule>();
  1057         case BEST_ELIGIBLE_PIVOT:
  1058           return start<BestEligiblePivotRule>();
  1059         case BLOCK_SEARCH_PIVOT:
  1060           return start<BlockSearchPivotRule>();
  1061         case LIMITED_SEARCH_PIVOT:
  1062           return start<LimitedSearchPivotRule>();
  1063         case CANDIDATE_LIST_PIVOT:
  1064           return start<CandidateListPivotRule>();
  1065         case COMBINED_PIVOT:
  1066           if ( countEdges(_graph) / countNodes(_graph) <=
  1067                COMBINED_PIVOT_MAX_DEG )
  1068             return start<LimitedSearchPivotRule>();
  1069           else
  1070             return start<BlockSearchPivotRule>();
  1071       }
  1072       return false;
  1073     }
  1074 
  1075     template<class PivotRuleImplementation>
  1076     bool start() {
  1077       PivotRuleImplementation pivot(*this);
  1078 
  1079       // Executing the network simplex algorithm
  1080       while (pivot.findEnteringEdge()) {
  1081         join = findJoinNode();
  1082         bool change = findLeavingEdge();
  1083         changeFlows(change);
  1084         if (change) {
  1085           updateThreadParent();
  1086           updatePredEdge();
  1087           updateDepthPotential();
  1088         }
  1089       }
  1090 
  1091       // Checking if the flow amount equals zero on all the artificial
  1092       // edges
  1093       for (InEdgeIt e(_graph, _root); e != INVALID; ++e)
  1094         if (_flow[e] > 0) return false;
  1095       for (OutEdgeIt e(_graph, _root); e != INVALID; ++e)
  1096         if (_flow[e] > 0) return false;
  1097 
  1098       // Copying flow values to _flow_result
  1099       if (_lower) {
  1100         for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e)
  1101           (*_flow_result)[e] = (*_lower)[e] + _flow[_edge_ref[e]];
  1102       } else {
  1103         for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e)
  1104           (*_flow_result)[e] = _flow[_edge_ref[e]];
  1105       }
  1106       // Copying potential values to _potential_result
  1107       for (typename Graph::NodeIt n(_graph_ref); n != INVALID; ++n)
  1108         (*_potential_result)[n] = _potential[_node_ref[n]];
  1109 
  1110       return true;
  1111     }
  1112 
  1113   }; //class NetworkSimplex
  1114 
  1115   ///@}
  1116 
  1117 } //namespace lemon
  1118 
  1119 #endif //LEMON_NETWORK_SIMPLEX_H