lemon/network_simplex.h
author kpeter
Thu, 13 Nov 2008 16:17:50 +0000
changeset 2630 d239741cfd44
parent 2629 84354c78b068
child 2634 e98bbe64cca4
permissions -rw-r--r--
Various improvements in NetworkSimplex.

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