lemon/network_simplex.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 936 ddd3c0d3d9bf
parent 921 140c953ad5d1
parent 919 e0cef67fe565
child 984 fcb6ad1e67d0
child 1003 16f55008c863
permissions -rw-r--r--
Implement the scaling Price Refinement heuristic in CostScaling (#417)
instead of Early Termination.

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