lemon/network_simplex.h
author convert-repo
Thu, 04 Mar 2010 19:34:55 +0000
changeset 2659 611ced85018b
parent 2635 23570e368afa
permissions -rw-r--r--
update tags
     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 #include <algorithm>
    30 
    31 #include <lemon/graph_utils.h>
    32 #include <lemon/math.h>
    33 
    34 namespace lemon {
    35 
    36   /// \addtogroup min_cost_flow
    37   /// @{
    38 
    39   /// \brief Implementation of the primal network simplex algorithm
    40   /// for finding a minimum cost flow.
    41   ///
    42   /// \ref NetworkSimplex implements the primal network simplex algorithm
    43   /// for finding a minimum cost flow.
    44   ///
    45   /// \tparam Graph The directed graph type the algorithm runs on.
    46   /// \tparam LowerMap The type of the lower bound map.
    47   /// \tparam CapacityMap The type of the capacity (upper bound) map.
    48   /// \tparam CostMap The type of the cost (length) map.
    49   /// \tparam SupplyMap The type of the supply map.
    50   ///
    51   /// \warning
    52   /// - Edge capacities and costs should be \e non-negative \e integers.
    53   /// - Supply values should be \e signed \e integers.
    54   /// - The value types of the maps should be convertible to each other.
    55   /// - \c CostMap::Value must be signed type.
    56   ///
    57   /// \note \ref NetworkSimplex provides five different pivot rule
    58   /// implementations that significantly affect the efficiency of the
    59   /// algorithm.
    60   /// By default "Block Search" pivot rule is used, which proved to be
    61   /// by far the most efficient according to our benchmark tests.
    62   /// However another pivot rule can be selected using \ref run()
    63   /// function with the proper parameter.
    64   ///
    65   /// \author Peter Kovacs
    66   template < typename Graph,
    67              typename LowerMap = typename Graph::template EdgeMap<int>,
    68              typename CapacityMap = typename Graph::template EdgeMap<int>,
    69              typename CostMap = typename Graph::template EdgeMap<int>,
    70              typename SupplyMap = typename Graph::template NodeMap<int> >
    71   class NetworkSimplex
    72   {
    73     GRAPH_TYPEDEFS(typename Graph);
    74 
    75     typedef typename CapacityMap::Value Capacity;
    76     typedef typename CostMap::Value Cost;
    77     typedef typename SupplyMap::Value Supply;
    78 
    79     typedef std::vector<Edge> EdgeVector;
    80     typedef std::vector<Node> NodeVector;
    81     typedef std::vector<int> IntVector;
    82     typedef std::vector<bool> BoolVector;
    83     typedef std::vector<Capacity> CapacityVector;
    84     typedef std::vector<Cost> CostVector;
    85     typedef std::vector<Supply> SupplyVector;
    86 
    87     typedef typename Graph::template NodeMap<int> IntNodeMap;
    88 
    89   public:
    90 
    91     /// The type of the flow map.
    92     typedef typename Graph::template EdgeMap<Capacity> FlowMap;
    93     /// The type of the potential map.
    94     typedef typename Graph::template NodeMap<Cost> PotentialMap;
    95 
    96   public:
    97 
    98     /// Enum type to select the pivot rule used by \ref run().
    99     enum PivotRuleEnum {
   100       FIRST_ELIGIBLE_PIVOT,
   101       BEST_ELIGIBLE_PIVOT,
   102       BLOCK_SEARCH_PIVOT,
   103       CANDIDATE_LIST_PIVOT,
   104       ALTERING_LIST_PIVOT
   105     };
   106 
   107   private:
   108 
   109     /// \brief Implementation of the "First Eligible" pivot rule for the
   110     /// \ref NetworkSimplex "network simplex" algorithm.
   111     ///
   112     /// This class implements the "First Eligible" pivot rule
   113     /// for the \ref NetworkSimplex "network simplex" algorithm.
   114     ///
   115     /// For more information see \ref NetworkSimplex::run().
   116     class FirstEligiblePivotRule
   117     {
   118     private:
   119 
   120       // References to the NetworkSimplex class
   121       const EdgeVector &_edge;
   122       const IntVector  &_source;
   123       const IntVector  &_target;
   124       const CostVector &_cost;
   125       const IntVector  &_state;
   126       const CostVector &_pi;
   127       int &_in_edge;
   128       int _edge_num;
   129 
   130       // Pivot rule data
   131       int _next_edge;
   132 
   133     public:
   134 
   135       /// Constructor
   136       FirstEligiblePivotRule(NetworkSimplex &ns) :
   137         _edge(ns._edge), _source(ns._source), _target(ns._target),
   138         _cost(ns._cost), _state(ns._state), _pi(ns._pi),
   139         _in_edge(ns._in_edge), _edge_num(ns._edge_num), _next_edge(0)
   140       {}
   141 
   142       /// Find next entering edge
   143       bool findEnteringEdge() {
   144         Cost c;
   145         for (int e = _next_edge; e < _edge_num; ++e) {
   146           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   147           if (c < 0) {
   148             _in_edge = e;
   149             _next_edge = e + 1;
   150             return true;
   151           }
   152         }
   153         for (int e = 0; e < _next_edge; ++e) {
   154           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   155           if (c < 0) {
   156             _in_edge = e;
   157             _next_edge = e + 1;
   158             return true;
   159           }
   160         }
   161         return false;
   162       }
   163 
   164     }; //class FirstEligiblePivotRule
   165 
   166 
   167     /// \brief Implementation of the "Best Eligible" pivot rule for the
   168     /// \ref NetworkSimplex "network simplex" algorithm.
   169     ///
   170     /// This class implements the "Best Eligible" pivot rule
   171     /// for the \ref NetworkSimplex "network simplex" algorithm.
   172     ///
   173     /// For more information see \ref NetworkSimplex::run().
   174     class BestEligiblePivotRule
   175     {
   176     private:
   177 
   178       // References to the NetworkSimplex class
   179       const EdgeVector &_edge;
   180       const IntVector  &_source;
   181       const IntVector  &_target;
   182       const CostVector &_cost;
   183       const IntVector  &_state;
   184       const CostVector &_pi;
   185       int &_in_edge;
   186       int _edge_num;
   187 
   188     public:
   189 
   190       /// Constructor
   191       BestEligiblePivotRule(NetworkSimplex &ns) :
   192         _edge(ns._edge), _source(ns._source), _target(ns._target),
   193         _cost(ns._cost), _state(ns._state), _pi(ns._pi),
   194         _in_edge(ns._in_edge), _edge_num(ns._edge_num)
   195       {}
   196 
   197       /// Find next entering edge
   198       bool findEnteringEdge() {
   199         Cost c, min = 0;
   200         for (int e = 0; e < _edge_num; ++e) {
   201           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   202           if (c < min) {
   203             min = c;
   204             _in_edge = e;
   205           }
   206         }
   207         return min < 0;
   208       }
   209 
   210     }; //class BestEligiblePivotRule
   211 
   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     ///
   219     /// For more information see \ref NetworkSimplex::run().
   220     class BlockSearchPivotRule
   221     {
   222     private:
   223 
   224       // References to the NetworkSimplex class
   225       const EdgeVector &_edge;
   226       const IntVector  &_source;
   227       const IntVector  &_target;
   228       const CostVector &_cost;
   229       const IntVector  &_state;
   230       const CostVector &_pi;
   231       int &_in_edge;
   232       int _edge_num;
   233 
   234       // Pivot rule data
   235       int _block_size;
   236       int _next_edge;
   237 
   238     public:
   239 
   240       /// Constructor
   241       BlockSearchPivotRule(NetworkSimplex &ns) :
   242         _edge(ns._edge), _source(ns._source), _target(ns._target),
   243         _cost(ns._cost), _state(ns._state), _pi(ns._pi),
   244         _in_edge(ns._in_edge), _edge_num(ns._edge_num), _next_edge(0)
   245       {
   246         // The main parameters of the pivot rule
   247         const double BLOCK_SIZE_FACTOR = 0.5;
   248         const int MIN_BLOCK_SIZE = 10;
   249 
   250         _block_size = std::max( int(BLOCK_SIZE_FACTOR * sqrt(_edge_num)),
   251                                 MIN_BLOCK_SIZE );
   252       }
   253 
   254       /// Find next entering edge
   255       bool findEnteringEdge() {
   256         Cost c, min = 0;
   257         int cnt = _block_size;
   258         int e;
   259         for (e = _next_edge; e < _edge_num; ++e) {
   260           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   261           if (c < min) {
   262             min = c;
   263             _in_edge = e;
   264           }
   265           if (--cnt == 0) {
   266             if (min < 0) goto search_end;
   267             cnt = _block_size;
   268           }
   269         }
   270         for (e = 0; e < _next_edge; ++e) {
   271           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   272           if (c < min) {
   273             min = c;
   274             _in_edge = e;
   275           }
   276           if (--cnt == 0) {
   277             if (min < 0) goto search_end;
   278             cnt = _block_size;
   279           }
   280         }
   281         if (min >= 0) return false;
   282 
   283       search_end:
   284         _next_edge = e;
   285         return true;
   286       }
   287 
   288     }; //class BlockSearchPivotRule
   289 
   290 
   291     /// \brief Implementation of the "Candidate List" pivot rule for the
   292     /// \ref NetworkSimplex "network simplex" algorithm.
   293     ///
   294     /// This class implements the "Candidate List" pivot rule
   295     /// for the \ref NetworkSimplex "network simplex" algorithm.
   296     ///
   297     /// For more information see \ref NetworkSimplex::run().
   298     class CandidateListPivotRule
   299     {
   300     private:
   301 
   302       // References to the NetworkSimplex class
   303       const EdgeVector &_edge;
   304       const IntVector  &_source;
   305       const IntVector  &_target;
   306       const CostVector &_cost;
   307       const IntVector  &_state;
   308       const CostVector &_pi;
   309       int &_in_edge;
   310       int _edge_num;
   311 
   312       // Pivot rule data
   313       IntVector _candidates;
   314       int _list_length, _minor_limit;
   315       int _curr_length, _minor_count;
   316       int _next_edge;
   317 
   318     public:
   319 
   320       /// Constructor
   321       CandidateListPivotRule(NetworkSimplex &ns) :
   322         _edge(ns._edge), _source(ns._source), _target(ns._target),
   323         _cost(ns._cost), _state(ns._state), _pi(ns._pi),
   324         _in_edge(ns._in_edge), _edge_num(ns._edge_num), _next_edge(0)
   325       {
   326         // The main parameters of the pivot rule
   327         const double LIST_LENGTH_FACTOR = 0.25;
   328         const int MIN_LIST_LENGTH = 10;
   329         const double MINOR_LIMIT_FACTOR = 0.1;
   330         const int MIN_MINOR_LIMIT = 3;
   331 
   332         _list_length = std::max( int(LIST_LENGTH_FACTOR * sqrt(_edge_num)),
   333                                  MIN_LIST_LENGTH );
   334         _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
   335                                  MIN_MINOR_LIMIT );
   336         _curr_length = _minor_count = 0;
   337         _candidates.resize(_list_length);
   338       }
   339 
   340       /// Find next entering edge
   341       bool findEnteringEdge() {
   342         Cost min, c;
   343         int e;
   344         if (_curr_length > 0 && _minor_count < _minor_limit) {
   345           // Minor iteration: select the best eligible edge from the
   346           // current candidate list
   347           ++_minor_count;
   348           min = 0;
   349           for (int i = 0; i < _curr_length; ++i) {
   350             e = _candidates[i];
   351             c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   352             if (c < min) {
   353               min = c;
   354               _in_edge = e;
   355             }
   356             else if (c >= 0) {
   357               _candidates[i--] = _candidates[--_curr_length];
   358             }
   359           }
   360           if (min < 0) return true;
   361         }
   362 
   363         // Major iteration: build a new candidate list
   364         min = 0;
   365         _curr_length = 0;
   366         for (e = _next_edge; e < _edge_num; ++e) {
   367           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   368           if (c < 0) {
   369             _candidates[_curr_length++] = e;
   370             if (c < min) {
   371               min = c;
   372               _in_edge = e;
   373             }
   374             if (_curr_length == _list_length) goto search_end;
   375           }
   376         }
   377         for (e = 0; e < _next_edge; ++e) {
   378           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   379           if (c < 0) {
   380             _candidates[_curr_length++] = e;
   381             if (c < min) {
   382               min = c;
   383               _in_edge = e;
   384             }
   385             if (_curr_length == _list_length) goto search_end;
   386           }
   387         }
   388         if (_curr_length == 0) return false;
   389       
   390       search_end:        
   391         _minor_count = 1;
   392         _next_edge = e;
   393         return true;
   394       }
   395 
   396     }; //class CandidateListPivotRule
   397 
   398 
   399     /// \brief Implementation of the "Altering Candidate List" pivot rule
   400     /// for the \ref NetworkSimplex "network simplex" algorithm.
   401     ///
   402     /// This class implements the "Altering Candidate List" pivot rule
   403     /// for the \ref NetworkSimplex "network simplex" algorithm.
   404     ///
   405     /// For more information see \ref NetworkSimplex::run().
   406     class AlteringListPivotRule
   407     {
   408     private:
   409 
   410       // References to the NetworkSimplex class
   411       const EdgeVector &_edge;
   412       const IntVector  &_source;
   413       const IntVector  &_target;
   414       const CostVector &_cost;
   415       const IntVector  &_state;
   416       const CostVector &_pi;
   417       int &_in_edge;
   418       int _edge_num;
   419 
   420       int _block_size, _head_length, _curr_length;
   421       int _next_edge;
   422       IntVector _candidates;
   423       CostVector _cand_cost;
   424 
   425       // Functor class to compare edges during sort of the candidate list
   426       class SortFunc
   427       {
   428       private:
   429         const CostVector &_map;
   430       public:
   431         SortFunc(const CostVector &map) : _map(map) {}
   432         bool operator()(int left, int right) {
   433           return _map[left] > _map[right];
   434         }
   435       };
   436 
   437       SortFunc _sort_func;
   438 
   439     public:
   440 
   441       /// Constructor
   442       AlteringListPivotRule(NetworkSimplex &ns) :
   443         _edge(ns._edge), _source(ns._source), _target(ns._target),
   444         _cost(ns._cost), _state(ns._state), _pi(ns._pi),
   445         _in_edge(ns._in_edge), _edge_num(ns._edge_num),
   446          _next_edge(0), _cand_cost(ns._edge_num),_sort_func(_cand_cost)
   447       {
   448         // The main parameters of the pivot rule
   449         const double BLOCK_SIZE_FACTOR = 1.0;
   450         const int MIN_BLOCK_SIZE = 10;
   451         const double HEAD_LENGTH_FACTOR = 0.1;
   452         const int MIN_HEAD_LENGTH = 3;
   453 
   454         _block_size = std::max( int(BLOCK_SIZE_FACTOR * sqrt(_edge_num)),
   455                                 MIN_BLOCK_SIZE );
   456         _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
   457                                  MIN_HEAD_LENGTH );
   458         _candidates.resize(_head_length + _block_size);
   459         _curr_length = 0;
   460       }
   461 
   462       /// Find next entering edge
   463       bool findEnteringEdge() {
   464         // Check the current candidate list
   465         int e;
   466         for (int i = 0; i < _curr_length; ++i) {
   467           e = _candidates[i];
   468           _cand_cost[e] = _state[e] * 
   469             (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   470           if (_cand_cost[e] >= 0) {
   471             _candidates[i--] = _candidates[--_curr_length];
   472           }
   473         }
   474 
   475         // Extend the list
   476         int cnt = _block_size;
   477         int limit = _head_length;
   478         
   479         for (e = _next_edge; e < _edge_num; ++e) {
   480           _cand_cost[e] = _state[e] *
   481             (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   482           if (_cand_cost[e] < 0) {
   483             _candidates[_curr_length++] = e;
   484           }
   485           if (--cnt == 0) {
   486             if (_curr_length > limit) goto search_end;
   487             limit = 0;
   488             cnt = _block_size;
   489           }
   490         }
   491         for (e = 0; e < _next_edge; ++e) {
   492           _cand_cost[e] = _state[e] *
   493             (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   494           if (_cand_cost[e] < 0) {
   495             _candidates[_curr_length++] = e;
   496           }
   497           if (--cnt == 0) {
   498             if (_curr_length > limit) goto search_end;
   499             limit = 0;
   500             cnt = _block_size;
   501           }
   502         }
   503         if (_curr_length == 0) return false;
   504         
   505       search_end:
   506 
   507         // Make heap of the candidate list (approximating a partial sort)
   508         make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
   509                    _sort_func );
   510 
   511         // Pop the first element of the heap
   512         _in_edge = _candidates[0];
   513         _next_edge = e;
   514         pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
   515                   _sort_func );
   516         _curr_length = std::min(_head_length, _curr_length - 1);
   517         return true;
   518       }
   519 
   520     }; //class AlteringListPivotRule
   521 
   522   private:
   523 
   524     // State constants for edges
   525     enum EdgeStateEnum {
   526       STATE_UPPER = -1,
   527       STATE_TREE  =  0,
   528       STATE_LOWER =  1
   529     };
   530 
   531   private:
   532 
   533     // The original graph
   534     const Graph &_orig_graph;
   535     // The original lower bound map
   536     const LowerMap *_orig_lower;
   537     // The original capacity map
   538     const CapacityMap &_orig_cap;
   539     // The original cost map
   540     const CostMap &_orig_cost;
   541     // The original supply map
   542     const SupplyMap *_orig_supply;
   543     // The source node (if no supply map was given)
   544     Node _orig_source;
   545     // The target node (if no supply map was given)
   546     Node _orig_target;
   547     // The flow value (if no supply map was given)
   548     Capacity _orig_flow_value;
   549 
   550     // The flow result map
   551     FlowMap *_flow_result;
   552     // The potential result map
   553     PotentialMap *_potential_result;
   554     // Indicate if the flow result map is local
   555     bool _local_flow;
   556     // Indicate if the potential result map is local
   557     bool _local_potential;
   558 
   559     // The edge references
   560     EdgeVector _edge;
   561     // The node references
   562     NodeVector _node;
   563     // The node ids
   564     IntNodeMap _node_id;
   565     // The source nodes of the edges
   566     IntVector _source;
   567     // The target nodess of the edges
   568     IntVector _target;
   569 
   570     // The (modified) capacity vector
   571     CapacityVector _cap;
   572     // The cost vector
   573     CostVector _cost;
   574     // The (modified) supply vector
   575     CostVector _supply;
   576     // The current flow vector
   577     CapacityVector _flow;
   578     // The current potential vector
   579     CostVector _pi;
   580 
   581     // The number of nodes in the original graph
   582     int _node_num;
   583     // The number of edges in the original graph
   584     int _edge_num;
   585 
   586     // The parent vector of the spanning tree structure
   587     IntVector _parent;
   588     // The pred_edge vector of the spanning tree structure
   589     IntVector _pred;
   590     // The thread vector of the spanning tree structure
   591     IntVector _thread;
   592 
   593     IntVector _rev_thread;
   594     IntVector _succ_num;
   595     IntVector _last_succ;
   596 
   597     IntVector _dirty_revs;
   598     
   599     // The forward vector of the spanning tree structure
   600     BoolVector _forward;
   601     // The state vector
   602     IntVector _state;
   603     // The root node
   604     int _root;
   605 
   606     // The entering edge of the current pivot iteration
   607     int _in_edge;
   608 
   609     // Temporary nodes used in the current pivot iteration
   610     int join, u_in, v_in, u_out, v_out;
   611     int right, first, second, last;
   612     int stem, par_stem, new_stem;
   613 
   614     // The maximum augment amount along the found cycle in the current
   615     // pivot iteration
   616     Capacity delta;
   617 
   618   public:
   619 
   620     /// \brief General constructor (with lower bounds).
   621     ///
   622     /// General constructor (with lower bounds).
   623     ///
   624     /// \param graph The directed graph the algorithm runs on.
   625     /// \param lower The lower bounds of the edges.
   626     /// \param capacity The capacities (upper bounds) of the edges.
   627     /// \param cost The cost (length) values of the edges.
   628     /// \param supply The supply values of the nodes (signed).
   629     NetworkSimplex( const Graph &graph,
   630                     const LowerMap &lower,
   631                     const CapacityMap &capacity,
   632                     const CostMap &cost,
   633                     const SupplyMap &supply ) :
   634       _orig_graph(graph), _orig_lower(&lower), _orig_cap(capacity),
   635       _orig_cost(cost), _orig_supply(&supply),
   636       _flow_result(NULL), _potential_result(NULL),
   637       _local_flow(false), _local_potential(false),
   638       _node_id(graph)
   639     {}
   640 
   641     /// \brief General constructor (without lower bounds).
   642     ///
   643     /// General constructor (without lower bounds).
   644     ///
   645     /// \param graph The directed graph the algorithm runs on.
   646     /// \param capacity The capacities (upper bounds) of the edges.
   647     /// \param cost The cost (length) values of the edges.
   648     /// \param supply The supply values of the nodes (signed).
   649     NetworkSimplex( const Graph &graph,
   650                     const CapacityMap &capacity,
   651                     const CostMap &cost,
   652                     const SupplyMap &supply ) :
   653       _orig_graph(graph), _orig_lower(NULL), _orig_cap(capacity),
   654       _orig_cost(cost), _orig_supply(&supply),
   655       _flow_result(NULL), _potential_result(NULL),
   656       _local_flow(false), _local_potential(false),
   657       _node_id(graph)
   658     {}
   659 
   660     /// \brief Simple constructor (with lower bounds).
   661     ///
   662     /// Simple constructor (with lower bounds).
   663     ///
   664     /// \param graph The directed graph the algorithm runs on.
   665     /// \param lower The lower bounds of the edges.
   666     /// \param capacity The capacities (upper bounds) of the edges.
   667     /// \param cost The cost (length) values of the edges.
   668     /// \param s The source node.
   669     /// \param t The target node.
   670     /// \param flow_value The required amount of flow from node \c s
   671     /// to node \c t (i.e. the supply of \c s and the demand of \c t).
   672     NetworkSimplex( const Graph &graph,
   673                     const LowerMap &lower,
   674                     const CapacityMap &capacity,
   675                     const CostMap &cost,
   676                     Node s, Node t,
   677                     Capacity flow_value ) :
   678       _orig_graph(graph), _orig_lower(&lower), _orig_cap(capacity),
   679       _orig_cost(cost), _orig_supply(NULL),
   680       _orig_source(s), _orig_target(t), _orig_flow_value(flow_value),
   681       _flow_result(NULL), _potential_result(NULL),
   682       _local_flow(false), _local_potential(false),
   683       _node_id(graph)
   684     {}
   685 
   686     /// \brief Simple constructor (without lower bounds).
   687     ///
   688     /// Simple constructor (without lower bounds).
   689     ///
   690     /// \param graph The directed graph the algorithm runs on.
   691     /// \param capacity The capacities (upper bounds) of the edges.
   692     /// \param cost The cost (length) values of the edges.
   693     /// \param s The source node.
   694     /// \param t The target node.
   695     /// \param flow_value The required amount of flow from node \c s
   696     /// to node \c t (i.e. the supply of \c s and the demand of \c t).
   697     NetworkSimplex( const Graph &graph,
   698                     const CapacityMap &capacity,
   699                     const CostMap &cost,
   700                     Node s, Node t,
   701                     Capacity flow_value ) :
   702       _orig_graph(graph), _orig_lower(NULL), _orig_cap(capacity),
   703       _orig_cost(cost), _orig_supply(NULL),
   704       _orig_source(s), _orig_target(t), _orig_flow_value(flow_value),
   705       _flow_result(NULL), _potential_result(NULL),
   706       _local_flow(false), _local_potential(false),
   707       _node_id(graph)
   708     {}
   709 
   710     /// Destructor.
   711     ~NetworkSimplex() {
   712       if (_local_flow) delete _flow_result;
   713       if (_local_potential) delete _potential_result;
   714     }
   715 
   716     /// \brief Set the flow map.
   717     ///
   718     /// Set the flow map.
   719     ///
   720     /// \return \c (*this)
   721     NetworkSimplex& flowMap(FlowMap &map) {
   722       if (_local_flow) {
   723         delete _flow_result;
   724         _local_flow = false;
   725       }
   726       _flow_result = &map;
   727       return *this;
   728     }
   729 
   730     /// \brief Set the potential map.
   731     ///
   732     /// Set the potential map.
   733     ///
   734     /// \return \c (*this)
   735     NetworkSimplex& potentialMap(PotentialMap &map) {
   736       if (_local_potential) {
   737         delete _potential_result;
   738         _local_potential = false;
   739       }
   740       _potential_result = &map;
   741       return *this;
   742     }
   743 
   744     /// \name Execution control
   745 
   746     /// @{
   747 
   748     /// \brief Runs the algorithm.
   749     ///
   750     /// Runs the algorithm.
   751     ///
   752     /// \param pivot_rule The pivot rule that is used during the
   753     /// algorithm.
   754     ///
   755     /// The available pivot rules:
   756     ///
   757     /// - FIRST_ELIGIBLE_PIVOT The next eligible edge is selected in
   758     /// a wraparound fashion in every iteration
   759     /// (\ref FirstEligiblePivotRule).
   760     ///
   761     /// - BEST_ELIGIBLE_PIVOT The best eligible edge is selected in
   762     /// every iteration (\ref BestEligiblePivotRule).
   763     ///
   764     /// - BLOCK_SEARCH_PIVOT A specified number of edges are examined in
   765     /// every iteration in a wraparound fashion and the best eligible
   766     /// edge is selected from this block (\ref BlockSearchPivotRule).
   767     ///
   768     /// - CANDIDATE_LIST_PIVOT In a major iteration a candidate list is
   769     /// built from eligible edges in a wraparound fashion and in the
   770     /// following minor iterations the best eligible edge is selected
   771     /// from this list (\ref CandidateListPivotRule).
   772     ///
   773     /// - ALTERING_LIST_PIVOT It is a modified version of the
   774     /// "Candidate List" pivot rule. It keeps only the several best
   775     /// eligible edges from the former candidate list and extends this
   776     /// list in every iteration (\ref AlteringListPivotRule).
   777     ///
   778     /// According to our comprehensive benchmark tests the "Block Search"
   779     /// pivot rule proved to be the fastest and the most robust on
   780     /// various test inputs. Thus it is the default option.
   781     ///
   782     /// \return \c true if a feasible flow can be found.
   783     bool run(PivotRuleEnum pivot_rule = BLOCK_SEARCH_PIVOT) {
   784       return init() && start(pivot_rule);
   785     }
   786 
   787     /// @}
   788 
   789     /// \name Query Functions
   790     /// The results of the algorithm can be obtained using these
   791     /// functions.\n
   792     /// \ref lemon::NetworkSimplex::run() "run()" must be called before
   793     /// using them.
   794 
   795     /// @{
   796 
   797     /// \brief Return a const reference to the edge map storing the
   798     /// found flow.
   799     ///
   800     /// Return a const reference to the edge map storing the found flow.
   801     ///
   802     /// \pre \ref run() must be called before using this function.
   803     const FlowMap& flowMap() const {
   804       return *_flow_result;
   805     }
   806 
   807     /// \brief Return a const reference to the node map storing the
   808     /// found potentials (the dual solution).
   809     ///
   810     /// Return a const reference to the node map storing the found
   811     /// potentials (the dual solution).
   812     ///
   813     /// \pre \ref run() must be called before using this function.
   814     const PotentialMap& potentialMap() const {
   815       return *_potential_result;
   816     }
   817 
   818     /// \brief Return the flow on the given edge.
   819     ///
   820     /// Return the flow on the given edge.
   821     ///
   822     /// \pre \ref run() must be called before using this function.
   823     Capacity flow(const typename Graph::Edge& edge) const {
   824       return (*_flow_result)[edge];
   825     }
   826 
   827     /// \brief Return the potential of the given node.
   828     ///
   829     /// Return the potential of the given node.
   830     ///
   831     /// \pre \ref run() must be called before using this function.
   832     Cost potential(const typename Graph::Node& node) const {
   833       return (*_potential_result)[node];
   834     }
   835 
   836     /// \brief Return the total cost of the found flow.
   837     ///
   838     /// Return the total cost of the found flow. The complexity of the
   839     /// function is \f$ O(e) \f$.
   840     ///
   841     /// \pre \ref run() must be called before using this function.
   842     Cost totalCost() const {
   843       Cost c = 0;
   844       for (EdgeIt e(_orig_graph); e != INVALID; ++e)
   845         c += (*_flow_result)[e] * _orig_cost[e];
   846       return c;
   847     }
   848 
   849     /// @}
   850 
   851   private:
   852 
   853     // Initialize internal data structures
   854     bool init() {
   855       // Initialize result maps
   856       if (!_flow_result) {
   857         _flow_result = new FlowMap(_orig_graph);
   858         _local_flow = true;
   859       }
   860       if (!_potential_result) {
   861         _potential_result = new PotentialMap(_orig_graph);
   862         _local_potential = true;
   863       }
   864       
   865       // Initialize vectors
   866       _node_num = countNodes(_orig_graph);
   867       _edge_num = countEdges(_orig_graph);
   868       int all_node_num = _node_num + 1;
   869       int all_edge_num = _edge_num + _node_num;
   870       
   871       _edge.resize(_edge_num);
   872       _node.reserve(_node_num);
   873       _source.resize(all_edge_num);
   874       _target.resize(all_edge_num);
   875       
   876       _cap.resize(all_edge_num);
   877       _cost.resize(all_edge_num);
   878       _supply.resize(all_node_num);
   879       _flow.resize(all_edge_num, 0);
   880       _pi.resize(all_node_num, 0);
   881       
   882       _parent.resize(all_node_num);
   883       _pred.resize(all_node_num);
   884       _forward.resize(all_node_num);
   885       _thread.resize(all_node_num);
   886       _rev_thread.resize(all_node_num);
   887       _succ_num.resize(all_node_num);
   888       _last_succ.resize(all_node_num);
   889       _state.resize(all_edge_num, STATE_LOWER);
   890       
   891       // Initialize node related data
   892       bool valid_supply = true;
   893       if (_orig_supply) {
   894         Supply sum = 0;
   895         int i = 0;
   896         for (NodeIt n(_orig_graph); n != INVALID; ++n, ++i) {
   897           _node.push_back(n);
   898           _node_id[n] = i;
   899           _supply[i] = (*_orig_supply)[n];
   900           sum += _supply[i];
   901         }
   902         valid_supply = (sum == 0);
   903       } else {
   904         int i = 0;
   905         for (NodeIt n(_orig_graph); n != INVALID; ++n, ++i) {
   906           _node.push_back(n);
   907           _node_id[n] = i;
   908           _supply[i] = 0;
   909         }
   910         _supply[_node_id[_orig_source]] =  _orig_flow_value;
   911         _supply[_node_id[_orig_target]] = -_orig_flow_value;
   912       }
   913       if (!valid_supply) return false;
   914       
   915       // Set data for the artificial root node
   916       _root = _node_num;
   917       _parent[_root] = -1;
   918       _pred[_root] = -1;
   919       _thread[_root] = 0;
   920       _rev_thread[0] = _root;
   921       _succ_num[_root] = all_node_num;
   922       _last_succ[_root] = _root - 1;
   923       _supply[_root] = 0;
   924       _pi[_root] = 0;
   925       
   926       // Store the edges
   927       int i = 0;
   928       for (EdgeIt e(_orig_graph); e != INVALID; ++e) {
   929         _edge[i++] = e;
   930       }
   931 
   932       // Initialize edge maps
   933       for (int i = 0; i != _edge_num; ++i) {
   934         Edge e = _edge[i];
   935         _source[i] = _node_id[_orig_graph.source(e)];
   936         _target[i] = _node_id[_orig_graph.target(e)];
   937         _cost[i] = _orig_cost[e];
   938         _cap[i] = _orig_cap[e];
   939       }
   940 
   941       // Remove non-zero lower bounds
   942       if (_orig_lower) {
   943         for (int i = 0; i != _edge_num; ++i) {
   944           Capacity c = (*_orig_lower)[_edge[i]];
   945           if (c != 0) {
   946             _cap[i] -= c;
   947             _supply[_source[i]] -= c;
   948             _supply[_target[i]] += c;
   949           }
   950         }
   951       }
   952 
   953       // Add artificial edges and initialize the spanning tree data structure
   954       Cost max_cost = std::numeric_limits<Cost>::max() / 2 + 1;
   955       Capacity max_cap = std::numeric_limits<Capacity>::max();
   956       for (int u = 0, e = _edge_num; u != _node_num; ++u, ++e) {
   957         _parent[u] = _root;
   958         _pred[u] = e;
   959         _thread[u] = u + 1;
   960         _rev_thread[u + 1] = u;
   961         _succ_num[u] = 1;
   962         _last_succ[u] = u;
   963         _cap[e] = max_cap;
   964         _state[e] = STATE_TREE;
   965         if (_supply[u] >= 0) {
   966           _forward[u] = true;
   967           _pi[u] = 0;
   968           _source[e] = u;
   969           _target[e] = _root;
   970           _flow[e] = _supply[u];
   971           _cost[e] = 0;
   972         }
   973         else {
   974           _forward[u] = false;
   975           _pi[u] = max_cost;
   976           _source[e] = _root;
   977           _target[e] = u;
   978           _flow[e] = -_supply[u];
   979           _cost[e] = max_cost;
   980         }
   981       }
   982 
   983       return true;
   984     }
   985 
   986     // Find the join node
   987     void findJoinNode() {
   988       int u = _source[_in_edge];
   989       int v = _target[_in_edge];
   990       while (u != v) {
   991         if (_succ_num[u] < _succ_num[v]) {
   992           u = _parent[u];
   993         } else {
   994           v = _parent[v];
   995         }
   996       }
   997       join = u;
   998     }
   999 
  1000     // Find the leaving edge of the cycle and returns true if the
  1001     // leaving edge is not the same as the entering edge
  1002     bool findLeavingEdge() {
  1003       // Initialize first and second nodes according to the direction
  1004       // of the cycle
  1005       if (_state[_in_edge] == STATE_LOWER) {
  1006         first  = _source[_in_edge];
  1007         second = _target[_in_edge];
  1008       } else {
  1009         first  = _target[_in_edge];
  1010         second = _source[_in_edge];
  1011       }
  1012       delta = _cap[_in_edge];
  1013       int result = 0;
  1014       Capacity d;
  1015       int e;
  1016 
  1017       // Search the cycle along the path form the first node to the root
  1018       for (int u = first; u != join; u = _parent[u]) {
  1019         e = _pred[u];
  1020         d = _forward[u] ? _flow[e] : _cap[e] - _flow[e];
  1021         if (d < delta) {
  1022           delta = d;
  1023           u_out = u;
  1024           result = 1;
  1025         }
  1026       }
  1027       // Search the cycle along the path form the second node to the root
  1028       for (int u = second; u != join; u = _parent[u]) {
  1029         e = _pred[u];
  1030         d = _forward[u] ? _cap[e] - _flow[e] : _flow[e];
  1031         if (d <= delta) {
  1032           delta = d;
  1033           u_out = u;
  1034           result = 2;
  1035         }
  1036       }
  1037 
  1038       if (result == 1) {
  1039         u_in = first;
  1040         v_in = second;
  1041       } else {
  1042         u_in = second;
  1043         v_in = first;
  1044       }
  1045       return result != 0;
  1046     }
  1047 
  1048     // Change _flow and _state vectors
  1049     void changeFlow(bool change) {
  1050       // Augment along the cycle
  1051       if (delta > 0) {
  1052         Capacity val = _state[_in_edge] * delta;
  1053         _flow[_in_edge] += val;
  1054         for (int u = _source[_in_edge]; u != join; u = _parent[u]) {
  1055           _flow[_pred[u]] += _forward[u] ? -val : val;
  1056         }
  1057         for (int u = _target[_in_edge]; u != join; u = _parent[u]) {
  1058           _flow[_pred[u]] += _forward[u] ? val : -val;
  1059         }
  1060       }
  1061       // Update the state of the entering and leaving edges
  1062       if (change) {
  1063         _state[_in_edge] = STATE_TREE;
  1064         _state[_pred[u_out]] =
  1065           (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
  1066       } else {
  1067         _state[_in_edge] = -_state[_in_edge];
  1068       }
  1069     }
  1070     
  1071     // Update the tree structure
  1072     void updateTreeStructure() {
  1073       int u, w;
  1074       int old_rev_thread = _rev_thread[u_out];
  1075       int old_succ_num = _succ_num[u_out];
  1076       int old_last_succ = _last_succ[u_out];
  1077       v_out = _parent[u_out];
  1078 
  1079       u = _last_succ[u_in];  // the last successor of u_in
  1080       right = _thread[u];    // the node after it
  1081       
  1082       // Handle the case when old_rev_thread equals to v_in 
  1083       // (it also means that join and v_out coincide)
  1084       if (old_rev_thread == v_in) {
  1085         last = _thread[_last_succ[u_out]];
  1086       } else {
  1087         last = _thread[v_in];
  1088       }
  1089 
  1090       // Update _thread and _parent along the stem nodes (i.e. the nodes 
  1091       // between u_in and u_out, whose parent have to be changed)
  1092       _thread[v_in] = stem = u_in;
  1093       _dirty_revs.clear();
  1094       _dirty_revs.push_back(v_in);
  1095       par_stem = v_in;
  1096       while (stem != u_out) {
  1097         // Insert the next stem node into the thread list
  1098         new_stem = _parent[stem];
  1099         _thread[u] = new_stem;
  1100         _dirty_revs.push_back(u);
  1101         
  1102         // Remove the subtree of stem from the thread list
  1103         w = _rev_thread[stem];
  1104         _thread[w] = right;
  1105         _rev_thread[right] = w;
  1106 
  1107         // Change the parent node and shift stem nodes
  1108         _parent[stem] = par_stem;        
  1109         par_stem = stem;
  1110         stem = new_stem;
  1111 
  1112         // Update u and right nodes
  1113         u = _last_succ[stem] == _last_succ[par_stem] ?
  1114           _rev_thread[par_stem] : _last_succ[stem];
  1115         right = _thread[u];
  1116       }
  1117       _parent[u_out] = par_stem;
  1118       _last_succ[u_out] = u;
  1119       _thread[u] = last;
  1120       _rev_thread[last] = u;
  1121 
  1122       // Remove the subtree of u_out from the thread list except for 
  1123       // the case when old_rev_thread equals to v_in 
  1124       // (it also means that join and v_out coincide)
  1125       if (old_rev_thread != v_in) {
  1126         _thread[old_rev_thread] = right;
  1127         _rev_thread[right] = old_rev_thread;
  1128       }
  1129       
  1130       // Update _rev_thread using the new _thread values
  1131       for (int i = 0; i < int(_dirty_revs.size()); ++i) {
  1132         u = _dirty_revs[i];
  1133         _rev_thread[_thread[u]] = u;
  1134       }
  1135       
  1136       // Update _last_succ for the stem nodes from u_out to u_in
  1137       for (u = u_out; u != u_in; u = _parent[u]) {
  1138         _last_succ[_parent[u]] = _last_succ[u];      
  1139       }
  1140 
  1141       // Set limits for updating _last_succ form v_in and v_out
  1142       // towards the root
  1143       int up_limit_in = -1;
  1144       int up_limit_out = -1;
  1145       if (_last_succ[join] == v_in) {
  1146         up_limit_out = join;
  1147       } else {
  1148         up_limit_in = join;
  1149       }
  1150 
  1151       // Update _last_succ from v_in towards the root
  1152       for (u = v_in; u != up_limit_in && _last_succ[u] == v_in; 
  1153            u = _parent[u]) {
  1154         _last_succ[u] = _last_succ[u_out];
  1155       }
  1156       // Update _last_succ from v_out towards the root
  1157       if (join != old_rev_thread && v_in != old_rev_thread) {
  1158         for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ; 
  1159              u = _parent[u]) {
  1160           _last_succ[u] = old_rev_thread;
  1161         }
  1162       } else {
  1163         for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
  1164              u = _parent[u]) {
  1165           _last_succ[u] = _last_succ[u_out];
  1166         }
  1167       }
  1168 
  1169       // Update _pred and _forward for the stem nodes from u_out to u_in
  1170       u = u_out;
  1171       while (u != u_in) {
  1172         w = _parent[u];
  1173         _pred[u] = _pred[w];
  1174         _forward[u] = !_forward[w];
  1175         u = w;
  1176       }
  1177       _pred[u_in] = _in_edge;
  1178       _forward[u_in] = (u_in == _source[_in_edge]);
  1179       
  1180       // Update _succ_num from v_in to join
  1181       for (u = v_in; u != join; u = _parent[u]) {
  1182         _succ_num[u] += old_succ_num;
  1183       }
  1184       // Update _succ_num from v_out to join
  1185       for (u = v_out; u != join; u = _parent[u]) {
  1186         _succ_num[u] -= old_succ_num;
  1187       }
  1188       // Update _succ_num for the stem nodes from u_out to u_in
  1189       int tmp = 0;
  1190       u = u_out;
  1191       while (u != u_in) {
  1192         w = _parent[u];
  1193         tmp = _succ_num[u] - _succ_num[w] + tmp;
  1194         _succ_num[u] = tmp;
  1195         u = w;
  1196       }
  1197       _succ_num[u_in] = old_succ_num;
  1198     }
  1199 
  1200     // Update potentials
  1201     void updatePotential() {
  1202       Cost sigma = _forward[u_in] ?
  1203         _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
  1204         _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
  1205       // Update in the lower subtree (which has been moved)
  1206       int end = _thread[_last_succ[u_in]];
  1207       for (int u = u_in; u != end; u = _thread[u]) {
  1208         _pi[u] += sigma;
  1209       }
  1210     }
  1211 
  1212     // Execute the algorithm
  1213     bool start(PivotRuleEnum pivot_rule) {
  1214       // Select the pivot rule implementation
  1215       switch (pivot_rule) {
  1216         case FIRST_ELIGIBLE_PIVOT:
  1217           return start<FirstEligiblePivotRule>();
  1218         case BEST_ELIGIBLE_PIVOT:
  1219           return start<BestEligiblePivotRule>();
  1220         case BLOCK_SEARCH_PIVOT:
  1221           return start<BlockSearchPivotRule>();
  1222         case CANDIDATE_LIST_PIVOT:
  1223           return start<CandidateListPivotRule>();
  1224         case ALTERING_LIST_PIVOT:
  1225           return start<AlteringListPivotRule>();
  1226       }
  1227       return false;
  1228     }
  1229 
  1230     template<class PivotRuleImplementation>
  1231     bool start() {
  1232       PivotRuleImplementation pivot(*this);
  1233       
  1234       // Execute the network simplex algorithm
  1235       while (pivot.findEnteringEdge()) {
  1236         findJoinNode();
  1237         bool change = findLeavingEdge();
  1238         changeFlow(change);
  1239         if (change) {
  1240           updateTreeStructure();
  1241           updatePotential();
  1242         }
  1243       }
  1244       
  1245       // Check if the flow amount equals zero on all the artificial edges
  1246       for (int e = _edge_num; e != _edge_num + _node_num; ++e) {
  1247         if (_flow[e] > 0) return false;
  1248       }
  1249 
  1250       // Copy flow values to _flow_result
  1251       if (_orig_lower) {
  1252         for (int i = 0; i != _edge_num; ++i) {
  1253           Edge e = _edge[i];
  1254           (*_flow_result)[e] = (*_orig_lower)[e] + _flow[i];
  1255         }
  1256       } else {
  1257         for (int i = 0; i != _edge_num; ++i) {
  1258           (*_flow_result)[_edge[i]] = _flow[i];
  1259         }
  1260       }
  1261       // Copy potential values to _potential_result
  1262       for (int i = 0; i != _node_num; ++i) {
  1263         (*_potential_result)[_node[i]] = _pi[i];
  1264       }
  1265       
  1266       return true;
  1267     }
  1268 
  1269   }; //class NetworkSimplex
  1270 
  1271   ///@}
  1272 
  1273 } //namespace lemon
  1274 
  1275 #endif //LEMON_NETWORK_SIMPLEX_H