lemon/network_simplex.h
author Peter Kovacs <kpeter@inf.elte.hu>
Sat, 08 Jan 2011 16:11:48 +0100
changeset 1025 140c953ad5d1
parent 991 fb932bcfd803
child 1026 9312d6c89d02
permissions -rw-r--r--
Minor doc improvements
     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-2010
     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_algs
    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_algs
    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   /// \ref amo93networkflows, \ref dantzig63linearprog,
    45   /// \ref kellyoneill91netsimplex.
    46   /// This algorithm is a highly efficient specialized version of the
    47   /// linear programming simplex method directly for the minimum cost
    48   /// flow problem.
    49   ///
    50   /// In general, %NetworkSimplex is the fastest implementation available
    51   /// in LEMON for this problem.
    52   /// Moreover, it supports both directions of the supply/demand inequality
    53   /// constraints. For more information, see \ref SupplyType.
    54   ///
    55   /// Most of the parameters of the problem (except for the digraph)
    56   /// can be given using separate functions, and the algorithm can be
    57   /// executed using the \ref run() function. If some parameters are not
    58   /// specified, then default values will be used.
    59   ///
    60   /// \tparam GR The digraph type the algorithm runs on.
    61   /// \tparam V The number type used for flow amounts, capacity bounds
    62   /// and supply values in the algorithm. By default, it is \c int.
    63   /// \tparam C The number type used for costs and potentials in the
    64   /// algorithm. By default, it is the same as \c V.
    65   ///
    66   /// \warning Both \c V and \c C must be signed number types.
    67   /// \warning All input data (capacities, supply values, and costs) must
    68   /// be integer.
    69   ///
    70   /// \note %NetworkSimplex provides five different pivot rule
    71   /// implementations, from which the most efficient one is used
    72   /// by default. For more information, see \ref PivotRule.
    73   template <typename GR, typename V = int, typename C = V>
    74   class NetworkSimplex
    75   {
    76   public:
    77 
    78     /// The type of the flow amounts, capacity bounds and supply values
    79     typedef V Value;
    80     /// The type of the arc costs
    81     typedef C Cost;
    82 
    83   public:
    84 
    85     /// \brief Problem type constants for the \c run() function.
    86     ///
    87     /// Enum type containing the problem type constants that can be
    88     /// returned by the \ref run() function of the algorithm.
    89     enum ProblemType {
    90       /// The problem has no feasible solution (flow).
    91       INFEASIBLE,
    92       /// The problem has optimal solution (i.e. it is feasible and
    93       /// bounded), and the algorithm has found optimal flow and node
    94       /// potentials (primal and dual solutions).
    95       OPTIMAL,
    96       /// The objective function of the problem is unbounded, i.e.
    97       /// there is a directed cycle having negative total cost and
    98       /// infinite upper bound.
    99       UNBOUNDED
   100     };
   101 
   102     /// \brief Constants for selecting the type of the supply constraints.
   103     ///
   104     /// Enum type containing constants for selecting the supply type,
   105     /// i.e. the direction of the inequalities in the supply/demand
   106     /// constraints of the \ref min_cost_flow "minimum cost flow problem".
   107     ///
   108     /// The default supply type is \c GEQ, the \c LEQ type can be
   109     /// selected using \ref supplyType().
   110     /// The equality form is a special case of both supply types.
   111     enum SupplyType {
   112       /// This option means that there are <em>"greater or equal"</em>
   113       /// supply/demand constraints in the definition of the problem.
   114       GEQ,
   115       /// This option means that there are <em>"less or equal"</em>
   116       /// supply/demand constraints in the definition of the problem.
   117       LEQ
   118     };
   119 
   120     /// \brief Constants for selecting the pivot rule.
   121     ///
   122     /// Enum type containing constants for selecting the pivot rule for
   123     /// the \ref run() function.
   124     ///
   125     /// \ref NetworkSimplex provides five different pivot rule
   126     /// implementations that significantly affect the running time
   127     /// of the algorithm.
   128     /// By default, \ref BLOCK_SEARCH "Block Search" is used, which
   129     /// proved to be the most efficient and the most robust on various
   130     /// test inputs.
   131     /// However, another pivot rule can be selected using the \ref run()
   132     /// function with the proper parameter.
   133     enum PivotRule {
   134 
   135       /// The \e First \e Eligible pivot rule.
   136       /// The next eligible arc is selected in a wraparound fashion
   137       /// in every iteration.
   138       FIRST_ELIGIBLE,
   139 
   140       /// The \e Best \e Eligible pivot rule.
   141       /// The best eligible arc is selected in every iteration.
   142       BEST_ELIGIBLE,
   143 
   144       /// The \e Block \e Search pivot rule.
   145       /// A specified number of arcs are examined in every iteration
   146       /// in a wraparound fashion and the best eligible arc is selected
   147       /// from this block.
   148       BLOCK_SEARCH,
   149 
   150       /// The \e Candidate \e List pivot rule.
   151       /// In a major iteration a candidate list is built from eligible arcs
   152       /// in a wraparound fashion and in the following minor iterations
   153       /// the best eligible arc is selected from this list.
   154       CANDIDATE_LIST,
   155 
   156       /// The \e Altering \e Candidate \e List pivot rule.
   157       /// It is a modified version of the Candidate List method.
   158       /// It keeps only the several best eligible arcs from the former
   159       /// candidate list and extends this list in every iteration.
   160       ALTERING_LIST
   161     };
   162 
   163   private:
   164 
   165     TEMPLATE_DIGRAPH_TYPEDEFS(GR);
   166 
   167     typedef std::vector<int> IntVector;
   168     typedef std::vector<Value> ValueVector;
   169     typedef std::vector<Cost> CostVector;
   170     typedef std::vector<signed char> CharVector;
   171     // Note: vector<signed char> is used instead of vector<ArcState> and 
   172     // vector<ArcDirection> for efficiency reasons
   173 
   174     // State constants for arcs
   175     enum ArcState {
   176       STATE_UPPER = -1,
   177       STATE_TREE  =  0,
   178       STATE_LOWER =  1
   179     };
   180 
   181     // Direction constants for tree arcs
   182     enum ArcDirection {
   183       DIR_DOWN = -1,
   184       DIR_UP   =  1
   185     };
   186 
   187   private:
   188 
   189     // Data related to the underlying digraph
   190     const GR &_graph;
   191     int _node_num;
   192     int _arc_num;
   193     int _all_arc_num;
   194     int _search_arc_num;
   195 
   196     // Parameters of the problem
   197     bool _have_lower;
   198     SupplyType _stype;
   199     Value _sum_supply;
   200 
   201     // Data structures for storing the digraph
   202     IntNodeMap _node_id;
   203     IntArcMap _arc_id;
   204     IntVector _source;
   205     IntVector _target;
   206     bool _arc_mixing;
   207 
   208     // Node and arc data
   209     ValueVector _lower;
   210     ValueVector _upper;
   211     ValueVector _cap;
   212     CostVector _cost;
   213     ValueVector _supply;
   214     ValueVector _flow;
   215     CostVector _pi;
   216 
   217     // Data for storing the spanning tree structure
   218     IntVector _parent;
   219     IntVector _pred;
   220     IntVector _thread;
   221     IntVector _rev_thread;
   222     IntVector _succ_num;
   223     IntVector _last_succ;
   224     CharVector _pred_dir;
   225     CharVector _state;
   226     IntVector _dirty_revs;
   227     int _root;
   228 
   229     // Temporary data used in the current pivot iteration
   230     int in_arc, join, u_in, v_in, u_out, v_out;
   231     Value delta;
   232 
   233     const Value MAX;
   234 
   235   public:
   236 
   237     /// \brief Constant for infinite upper bounds (capacities).
   238     ///
   239     /// Constant for infinite upper bounds (capacities).
   240     /// It is \c std::numeric_limits<Value>::infinity() if available,
   241     /// \c std::numeric_limits<Value>::max() otherwise.
   242     const Value INF;
   243 
   244   private:
   245 
   246     // Implementation of the First Eligible pivot rule
   247     class FirstEligiblePivotRule
   248     {
   249     private:
   250 
   251       // References to the NetworkSimplex class
   252       const IntVector  &_source;
   253       const IntVector  &_target;
   254       const CostVector &_cost;
   255       const CharVector &_state;
   256       const CostVector &_pi;
   257       int &_in_arc;
   258       int _search_arc_num;
   259 
   260       // Pivot rule data
   261       int _next_arc;
   262 
   263     public:
   264 
   265       // Constructor
   266       FirstEligiblePivotRule(NetworkSimplex &ns) :
   267         _source(ns._source), _target(ns._target),
   268         _cost(ns._cost), _state(ns._state), _pi(ns._pi),
   269         _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
   270         _next_arc(0)
   271       {}
   272 
   273       // Find next entering arc
   274       bool findEnteringArc() {
   275         Cost c;
   276         for (int e = _next_arc; e != _search_arc_num; ++e) {
   277           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   278           if (c < 0) {
   279             _in_arc = e;
   280             _next_arc = e + 1;
   281             return true;
   282           }
   283         }
   284         for (int e = 0; e != _next_arc; ++e) {
   285           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   286           if (c < 0) {
   287             _in_arc = e;
   288             _next_arc = e + 1;
   289             return true;
   290           }
   291         }
   292         return false;
   293       }
   294 
   295     }; //class FirstEligiblePivotRule
   296 
   297 
   298     // Implementation of the Best Eligible pivot rule
   299     class BestEligiblePivotRule
   300     {
   301     private:
   302 
   303       // References to the NetworkSimplex class
   304       const IntVector  &_source;
   305       const IntVector  &_target;
   306       const CostVector &_cost;
   307       const CharVector &_state;
   308       const CostVector &_pi;
   309       int &_in_arc;
   310       int _search_arc_num;
   311 
   312     public:
   313 
   314       // Constructor
   315       BestEligiblePivotRule(NetworkSimplex &ns) :
   316         _source(ns._source), _target(ns._target),
   317         _cost(ns._cost), _state(ns._state), _pi(ns._pi),
   318         _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num)
   319       {}
   320 
   321       // Find next entering arc
   322       bool findEnteringArc() {
   323         Cost c, min = 0;
   324         for (int e = 0; e != _search_arc_num; ++e) {
   325           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   326           if (c < min) {
   327             min = c;
   328             _in_arc = e;
   329           }
   330         }
   331         return min < 0;
   332       }
   333 
   334     }; //class BestEligiblePivotRule
   335 
   336 
   337     // Implementation of the Block Search pivot rule
   338     class BlockSearchPivotRule
   339     {
   340     private:
   341 
   342       // References to the NetworkSimplex class
   343       const IntVector  &_source;
   344       const IntVector  &_target;
   345       const CostVector &_cost;
   346       const CharVector &_state;
   347       const CostVector &_pi;
   348       int &_in_arc;
   349       int _search_arc_num;
   350 
   351       // Pivot rule data
   352       int _block_size;
   353       int _next_arc;
   354 
   355     public:
   356 
   357       // Constructor
   358       BlockSearchPivotRule(NetworkSimplex &ns) :
   359         _source(ns._source), _target(ns._target),
   360         _cost(ns._cost), _state(ns._state), _pi(ns._pi),
   361         _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
   362         _next_arc(0)
   363       {
   364         // The main parameters of the pivot rule
   365         const double BLOCK_SIZE_FACTOR = 1.0;
   366         const int MIN_BLOCK_SIZE = 10;
   367 
   368         _block_size = std::max( int(BLOCK_SIZE_FACTOR *
   369                                     std::sqrt(double(_search_arc_num))),
   370                                 MIN_BLOCK_SIZE );
   371       }
   372 
   373       // Find next entering arc
   374       bool findEnteringArc() {
   375         Cost c, min = 0;
   376         int cnt = _block_size;
   377         int e;
   378         for (e = _next_arc; e != _search_arc_num; ++e) {
   379           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   380           if (c < min) {
   381             min = c;
   382             _in_arc = e;
   383           }
   384           if (--cnt == 0) {
   385             if (min < 0) goto search_end;
   386             cnt = _block_size;
   387           }
   388         }
   389         for (e = 0; e != _next_arc; ++e) {
   390           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   391           if (c < min) {
   392             min = c;
   393             _in_arc = e;
   394           }
   395           if (--cnt == 0) {
   396             if (min < 0) goto search_end;
   397             cnt = _block_size;
   398           }
   399         }
   400         if (min >= 0) return false;
   401 
   402       search_end:
   403         _next_arc = e;
   404         return true;
   405       }
   406 
   407     }; //class BlockSearchPivotRule
   408 
   409 
   410     // Implementation of the Candidate List pivot rule
   411     class CandidateListPivotRule
   412     {
   413     private:
   414 
   415       // References to the NetworkSimplex class
   416       const IntVector  &_source;
   417       const IntVector  &_target;
   418       const CostVector &_cost;
   419       const CharVector &_state;
   420       const CostVector &_pi;
   421       int &_in_arc;
   422       int _search_arc_num;
   423 
   424       // Pivot rule data
   425       IntVector _candidates;
   426       int _list_length, _minor_limit;
   427       int _curr_length, _minor_count;
   428       int _next_arc;
   429 
   430     public:
   431 
   432       /// Constructor
   433       CandidateListPivotRule(NetworkSimplex &ns) :
   434         _source(ns._source), _target(ns._target),
   435         _cost(ns._cost), _state(ns._state), _pi(ns._pi),
   436         _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
   437         _next_arc(0)
   438       {
   439         // The main parameters of the pivot rule
   440         const double LIST_LENGTH_FACTOR = 0.25;
   441         const int MIN_LIST_LENGTH = 10;
   442         const double MINOR_LIMIT_FACTOR = 0.1;
   443         const int MIN_MINOR_LIMIT = 3;
   444 
   445         _list_length = std::max( int(LIST_LENGTH_FACTOR *
   446                                      std::sqrt(double(_search_arc_num))),
   447                                  MIN_LIST_LENGTH );
   448         _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
   449                                  MIN_MINOR_LIMIT );
   450         _curr_length = _minor_count = 0;
   451         _candidates.resize(_list_length);
   452       }
   453 
   454       /// Find next entering arc
   455       bool findEnteringArc() {
   456         Cost min, c;
   457         int e;
   458         if (_curr_length > 0 && _minor_count < _minor_limit) {
   459           // Minor iteration: select the best eligible arc from the
   460           // current candidate list
   461           ++_minor_count;
   462           min = 0;
   463           for (int i = 0; i < _curr_length; ++i) {
   464             e = _candidates[i];
   465             c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   466             if (c < min) {
   467               min = c;
   468               _in_arc = e;
   469             }
   470             else if (c >= 0) {
   471               _candidates[i--] = _candidates[--_curr_length];
   472             }
   473           }
   474           if (min < 0) return true;
   475         }
   476 
   477         // Major iteration: build a new candidate list
   478         min = 0;
   479         _curr_length = 0;
   480         for (e = _next_arc; e != _search_arc_num; ++e) {
   481           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   482           if (c < 0) {
   483             _candidates[_curr_length++] = e;
   484             if (c < min) {
   485               min = c;
   486               _in_arc = e;
   487             }
   488             if (_curr_length == _list_length) goto search_end;
   489           }
   490         }
   491         for (e = 0; e != _next_arc; ++e) {
   492           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   493           if (c < 0) {
   494             _candidates[_curr_length++] = e;
   495             if (c < min) {
   496               min = c;
   497               _in_arc = e;
   498             }
   499             if (_curr_length == _list_length) goto search_end;
   500           }
   501         }
   502         if (_curr_length == 0) return false;
   503 
   504       search_end:
   505         _minor_count = 1;
   506         _next_arc = e;
   507         return true;
   508       }
   509 
   510     }; //class CandidateListPivotRule
   511 
   512 
   513     // Implementation of the Altering Candidate List pivot rule
   514     class AlteringListPivotRule
   515     {
   516     private:
   517 
   518       // References to the NetworkSimplex class
   519       const IntVector  &_source;
   520       const IntVector  &_target;
   521       const CostVector &_cost;
   522       const CharVector &_state;
   523       const CostVector &_pi;
   524       int &_in_arc;
   525       int _search_arc_num;
   526 
   527       // Pivot rule data
   528       int _block_size, _head_length, _curr_length;
   529       int _next_arc;
   530       IntVector _candidates;
   531       CostVector _cand_cost;
   532 
   533       // Functor class to compare arcs during sort of the candidate list
   534       class SortFunc
   535       {
   536       private:
   537         const CostVector &_map;
   538       public:
   539         SortFunc(const CostVector &map) : _map(map) {}
   540         bool operator()(int left, int right) {
   541           return _map[left] > _map[right];
   542         }
   543       };
   544 
   545       SortFunc _sort_func;
   546 
   547     public:
   548 
   549       // Constructor
   550       AlteringListPivotRule(NetworkSimplex &ns) :
   551         _source(ns._source), _target(ns._target),
   552         _cost(ns._cost), _state(ns._state), _pi(ns._pi),
   553         _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
   554         _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
   555       {
   556         // The main parameters of the pivot rule
   557         const double BLOCK_SIZE_FACTOR = 1.0;
   558         const int MIN_BLOCK_SIZE = 10;
   559         const double HEAD_LENGTH_FACTOR = 0.1;
   560         const int MIN_HEAD_LENGTH = 3;
   561 
   562         _block_size = std::max( int(BLOCK_SIZE_FACTOR *
   563                                     std::sqrt(double(_search_arc_num))),
   564                                 MIN_BLOCK_SIZE );
   565         _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
   566                                  MIN_HEAD_LENGTH );
   567         _candidates.resize(_head_length + _block_size);
   568         _curr_length = 0;
   569       }
   570 
   571       // Find next entering arc
   572       bool findEnteringArc() {
   573         // Check the current candidate list
   574         int e;
   575         Cost c;
   576         for (int i = 0; i != _curr_length; ++i) {
   577           e = _candidates[i];
   578           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   579           if (c < 0) {
   580             _cand_cost[e] = c;
   581           } else {
   582             _candidates[i--] = _candidates[--_curr_length];
   583           }
   584         }
   585 
   586         // Extend the list
   587         int cnt = _block_size;
   588         int limit = _head_length;
   589 
   590         for (e = _next_arc; e != _search_arc_num; ++e) {
   591           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   592           if (c < 0) {
   593             _cand_cost[e] = c;
   594             _candidates[_curr_length++] = e;
   595           }
   596           if (--cnt == 0) {
   597             if (_curr_length > limit) goto search_end;
   598             limit = 0;
   599             cnt = _block_size;
   600           }
   601         }
   602         for (e = 0; e != _next_arc; ++e) {
   603           _cand_cost[e] = _state[e] *
   604             (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   605           if (_cand_cost[e] < 0) {
   606             _candidates[_curr_length++] = e;
   607           }
   608           if (--cnt == 0) {
   609             if (_curr_length > limit) goto search_end;
   610             limit = 0;
   611             cnt = _block_size;
   612           }
   613         }
   614         if (_curr_length == 0) return false;
   615 
   616       search_end:
   617 
   618         // Make heap of the candidate list (approximating a partial sort)
   619         make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
   620                    _sort_func );
   621 
   622         // Pop the first element of the heap
   623         _in_arc = _candidates[0];
   624         _next_arc = e;
   625         pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
   626                   _sort_func );
   627         _curr_length = std::min(_head_length, _curr_length - 1);
   628         return true;
   629       }
   630 
   631     }; //class AlteringListPivotRule
   632 
   633   public:
   634 
   635     /// \brief Constructor.
   636     ///
   637     /// The constructor of the class.
   638     ///
   639     /// \param graph The digraph the algorithm runs on.
   640     /// \param arc_mixing Indicate if the arcs will be stored in a
   641     /// mixed order in the internal data structure.
   642     /// In general, it leads to similar performance as using the original
   643     /// arc order, but it makes the algorithm more robust and in special
   644     /// cases, even significantly faster. Therefore, it is enabled by default.
   645     NetworkSimplex(const GR& graph, bool arc_mixing = true) :
   646       _graph(graph), _node_id(graph), _arc_id(graph),
   647       _arc_mixing(arc_mixing),
   648       MAX(std::numeric_limits<Value>::max()),
   649       INF(std::numeric_limits<Value>::has_infinity ?
   650           std::numeric_limits<Value>::infinity() : MAX)
   651     {
   652       // Check the number types
   653       LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
   654         "The flow type of NetworkSimplex must be signed");
   655       LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
   656         "The cost type of NetworkSimplex must be signed");
   657 
   658       // Reset data structures
   659       reset();
   660     }
   661 
   662     /// \name Parameters
   663     /// The parameters of the algorithm can be specified using these
   664     /// functions.
   665 
   666     /// @{
   667 
   668     /// \brief Set the lower bounds on the arcs.
   669     ///
   670     /// This function sets the lower bounds on the arcs.
   671     /// If it is not used before calling \ref run(), the lower bounds
   672     /// will be set to zero on all arcs.
   673     ///
   674     /// \param map An arc map storing the lower bounds.
   675     /// Its \c Value type must be convertible to the \c Value type
   676     /// of the algorithm.
   677     ///
   678     /// \return <tt>(*this)</tt>
   679     template <typename LowerMap>
   680     NetworkSimplex& lowerMap(const LowerMap& map) {
   681       _have_lower = true;
   682       for (ArcIt a(_graph); a != INVALID; ++a) {
   683         _lower[_arc_id[a]] = map[a];
   684       }
   685       return *this;
   686     }
   687 
   688     /// \brief Set the upper bounds (capacities) on the arcs.
   689     ///
   690     /// This function sets the upper bounds (capacities) on the arcs.
   691     /// If it is not used before calling \ref run(), the upper bounds
   692     /// will be set to \ref INF on all arcs (i.e. the flow value will be
   693     /// unbounded from above).
   694     ///
   695     /// \param map An arc map storing the upper bounds.
   696     /// Its \c Value type must be convertible to the \c Value type
   697     /// of the algorithm.
   698     ///
   699     /// \return <tt>(*this)</tt>
   700     template<typename UpperMap>
   701     NetworkSimplex& upperMap(const UpperMap& map) {
   702       for (ArcIt a(_graph); a != INVALID; ++a) {
   703         _upper[_arc_id[a]] = map[a];
   704       }
   705       return *this;
   706     }
   707 
   708     /// \brief Set the costs of the arcs.
   709     ///
   710     /// This function sets the costs of the arcs.
   711     /// If it is not used before calling \ref run(), the costs
   712     /// will be set to \c 1 on all arcs.
   713     ///
   714     /// \param map An arc map storing the costs.
   715     /// Its \c Value type must be convertible to the \c Cost type
   716     /// of the algorithm.
   717     ///
   718     /// \return <tt>(*this)</tt>
   719     template<typename CostMap>
   720     NetworkSimplex& costMap(const CostMap& map) {
   721       for (ArcIt a(_graph); a != INVALID; ++a) {
   722         _cost[_arc_id[a]] = map[a];
   723       }
   724       return *this;
   725     }
   726 
   727     /// \brief Set the supply values of the nodes.
   728     ///
   729     /// This function sets the supply values of the nodes.
   730     /// If neither this function nor \ref stSupply() is used before
   731     /// calling \ref run(), the supply of each node will be set to zero.
   732     ///
   733     /// \param map A node map storing the supply values.
   734     /// Its \c Value type must be convertible to the \c Value type
   735     /// of the algorithm.
   736     ///
   737     /// \return <tt>(*this)</tt>
   738     template<typename SupplyMap>
   739     NetworkSimplex& supplyMap(const SupplyMap& map) {
   740       for (NodeIt n(_graph); n != INVALID; ++n) {
   741         _supply[_node_id[n]] = map[n];
   742       }
   743       return *this;
   744     }
   745 
   746     /// \brief Set single source and target nodes and a supply value.
   747     ///
   748     /// This function sets a single source node and a single target node
   749     /// and the required flow value.
   750     /// If neither this function nor \ref supplyMap() is used before
   751     /// calling \ref run(), the supply of each node will be set to zero.
   752     ///
   753     /// Using this function has the same effect as using \ref supplyMap()
   754     /// with such a map in which \c k is assigned to \c s, \c -k is
   755     /// assigned to \c t and all other nodes have zero supply value.
   756     ///
   757     /// \param s The source node.
   758     /// \param t The target node.
   759     /// \param k The required amount of flow from node \c s to node \c t
   760     /// (i.e. the supply of \c s and the demand of \c t).
   761     ///
   762     /// \return <tt>(*this)</tt>
   763     NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
   764       for (int i = 0; i != _node_num; ++i) {
   765         _supply[i] = 0;
   766       }
   767       _supply[_node_id[s]] =  k;
   768       _supply[_node_id[t]] = -k;
   769       return *this;
   770     }
   771 
   772     /// \brief Set the type of the supply constraints.
   773     ///
   774     /// This function sets the type of the supply/demand constraints.
   775     /// If it is not used before calling \ref run(), the \ref GEQ supply
   776     /// type will be used.
   777     ///
   778     /// For more information, see \ref SupplyType.
   779     ///
   780     /// \return <tt>(*this)</tt>
   781     NetworkSimplex& supplyType(SupplyType supply_type) {
   782       _stype = supply_type;
   783       return *this;
   784     }
   785 
   786     /// @}
   787 
   788     /// \name Execution Control
   789     /// The algorithm can be executed using \ref run().
   790 
   791     /// @{
   792 
   793     /// \brief Run the algorithm.
   794     ///
   795     /// This function runs the algorithm.
   796     /// The paramters can be specified using functions \ref lowerMap(),
   797     /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
   798     /// \ref supplyType().
   799     /// For example,
   800     /// \code
   801     ///   NetworkSimplex<ListDigraph> ns(graph);
   802     ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
   803     ///     .supplyMap(sup).run();
   804     /// \endcode
   805     ///
   806     /// This function can be called more than once. All the given parameters
   807     /// are kept for the next call, unless \ref resetParams() or \ref reset()
   808     /// is used, thus only the modified parameters have to be set again.
   809     /// If the underlying digraph was also modified after the construction
   810     /// of the class (or the last \ref reset() call), then the \ref reset()
   811     /// function must be called.
   812     ///
   813     /// \param pivot_rule The pivot rule that will be used during the
   814     /// algorithm. For more information, see \ref PivotRule.
   815     ///
   816     /// \return \c INFEASIBLE if no feasible flow exists,
   817     /// \n \c OPTIMAL if the problem has optimal solution
   818     /// (i.e. it is feasible and bounded), and the algorithm has found
   819     /// optimal flow and node potentials (primal and dual solutions),
   820     /// \n \c UNBOUNDED if the objective function of the problem is
   821     /// unbounded, i.e. there is a directed cycle having negative total
   822     /// cost and infinite upper bound.
   823     ///
   824     /// \see ProblemType, PivotRule
   825     /// \see resetParams(), reset()
   826     ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
   827       if (!init()) return INFEASIBLE;
   828       return start(pivot_rule);
   829     }
   830 
   831     /// \brief Reset all the parameters that have been given before.
   832     ///
   833     /// This function resets all the paramaters that have been given
   834     /// before using functions \ref lowerMap(), \ref upperMap(),
   835     /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
   836     ///
   837     /// It is useful for multiple \ref run() calls. Basically, all the given
   838     /// parameters are kept for the next \ref run() call, unless
   839     /// \ref resetParams() or \ref reset() is used.
   840     /// If the underlying digraph was also modified after the construction
   841     /// of the class or the last \ref reset() call, then the \ref reset()
   842     /// function must be used, otherwise \ref resetParams() is sufficient.
   843     ///
   844     /// For example,
   845     /// \code
   846     ///   NetworkSimplex<ListDigraph> ns(graph);
   847     ///
   848     ///   // First run
   849     ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
   850     ///     .supplyMap(sup).run();
   851     ///
   852     ///   // Run again with modified cost map (resetParams() is not called,
   853     ///   // so only the cost map have to be set again)
   854     ///   cost[e] += 100;
   855     ///   ns.costMap(cost).run();
   856     ///
   857     ///   // Run again from scratch using resetParams()
   858     ///   // (the lower bounds will be set to zero on all arcs)
   859     ///   ns.resetParams();
   860     ///   ns.upperMap(capacity).costMap(cost)
   861     ///     .supplyMap(sup).run();
   862     /// \endcode
   863     ///
   864     /// \return <tt>(*this)</tt>
   865     ///
   866     /// \see reset(), run()
   867     NetworkSimplex& resetParams() {
   868       for (int i = 0; i != _node_num; ++i) {
   869         _supply[i] = 0;
   870       }
   871       for (int i = 0; i != _arc_num; ++i) {
   872         _lower[i] = 0;
   873         _upper[i] = INF;
   874         _cost[i] = 1;
   875       }
   876       _have_lower = false;
   877       _stype = GEQ;
   878       return *this;
   879     }
   880 
   881     /// \brief Reset the internal data structures and all the parameters
   882     /// that have been given before.
   883     ///
   884     /// This function resets the internal data structures and all the
   885     /// paramaters that have been given before using functions \ref lowerMap(),
   886     /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
   887     /// \ref supplyType().
   888     ///
   889     /// It is useful for multiple \ref run() calls. Basically, all the given
   890     /// parameters are kept for the next \ref run() call, unless
   891     /// \ref resetParams() or \ref reset() is used.
   892     /// If the underlying digraph was also modified after the construction
   893     /// of the class or the last \ref reset() call, then the \ref reset()
   894     /// function must be used, otherwise \ref resetParams() is sufficient.
   895     ///
   896     /// See \ref resetParams() for examples.
   897     ///
   898     /// \return <tt>(*this)</tt>
   899     ///
   900     /// \see resetParams(), run()
   901     NetworkSimplex& reset() {
   902       // Resize vectors
   903       _node_num = countNodes(_graph);
   904       _arc_num = countArcs(_graph);
   905       int all_node_num = _node_num + 1;
   906       int max_arc_num = _arc_num + 2 * _node_num;
   907 
   908       _source.resize(max_arc_num);
   909       _target.resize(max_arc_num);
   910 
   911       _lower.resize(_arc_num);
   912       _upper.resize(_arc_num);
   913       _cap.resize(max_arc_num);
   914       _cost.resize(max_arc_num);
   915       _supply.resize(all_node_num);
   916       _flow.resize(max_arc_num);
   917       _pi.resize(all_node_num);
   918 
   919       _parent.resize(all_node_num);
   920       _pred.resize(all_node_num);
   921       _pred_dir.resize(all_node_num);
   922       _thread.resize(all_node_num);
   923       _rev_thread.resize(all_node_num);
   924       _succ_num.resize(all_node_num);
   925       _last_succ.resize(all_node_num);
   926       _state.resize(max_arc_num);
   927 
   928       // Copy the graph
   929       int i = 0;
   930       for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
   931         _node_id[n] = i;
   932       }
   933       if (_arc_mixing) {
   934         // Store the arcs in a mixed order
   935         const int skip = std::max(_arc_num / _node_num, 3);
   936         int i = 0, j = 0;
   937         for (ArcIt a(_graph); a != INVALID; ++a) {
   938           _arc_id[a] = i;
   939           _source[i] = _node_id[_graph.source(a)];
   940           _target[i] = _node_id[_graph.target(a)];
   941           if ((i += skip) >= _arc_num) i = ++j;
   942         }
   943       } else {
   944         // Store the arcs in the original order
   945         int i = 0;
   946         for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
   947           _arc_id[a] = i;
   948           _source[i] = _node_id[_graph.source(a)];
   949           _target[i] = _node_id[_graph.target(a)];
   950         }
   951       }
   952 
   953       // Reset parameters
   954       resetParams();
   955       return *this;
   956     }
   957 
   958     /// @}
   959 
   960     /// \name Query Functions
   961     /// The results of the algorithm can be obtained using these
   962     /// functions.\n
   963     /// The \ref run() function must be called before using them.
   964 
   965     /// @{
   966 
   967     /// \brief Return the total cost of the found flow.
   968     ///
   969     /// This function returns the total cost of the found flow.
   970     /// Its complexity is O(e).
   971     ///
   972     /// \note The return type of the function can be specified as a
   973     /// template parameter. For example,
   974     /// \code
   975     ///   ns.totalCost<double>();
   976     /// \endcode
   977     /// It is useful if the total cost cannot be stored in the \c Cost
   978     /// type of the algorithm, which is the default return type of the
   979     /// function.
   980     ///
   981     /// \pre \ref run() must be called before using this function.
   982     template <typename Number>
   983     Number totalCost() const {
   984       Number c = 0;
   985       for (ArcIt a(_graph); a != INVALID; ++a) {
   986         int i = _arc_id[a];
   987         c += Number(_flow[i]) * Number(_cost[i]);
   988       }
   989       return c;
   990     }
   991 
   992 #ifndef DOXYGEN
   993     Cost totalCost() const {
   994       return totalCost<Cost>();
   995     }
   996 #endif
   997 
   998     /// \brief Return the flow on the given arc.
   999     ///
  1000     /// This function returns the flow on the given arc.
  1001     ///
  1002     /// \pre \ref run() must be called before using this function.
  1003     Value flow(const Arc& a) const {
  1004       return _flow[_arc_id[a]];
  1005     }
  1006 
  1007     /// \brief Return the flow map (the primal solution).
  1008     ///
  1009     /// This function copies the flow value on each arc into the given
  1010     /// map. The \c Value type of the algorithm must be convertible to
  1011     /// the \c Value type of the map.
  1012     ///
  1013     /// \pre \ref run() must be called before using this function.
  1014     template <typename FlowMap>
  1015     void flowMap(FlowMap &map) const {
  1016       for (ArcIt a(_graph); a != INVALID; ++a) {
  1017         map.set(a, _flow[_arc_id[a]]);
  1018       }
  1019     }
  1020 
  1021     /// \brief Return the potential (dual value) of the given node.
  1022     ///
  1023     /// This function returns the potential (dual value) of the
  1024     /// given node.
  1025     ///
  1026     /// \pre \ref run() must be called before using this function.
  1027     Cost potential(const Node& n) const {
  1028       return _pi[_node_id[n]];
  1029     }
  1030 
  1031     /// \brief Return the potential map (the dual solution).
  1032     ///
  1033     /// This function copies the potential (dual value) of each node
  1034     /// into the given map.
  1035     /// The \c Cost type of the algorithm must be convertible to the
  1036     /// \c Value type of the map.
  1037     ///
  1038     /// \pre \ref run() must be called before using this function.
  1039     template <typename PotentialMap>
  1040     void potentialMap(PotentialMap &map) const {
  1041       for (NodeIt n(_graph); n != INVALID; ++n) {
  1042         map.set(n, _pi[_node_id[n]]);
  1043       }
  1044     }
  1045 
  1046     /// @}
  1047 
  1048   private:
  1049 
  1050     // Initialize internal data structures
  1051     bool init() {
  1052       if (_node_num == 0) return false;
  1053 
  1054       // Check the sum of supply values
  1055       _sum_supply = 0;
  1056       for (int i = 0; i != _node_num; ++i) {
  1057         _sum_supply += _supply[i];
  1058       }
  1059       if ( !((_stype == GEQ && _sum_supply <= 0) ||
  1060              (_stype == LEQ && _sum_supply >= 0)) ) return false;
  1061 
  1062       // Remove non-zero lower bounds
  1063       if (_have_lower) {
  1064         for (int i = 0; i != _arc_num; ++i) {
  1065           Value c = _lower[i];
  1066           if (c >= 0) {
  1067             _cap[i] = _upper[i] < MAX ? _upper[i] - c : INF;
  1068           } else {
  1069             _cap[i] = _upper[i] < MAX + c ? _upper[i] - c : INF;
  1070           }
  1071           _supply[_source[i]] -= c;
  1072           _supply[_target[i]] += c;
  1073         }
  1074       } else {
  1075         for (int i = 0; i != _arc_num; ++i) {
  1076           _cap[i] = _upper[i];
  1077         }
  1078       }
  1079 
  1080       // Initialize artifical cost
  1081       Cost ART_COST;
  1082       if (std::numeric_limits<Cost>::is_exact) {
  1083         ART_COST = std::numeric_limits<Cost>::max() / 2 + 1;
  1084       } else {
  1085         ART_COST = 0;
  1086         for (int i = 0; i != _arc_num; ++i) {
  1087           if (_cost[i] > ART_COST) ART_COST = _cost[i];
  1088         }
  1089         ART_COST = (ART_COST + 1) * _node_num;
  1090       }
  1091 
  1092       // Initialize arc maps
  1093       for (int i = 0; i != _arc_num; ++i) {
  1094         _flow[i] = 0;
  1095         _state[i] = STATE_LOWER;
  1096       }
  1097 
  1098       // Set data for the artificial root node
  1099       _root = _node_num;
  1100       _parent[_root] = -1;
  1101       _pred[_root] = -1;
  1102       _thread[_root] = 0;
  1103       _rev_thread[0] = _root;
  1104       _succ_num[_root] = _node_num + 1;
  1105       _last_succ[_root] = _root - 1;
  1106       _supply[_root] = -_sum_supply;
  1107       _pi[_root] = 0;
  1108 
  1109       // Add artificial arcs and initialize the spanning tree data structure
  1110       if (_sum_supply == 0) {
  1111         // EQ supply constraints
  1112         _search_arc_num = _arc_num;
  1113         _all_arc_num = _arc_num + _node_num;
  1114         for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
  1115           _parent[u] = _root;
  1116           _pred[u] = e;
  1117           _thread[u] = u + 1;
  1118           _rev_thread[u + 1] = u;
  1119           _succ_num[u] = 1;
  1120           _last_succ[u] = u;
  1121           _cap[e] = INF;
  1122           _state[e] = STATE_TREE;
  1123           if (_supply[u] >= 0) {
  1124             _pred_dir[u] = DIR_UP;
  1125             _pi[u] = 0;
  1126             _source[e] = u;
  1127             _target[e] = _root;
  1128             _flow[e] = _supply[u];
  1129             _cost[e] = 0;
  1130           } else {
  1131             _pred_dir[u] = DIR_DOWN;
  1132             _pi[u] = ART_COST;
  1133             _source[e] = _root;
  1134             _target[e] = u;
  1135             _flow[e] = -_supply[u];
  1136             _cost[e] = ART_COST;
  1137           }
  1138         }
  1139       }
  1140       else if (_sum_supply > 0) {
  1141         // LEQ supply constraints
  1142         _search_arc_num = _arc_num + _node_num;
  1143         int f = _arc_num + _node_num;
  1144         for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
  1145           _parent[u] = _root;
  1146           _thread[u] = u + 1;
  1147           _rev_thread[u + 1] = u;
  1148           _succ_num[u] = 1;
  1149           _last_succ[u] = u;
  1150           if (_supply[u] >= 0) {
  1151             _pred_dir[u] = DIR_UP;
  1152             _pi[u] = 0;
  1153             _pred[u] = e;
  1154             _source[e] = u;
  1155             _target[e] = _root;
  1156             _cap[e] = INF;
  1157             _flow[e] = _supply[u];
  1158             _cost[e] = 0;
  1159             _state[e] = STATE_TREE;
  1160           } else {
  1161             _pred_dir[u] = DIR_DOWN;
  1162             _pi[u] = ART_COST;
  1163             _pred[u] = f;
  1164             _source[f] = _root;
  1165             _target[f] = u;
  1166             _cap[f] = INF;
  1167             _flow[f] = -_supply[u];
  1168             _cost[f] = ART_COST;
  1169             _state[f] = STATE_TREE;
  1170             _source[e] = u;
  1171             _target[e] = _root;
  1172             _cap[e] = INF;
  1173             _flow[e] = 0;
  1174             _cost[e] = 0;
  1175             _state[e] = STATE_LOWER;
  1176             ++f;
  1177           }
  1178         }
  1179         _all_arc_num = f;
  1180       }
  1181       else {
  1182         // GEQ supply constraints
  1183         _search_arc_num = _arc_num + _node_num;
  1184         int f = _arc_num + _node_num;
  1185         for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
  1186           _parent[u] = _root;
  1187           _thread[u] = u + 1;
  1188           _rev_thread[u + 1] = u;
  1189           _succ_num[u] = 1;
  1190           _last_succ[u] = u;
  1191           if (_supply[u] <= 0) {
  1192             _pred_dir[u] = DIR_DOWN;
  1193             _pi[u] = 0;
  1194             _pred[u] = e;
  1195             _source[e] = _root;
  1196             _target[e] = u;
  1197             _cap[e] = INF;
  1198             _flow[e] = -_supply[u];
  1199             _cost[e] = 0;
  1200             _state[e] = STATE_TREE;
  1201           } else {
  1202             _pred_dir[u] = DIR_UP;
  1203             _pi[u] = -ART_COST;
  1204             _pred[u] = f;
  1205             _source[f] = u;
  1206             _target[f] = _root;
  1207             _cap[f] = INF;
  1208             _flow[f] = _supply[u];
  1209             _state[f] = STATE_TREE;
  1210             _cost[f] = ART_COST;
  1211             _source[e] = _root;
  1212             _target[e] = u;
  1213             _cap[e] = INF;
  1214             _flow[e] = 0;
  1215             _cost[e] = 0;
  1216             _state[e] = STATE_LOWER;
  1217             ++f;
  1218           }
  1219         }
  1220         _all_arc_num = f;
  1221       }
  1222 
  1223       return true;
  1224     }
  1225 
  1226     // Find the join node
  1227     void findJoinNode() {
  1228       int u = _source[in_arc];
  1229       int v = _target[in_arc];
  1230       while (u != v) {
  1231         if (_succ_num[u] < _succ_num[v]) {
  1232           u = _parent[u];
  1233         } else {
  1234           v = _parent[v];
  1235         }
  1236       }
  1237       join = u;
  1238     }
  1239 
  1240     // Find the leaving arc of the cycle and returns true if the
  1241     // leaving arc is not the same as the entering arc
  1242     bool findLeavingArc() {
  1243       // Initialize first and second nodes according to the direction
  1244       // of the cycle
  1245       int first, second;
  1246       if (_state[in_arc] == STATE_LOWER) {
  1247         first  = _source[in_arc];
  1248         second = _target[in_arc];
  1249       } else {
  1250         first  = _target[in_arc];
  1251         second = _source[in_arc];
  1252       }
  1253       delta = _cap[in_arc];
  1254       int result = 0;
  1255       Value c, d;
  1256       int e;
  1257 
  1258       // Search the cycle form the first node to the join node
  1259       for (int u = first; u != join; u = _parent[u]) {
  1260         e = _pred[u];
  1261         d = _flow[e];
  1262         if (_pred_dir[u] == DIR_DOWN) {
  1263           c = _cap[e];
  1264           d = c >= MAX ? INF : c - d;
  1265         }
  1266         if (d < delta) {
  1267           delta = d;
  1268           u_out = u;
  1269           result = 1;
  1270         }
  1271       }
  1272 
  1273       // Search the cycle form the second node to the join node
  1274       for (int u = second; u != join; u = _parent[u]) {
  1275         e = _pred[u];
  1276         d = _flow[e];
  1277         if (_pred_dir[u] == DIR_UP) {
  1278           c = _cap[e];
  1279           d = c >= MAX ? INF : c - d;
  1280         }
  1281         if (d <= delta) {
  1282           delta = d;
  1283           u_out = u;
  1284           result = 2;
  1285         }
  1286       }
  1287 
  1288       if (result == 1) {
  1289         u_in = first;
  1290         v_in = second;
  1291       } else {
  1292         u_in = second;
  1293         v_in = first;
  1294       }
  1295       return result != 0;
  1296     }
  1297 
  1298     // Change _flow and _state vectors
  1299     void changeFlow(bool change) {
  1300       // Augment along the cycle
  1301       if (delta > 0) {
  1302         Value val = _state[in_arc] * delta;
  1303         _flow[in_arc] += val;
  1304         for (int u = _source[in_arc]; u != join; u = _parent[u]) {
  1305           _flow[_pred[u]] -= _pred_dir[u] * val;
  1306         }
  1307         for (int u = _target[in_arc]; u != join; u = _parent[u]) {
  1308           _flow[_pred[u]] += _pred_dir[u] * val;
  1309         }
  1310       }
  1311       // Update the state of the entering and leaving arcs
  1312       if (change) {
  1313         _state[in_arc] = STATE_TREE;
  1314         _state[_pred[u_out]] =
  1315           (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
  1316       } else {
  1317         _state[in_arc] = -_state[in_arc];
  1318       }
  1319     }
  1320 
  1321     // Update the tree structure
  1322     void updateTreeStructure() {
  1323       int old_rev_thread = _rev_thread[u_out];
  1324       int old_succ_num = _succ_num[u_out];
  1325       int old_last_succ = _last_succ[u_out];
  1326       v_out = _parent[u_out];
  1327 
  1328       // Check if u_in and u_out coincide
  1329       if (u_in == u_out) {
  1330         // Update _parent, _pred, _pred_dir
  1331         _parent[u_in] = v_in;
  1332         _pred[u_in] = in_arc;
  1333         _pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN;
  1334 
  1335         // Update _thread and _rev_thread
  1336         if (_thread[v_in] != u_out) {
  1337           int after = _thread[old_last_succ];
  1338           _thread[old_rev_thread] = after;
  1339           _rev_thread[after] = old_rev_thread;
  1340           after = _thread[v_in];
  1341           _thread[v_in] = u_out;
  1342           _rev_thread[u_out] = v_in;
  1343           _thread[old_last_succ] = after;
  1344           _rev_thread[after] = old_last_succ;
  1345         }
  1346       } else {
  1347         // Handle the case when old_rev_thread equals to v_in
  1348         // (it also means that join and v_out coincide)
  1349         int thread_continue = old_rev_thread == v_in ?
  1350           _thread[old_last_succ] : _thread[v_in];
  1351 
  1352         // Update _thread and _parent along the stem nodes (i.e. the nodes
  1353         // between u_in and u_out, whose parent have to be changed)
  1354         int stem = u_in;              // the current stem node
  1355         int par_stem = v_in;          // the new parent of stem
  1356         int next_stem;                // the next stem node
  1357         int last = _last_succ[u_in];  // the last successor of stem
  1358         int before, after = _thread[last];
  1359         _thread[v_in] = u_in;
  1360         _dirty_revs.clear();
  1361         _dirty_revs.push_back(v_in);
  1362         while (stem != u_out) {
  1363           // Insert the next stem node into the thread list
  1364           next_stem = _parent[stem];
  1365           _thread[last] = next_stem;
  1366           _dirty_revs.push_back(last);
  1367 
  1368           // Remove the subtree of stem from the thread list
  1369           before = _rev_thread[stem];
  1370           _thread[before] = after;
  1371           _rev_thread[after] = before;
  1372 
  1373           // Change the parent node and shift stem nodes
  1374           _parent[stem] = par_stem;
  1375           par_stem = stem;
  1376           stem = next_stem;
  1377 
  1378           // Update last and after
  1379           last = _last_succ[stem] == _last_succ[par_stem] ?
  1380             _rev_thread[par_stem] : _last_succ[stem];
  1381           after = _thread[last];
  1382         }
  1383         _parent[u_out] = par_stem;
  1384         _thread[last] = thread_continue;
  1385         _rev_thread[thread_continue] = last;
  1386         _last_succ[u_out] = last;
  1387 
  1388         // Remove the subtree of u_out from the thread list except for
  1389         // the case when old_rev_thread equals to v_in
  1390         if (old_rev_thread != v_in) {
  1391           _thread[old_rev_thread] = after;
  1392           _rev_thread[after] = old_rev_thread;
  1393         }
  1394 
  1395         // Update _rev_thread using the new _thread values
  1396         for (int i = 0; i != int(_dirty_revs.size()); ++i) {
  1397           int u = _dirty_revs[i];
  1398           _rev_thread[_thread[u]] = u;
  1399         }
  1400 
  1401         // Update _pred, _pred_dir, _last_succ and _succ_num for the
  1402         // stem nodes from u_out to u_in
  1403         int tmp_sc = 0, tmp_ls = _last_succ[u_out];
  1404         for (int u = u_out, p = _parent[u]; u != u_in; u = p, p = _parent[u]) {
  1405           _pred[u] = _pred[p];
  1406           _pred_dir[u] = -_pred_dir[p];
  1407           tmp_sc += _succ_num[u] - _succ_num[p];
  1408           _succ_num[u] = tmp_sc;
  1409           _last_succ[p] = tmp_ls;
  1410         }
  1411         _pred[u_in] = in_arc;
  1412         _pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN;
  1413         _succ_num[u_in] = old_succ_num;
  1414       }
  1415 
  1416       // Update _last_succ from v_in towards the root
  1417       int up_limit_out = _last_succ[join] == v_in ? join : -1;
  1418       int last_succ_out = _last_succ[u_out];
  1419       for (int u = v_in; u != -1 && _last_succ[u] == v_in; u = _parent[u]) {
  1420         _last_succ[u] = last_succ_out;
  1421       }
  1422 
  1423       // Update _last_succ from v_out towards the root
  1424       if (join != old_rev_thread && v_in != old_rev_thread) {
  1425         for (int u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
  1426              u = _parent[u]) {
  1427           _last_succ[u] = old_rev_thread;
  1428         }
  1429       }
  1430       else if (last_succ_out != old_last_succ) {
  1431         for (int u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
  1432              u = _parent[u]) {
  1433           _last_succ[u] = last_succ_out;
  1434         }
  1435       }
  1436 
  1437       // Update _succ_num from v_in to join
  1438       for (int u = v_in; u != join; u = _parent[u]) {
  1439         _succ_num[u] += old_succ_num;
  1440       }
  1441       // Update _succ_num from v_out to join
  1442       for (int u = v_out; u != join; u = _parent[u]) {
  1443         _succ_num[u] -= old_succ_num;
  1444       }
  1445     }
  1446 
  1447     // Update potentials in the subtree that has been moved
  1448     void updatePotential() {
  1449       Cost sigma = _pi[v_in] - _pi[u_in] -
  1450                    _pred_dir[u_in] * _cost[in_arc];
  1451       int end = _thread[_last_succ[u_in]];
  1452       for (int u = u_in; u != end; u = _thread[u]) {
  1453         _pi[u] += sigma;
  1454       }
  1455     }
  1456 
  1457     // Heuristic initial pivots
  1458     bool initialPivots() {
  1459       Value curr, total = 0;
  1460       std::vector<Node> supply_nodes, demand_nodes;
  1461       for (NodeIt u(_graph); u != INVALID; ++u) {
  1462         curr = _supply[_node_id[u]];
  1463         if (curr > 0) {
  1464           total += curr;
  1465           supply_nodes.push_back(u);
  1466         }
  1467         else if (curr < 0) {
  1468           demand_nodes.push_back(u);
  1469         }
  1470       }
  1471       if (_sum_supply > 0) total -= _sum_supply;
  1472       if (total <= 0) return true;
  1473 
  1474       IntVector arc_vector;
  1475       if (_sum_supply >= 0) {
  1476         if (supply_nodes.size() == 1 && demand_nodes.size() == 1) {
  1477           // Perform a reverse graph search from the sink to the source
  1478           typename GR::template NodeMap<bool> reached(_graph, false);
  1479           Node s = supply_nodes[0], t = demand_nodes[0];
  1480           std::vector<Node> stack;
  1481           reached[t] = true;
  1482           stack.push_back(t);
  1483           while (!stack.empty()) {
  1484             Node u, v = stack.back();
  1485             stack.pop_back();
  1486             if (v == s) break;
  1487             for (InArcIt a(_graph, v); a != INVALID; ++a) {
  1488               if (reached[u = _graph.source(a)]) continue;
  1489               int j = _arc_id[a];
  1490               if (_cap[j] >= total) {
  1491                 arc_vector.push_back(j);
  1492                 reached[u] = true;
  1493                 stack.push_back(u);
  1494               }
  1495             }
  1496           }
  1497         } else {
  1498           // Find the min. cost incomming arc for each demand node
  1499           for (int i = 0; i != int(demand_nodes.size()); ++i) {
  1500             Node v = demand_nodes[i];
  1501             Cost c, min_cost = std::numeric_limits<Cost>::max();
  1502             Arc min_arc = INVALID;
  1503             for (InArcIt a(_graph, v); a != INVALID; ++a) {
  1504               c = _cost[_arc_id[a]];
  1505               if (c < min_cost) {
  1506                 min_cost = c;
  1507                 min_arc = a;
  1508               }
  1509             }
  1510             if (min_arc != INVALID) {
  1511               arc_vector.push_back(_arc_id[min_arc]);
  1512             }
  1513           }
  1514         }
  1515       } else {
  1516         // Find the min. cost outgoing arc for each supply node
  1517         for (int i = 0; i != int(supply_nodes.size()); ++i) {
  1518           Node u = supply_nodes[i];
  1519           Cost c, min_cost = std::numeric_limits<Cost>::max();
  1520           Arc min_arc = INVALID;
  1521           for (OutArcIt a(_graph, u); a != INVALID; ++a) {
  1522             c = _cost[_arc_id[a]];
  1523             if (c < min_cost) {
  1524               min_cost = c;
  1525               min_arc = a;
  1526             }
  1527           }
  1528           if (min_arc != INVALID) {
  1529             arc_vector.push_back(_arc_id[min_arc]);
  1530           }
  1531         }
  1532       }
  1533 
  1534       // Perform heuristic initial pivots
  1535       for (int i = 0; i != int(arc_vector.size()); ++i) {
  1536         in_arc = arc_vector[i];
  1537         if (_state[in_arc] * (_cost[in_arc] + _pi[_source[in_arc]] -
  1538             _pi[_target[in_arc]]) >= 0) continue;
  1539         findJoinNode();
  1540         bool change = findLeavingArc();
  1541         if (delta >= MAX) return false;
  1542         changeFlow(change);
  1543         if (change) {
  1544           updateTreeStructure();
  1545           updatePotential();
  1546         }
  1547       }
  1548       return true;
  1549     }
  1550 
  1551     // Execute the algorithm
  1552     ProblemType start(PivotRule pivot_rule) {
  1553       // Select the pivot rule implementation
  1554       switch (pivot_rule) {
  1555         case FIRST_ELIGIBLE:
  1556           return start<FirstEligiblePivotRule>();
  1557         case BEST_ELIGIBLE:
  1558           return start<BestEligiblePivotRule>();
  1559         case BLOCK_SEARCH:
  1560           return start<BlockSearchPivotRule>();
  1561         case CANDIDATE_LIST:
  1562           return start<CandidateListPivotRule>();
  1563         case ALTERING_LIST:
  1564           return start<AlteringListPivotRule>();
  1565       }
  1566       return INFEASIBLE; // avoid warning
  1567     }
  1568 
  1569     template <typename PivotRuleImpl>
  1570     ProblemType start() {
  1571       PivotRuleImpl pivot(*this);
  1572 
  1573       // Perform heuristic initial pivots
  1574       if (!initialPivots()) return UNBOUNDED;
  1575 
  1576       // Execute the Network Simplex algorithm
  1577       while (pivot.findEnteringArc()) {
  1578         findJoinNode();
  1579         bool change = findLeavingArc();
  1580         if (delta >= MAX) return UNBOUNDED;
  1581         changeFlow(change);
  1582         if (change) {
  1583           updateTreeStructure();
  1584           updatePotential();
  1585         }
  1586       }
  1587 
  1588       // Check feasibility
  1589       for (int e = _search_arc_num; e != _all_arc_num; ++e) {
  1590         if (_flow[e] != 0) return INFEASIBLE;
  1591       }
  1592 
  1593       // Transform the solution and the supply map to the original form
  1594       if (_have_lower) {
  1595         for (int i = 0; i != _arc_num; ++i) {
  1596           Value c = _lower[i];
  1597           if (c != 0) {
  1598             _flow[i] += c;
  1599             _supply[_source[i]] += c;
  1600             _supply[_target[i]] -= c;
  1601           }
  1602         }
  1603       }
  1604 
  1605       // Shift potentials to meet the requirements of the GEQ/LEQ type
  1606       // optimality conditions
  1607       if (_sum_supply == 0) {
  1608         if (_stype == GEQ) {
  1609           Cost max_pot = -std::numeric_limits<Cost>::max();
  1610           for (int i = 0; i != _node_num; ++i) {
  1611             if (_pi[i] > max_pot) max_pot = _pi[i];
  1612           }
  1613           if (max_pot > 0) {
  1614             for (int i = 0; i != _node_num; ++i)
  1615               _pi[i] -= max_pot;
  1616           }
  1617         } else {
  1618           Cost min_pot = std::numeric_limits<Cost>::max();
  1619           for (int i = 0; i != _node_num; ++i) {
  1620             if (_pi[i] < min_pot) min_pot = _pi[i];
  1621           }
  1622           if (min_pot < 0) {
  1623             for (int i = 0; i != _node_num; ++i)
  1624               _pi[i] -= min_pot;
  1625           }
  1626         }
  1627       }
  1628 
  1629       return OPTIMAL;
  1630     }
  1631 
  1632   }; //class NetworkSimplex
  1633 
  1634   ///@}
  1635 
  1636 } //namespace lemon
  1637 
  1638 #endif //LEMON_NETWORK_SIMPLEX_H