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