lemon/network_simplex.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 894 bb70ad62c95f
parent 663 8b0df68370a4
child 892 cbf32bf95954
permissions -rw-r--r--
Fix critical bug in preflow (#372)

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