lemon/network_simplex.h
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 806 fa6f37d7a25b
parent 755 134852d7fb0a
parent 786 e20173729589
child 811 fe80a8145653
permissions -rw-r--r--
Entirely rework CapacityScaling (#180)

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