lemon/network_simplex.h
changeset 2634 e98bbe64cca4
parent 2630 d239741cfd44
child 2635 23570e368afa
equal deleted inserted replaced
18:d5c822bd99ec 19:13ab2cd16858
    26 
    26 
    27 #include <vector>
    27 #include <vector>
    28 #include <limits>
    28 #include <limits>
    29 #include <algorithm>
    29 #include <algorithm>
    30 
    30 
    31 #include <lemon/graph_adaptor.h>
       
    32 #include <lemon/graph_utils.h>
    31 #include <lemon/graph_utils.h>
    33 #include <lemon/smart_graph.h>
       
    34 #include <lemon/math.h>
    32 #include <lemon/math.h>
    35 
    33 
    36 namespace lemon {
    34 namespace lemon {
    37 
    35 
    38   /// \addtogroup min_cost_flow
    36   /// \addtogroup min_cost_flow
    70              typename CapacityMap = typename Graph::template EdgeMap<int>,
    68              typename CapacityMap = typename Graph::template EdgeMap<int>,
    71              typename CostMap = typename Graph::template EdgeMap<int>,
    69              typename CostMap = typename Graph::template EdgeMap<int>,
    72              typename SupplyMap = typename Graph::template NodeMap<int> >
    70              typename SupplyMap = typename Graph::template NodeMap<int> >
    73   class NetworkSimplex
    71   class NetworkSimplex
    74   {
    72   {
       
    73     GRAPH_TYPEDEFS(typename Graph);
       
    74 
    75     typedef typename CapacityMap::Value Capacity;
    75     typedef typename CapacityMap::Value Capacity;
    76     typedef typename CostMap::Value Cost;
    76     typedef typename CostMap::Value Cost;
    77     typedef typename SupplyMap::Value Supply;
    77     typedef typename SupplyMap::Value Supply;
    78 
    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;
    79     typedef std::vector<Edge> EdgeVector;
       
    80     typedef std::vector<Node> NodeVector;
       
    81     typedef std::vector<int> IntVector;
       
    82     typedef std::vector<bool> BoolVector;
       
    83     typedef std::vector<Capacity> CapacityVector;
       
    84     typedef std::vector<Cost> CostVector;
       
    85     typedef std::vector<Supply> SupplyVector;
       
    86 
       
    87     typedef typename Graph::template NodeMap<int> IntNodeMap;
    98 
    88 
    99   public:
    89   public:
   100 
    90 
   101     /// The type of the flow map.
    91     /// The type of the flow map.
   102     typedef typename Graph::template EdgeMap<Capacity> FlowMap;
    92     typedef typename Graph::template EdgeMap<Capacity> FlowMap;
   114       ALTERING_LIST_PIVOT
   104       ALTERING_LIST_PIVOT
   115     };
   105     };
   116 
   106 
   117   private:
   107   private:
   118 
   108 
   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
   109     /// \brief Implementation of the "First Eligible" pivot rule for the
   149     /// \ref NetworkSimplex "network simplex" algorithm.
   110     /// \ref NetworkSimplex "network simplex" algorithm.
   150     ///
   111     ///
   151     /// This class implements the "First Eligible" pivot rule
   112     /// This class implements the "First Eligible" pivot rule
   152     /// for the \ref NetworkSimplex "network simplex" algorithm.
   113     /// for the \ref NetworkSimplex "network simplex" algorithm.
   155     class FirstEligiblePivotRule
   116     class FirstEligiblePivotRule
   156     {
   117     {
   157     private:
   118     private:
   158 
   119 
   159       // References to the NetworkSimplex class
   120       // References to the NetworkSimplex class
   160       NetworkSimplex &_ns;
   121       const EdgeVector &_edge;
   161       EdgeVector &_edges;
   122       const IntVector  &_source;
   162 
   123       const IntVector  &_target;
       
   124       const CostVector &_cost;
       
   125       const IntVector  &_state;
       
   126       const CostVector &_pi;
       
   127       int &_in_edge;
       
   128       int _edge_num;
       
   129 
       
   130       // Pivot rule data
   163       int _next_edge;
   131       int _next_edge;
   164 
   132 
   165     public:
   133     public:
   166 
   134 
   167       /// Constructor
   135       /// Constructor
   168       FirstEligiblePivotRule(NetworkSimplex &ns, EdgeVector &edges) :
   136       FirstEligiblePivotRule(NetworkSimplex &ns) :
   169         _ns(ns), _edges(edges), _next_edge(0) {}
   137         _edge(ns._edge), _source(ns._source), _target(ns._target),
       
   138         _cost(ns._cost), _state(ns._state), _pi(ns._pi),
       
   139         _in_edge(ns._in_edge), _edge_num(ns._edge_num), _next_edge(0)
       
   140       {}
   170 
   141 
   171       /// Find next entering edge
   142       /// Find next entering edge
   172       bool findEnteringEdge() {
   143       bool findEnteringEdge() {
   173         Edge e;
   144         Cost c;
   174         for (int i = _next_edge; i < int(_edges.size()); ++i) {
   145         for (int e = _next_edge; e < _edge_num; ++e) {
   175           e = _edges[i];
   146           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   176           if (_ns._state[e] * _ns._red_cost[e] < 0) {
   147           if (c < 0) {
   177             _ns._in_edge = e;
   148             _in_edge = e;
   178             _next_edge = i + 1;
   149             _next_edge = e + 1;
   179             return true;
   150             return true;
   180           }
   151           }
   181         }
   152         }
   182         for (int i = 0; i < _next_edge; ++i) {
   153         for (int e = 0; e < _next_edge; ++e) {
   183           e = _edges[i];
   154           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   184           if (_ns._state[e] * _ns._red_cost[e] < 0) {
   155           if (c < 0) {
   185             _ns._in_edge = e;
   156             _in_edge = e;
   186             _next_edge = i + 1;
   157             _next_edge = e + 1;
   187             return true;
   158             return true;
   188           }
   159           }
   189         }
   160         }
   190         return false;
   161         return false;
   191       }
   162       }
       
   163 
   192     }; //class FirstEligiblePivotRule
   164     }; //class FirstEligiblePivotRule
       
   165 
   193 
   166 
   194     /// \brief Implementation of the "Best Eligible" pivot rule for the
   167     /// \brief Implementation of the "Best Eligible" pivot rule for the
   195     /// \ref NetworkSimplex "network simplex" algorithm.
   168     /// \ref NetworkSimplex "network simplex" algorithm.
   196     ///
   169     ///
   197     /// This class implements the "Best Eligible" pivot rule
   170     /// This class implements the "Best Eligible" pivot rule
   201     class BestEligiblePivotRule
   174     class BestEligiblePivotRule
   202     {
   175     {
   203     private:
   176     private:
   204 
   177 
   205       // References to the NetworkSimplex class
   178       // References to the NetworkSimplex class
   206       NetworkSimplex &_ns;
   179       const EdgeVector &_edge;
   207       EdgeVector &_edges;
   180       const IntVector  &_source;
       
   181       const IntVector  &_target;
       
   182       const CostVector &_cost;
       
   183       const IntVector  &_state;
       
   184       const CostVector &_pi;
       
   185       int &_in_edge;
       
   186       int _edge_num;
   208 
   187 
   209     public:
   188     public:
   210 
   189 
   211       /// Constructor
   190       /// Constructor
   212       BestEligiblePivotRule(NetworkSimplex &ns, EdgeVector &edges) :
   191       BestEligiblePivotRule(NetworkSimplex &ns) :
   213         _ns(ns), _edges(edges) {}
   192         _edge(ns._edge), _source(ns._source), _target(ns._target),
       
   193         _cost(ns._cost), _state(ns._state), _pi(ns._pi),
       
   194         _in_edge(ns._in_edge), _edge_num(ns._edge_num)
       
   195       {}
   214 
   196 
   215       /// Find next entering edge
   197       /// Find next entering edge
   216       bool findEnteringEdge() {
   198       bool findEnteringEdge() {
   217         Cost min = 0;
   199         Cost c, min = 0;
   218         Edge e;
   200         for (int e = 0; e < _edge_num; ++e) {
   219         for (int i = 0; i < int(_edges.size()); ++i) {
   201           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   220           e = _edges[i];
   202           if (c < min) {
   221           if (_ns._state[e] * _ns._red_cost[e] < min) {
   203             min = c;
   222             min = _ns._state[e] * _ns._red_cost[e];
   204             _in_edge = e;
   223             _ns._in_edge = e;
       
   224           }
   205           }
   225         }
   206         }
   226         return min < 0;
   207         return min < 0;
   227       }
   208       }
       
   209 
   228     }; //class BestEligiblePivotRule
   210     }; //class BestEligiblePivotRule
       
   211 
   229 
   212 
   230     /// \brief Implementation of the "Block Search" pivot rule for the
   213     /// \brief Implementation of the "Block Search" pivot rule for the
   231     /// \ref NetworkSimplex "network simplex" algorithm.
   214     /// \ref NetworkSimplex "network simplex" algorithm.
   232     ///
   215     ///
   233     /// This class implements the "Block Search" pivot rule
   216     /// This class implements the "Block Search" pivot rule
   237     class BlockSearchPivotRule
   220     class BlockSearchPivotRule
   238     {
   221     {
   239     private:
   222     private:
   240 
   223 
   241       // References to the NetworkSimplex class
   224       // References to the NetworkSimplex class
   242       NetworkSimplex &_ns;
   225       const EdgeVector &_edge;
   243       EdgeVector &_edges;
   226       const IntVector  &_source;
   244 
   227       const IntVector  &_target;
       
   228       const CostVector &_cost;
       
   229       const IntVector  &_state;
       
   230       const CostVector &_pi;
       
   231       int &_in_edge;
       
   232       int _edge_num;
       
   233 
       
   234       // Pivot rule data
   245       int _block_size;
   235       int _block_size;
   246       int _next_edge, _min_edge;
   236       int _next_edge;
   247 
   237 
   248     public:
   238     public:
   249 
   239 
   250       /// Constructor
   240       /// Constructor
   251       BlockSearchPivotRule(NetworkSimplex &ns, EdgeVector &edges) :
   241       BlockSearchPivotRule(NetworkSimplex &ns) :
   252         _ns(ns), _edges(edges), _next_edge(0), _min_edge(0)
   242         _edge(ns._edge), _source(ns._source), _target(ns._target),
       
   243         _cost(ns._cost), _state(ns._state), _pi(ns._pi),
       
   244         _in_edge(ns._in_edge), _edge_num(ns._edge_num), _next_edge(0)
   253       {
   245       {
   254         // The main parameters of the pivot rule
   246         // The main parameters of the pivot rule
   255         const double BLOCK_SIZE_FACTOR = 2.0;
   247         const double BLOCK_SIZE_FACTOR = 2.0;
   256         const int MIN_BLOCK_SIZE = 10;
   248         const int MIN_BLOCK_SIZE = 10;
   257 
   249 
   258         _block_size = std::max( int(BLOCK_SIZE_FACTOR * sqrt(_edges.size())),
   250         _block_size = std::max( int(BLOCK_SIZE_FACTOR * sqrt(_edge_num)),
   259                                 MIN_BLOCK_SIZE );
   251                                 MIN_BLOCK_SIZE );
   260       }
   252       }
   261 
   253 
   262       /// Find next entering edge
   254       /// Find next entering edge
   263       bool findEnteringEdge() {
   255       bool findEnteringEdge() {
   264         Cost curr, min = 0;
   256         Cost c, min = 0;
   265         Edge e;
       
   266         int cnt = _block_size;
   257         int cnt = _block_size;
   267         int i;
   258         int e, min_edge = _next_edge;
   268         for (i = _next_edge; i < int(_edges.size()); ++i) {
   259         for (e = _next_edge; e < _edge_num; ++e) {
   269           e = _edges[i];
   260           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   270           if ((curr = _ns._state[e] * _ns._red_cost[e]) < min) {
   261           if (c < min) {
   271             min = curr;
   262             min = c;
   272             _min_edge = i;
   263             min_edge = e;
   273           }
   264           }
   274           if (--cnt == 0) {
   265           if (--cnt == 0) {
   275             if (min < 0) break;
   266             if (min < 0) break;
   276             cnt = _block_size;
   267             cnt = _block_size;
   277           }
   268           }
   278         }
   269         }
   279         if (min == 0 || cnt > 0) {
   270         if (min == 0 || cnt > 0) {
   280           for (i = 0; i < _next_edge; ++i) {
   271           for (e = 0; e < _next_edge; ++e) {
   281             e = _edges[i];
   272             c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   282             if ((curr = _ns._state[e] * _ns._red_cost[e]) < min) {
   273             if (c < min) {
   283               min = curr;
   274               min = c;
   284               _min_edge = i;
   275               min_edge = e;
   285             }
   276             }
   286             if (--cnt == 0) {
   277             if (--cnt == 0) {
   287               if (min < 0) break;
   278               if (min < 0) break;
   288               cnt = _block_size;
   279               cnt = _block_size;
   289             }
   280             }
   290           }
   281           }
   291         }
   282         }
   292         if (min >= 0) return false;
   283         if (min >= 0) return false;
   293         _ns._in_edge = _edges[_min_edge];
   284         _in_edge = min_edge;
   294         _next_edge = i;
   285         _next_edge = e;
   295         return true;
   286         return true;
   296       }
   287       }
       
   288 
   297     }; //class BlockSearchPivotRule
   289     }; //class BlockSearchPivotRule
       
   290 
   298 
   291 
   299     /// \brief Implementation of the "Candidate List" pivot rule for the
   292     /// \brief Implementation of the "Candidate List" pivot rule for the
   300     /// \ref NetworkSimplex "network simplex" algorithm.
   293     /// \ref NetworkSimplex "network simplex" algorithm.
   301     ///
   294     ///
   302     /// This class implements the "Candidate List" pivot rule
   295     /// This class implements the "Candidate List" pivot rule
   306     class CandidateListPivotRule
   299     class CandidateListPivotRule
   307     {
   300     {
   308     private:
   301     private:
   309 
   302 
   310       // References to the NetworkSimplex class
   303       // References to the NetworkSimplex class
   311       NetworkSimplex &_ns;
   304       const EdgeVector &_edge;
   312       EdgeVector &_edges;
   305       const IntVector  &_source;
   313 
   306       const IntVector  &_target;
   314       EdgeVector _candidates;
   307       const CostVector &_cost;
       
   308       const IntVector  &_state;
       
   309       const CostVector &_pi;
       
   310       int &_in_edge;
       
   311       int _edge_num;
       
   312 
       
   313       // Pivot rule data
       
   314       IntVector _candidates;
   315       int _list_length, _minor_limit;
   315       int _list_length, _minor_limit;
   316       int _curr_length, _minor_count;
   316       int _curr_length, _minor_count;
   317       int _next_edge, _min_edge;
   317       int _next_edge;
   318 
   318 
   319     public:
   319     public:
   320 
   320 
   321       /// Constructor
   321       /// Constructor
   322       CandidateListPivotRule(NetworkSimplex &ns, EdgeVector &edges) :
   322       CandidateListPivotRule(NetworkSimplex &ns) :
   323         _ns(ns), _edges(edges), _next_edge(0), _min_edge(0)
   323         _edge(ns._edge), _source(ns._source), _target(ns._target),
       
   324         _cost(ns._cost), _state(ns._state), _pi(ns._pi),
       
   325         _in_edge(ns._in_edge), _edge_num(ns._edge_num), _next_edge(0)
   324       {
   326       {
   325         // The main parameters of the pivot rule
   327         // The main parameters of the pivot rule
   326         const double LIST_LENGTH_FACTOR = 1.0;
   328         const double LIST_LENGTH_FACTOR = 1.0;
   327         const int MIN_LIST_LENGTH = 10;
   329         const int MIN_LIST_LENGTH = 10;
   328         const double MINOR_LIMIT_FACTOR = 0.1;
   330         const double MINOR_LIMIT_FACTOR = 0.1;
   329         const int MIN_MINOR_LIMIT = 3;
   331         const int MIN_MINOR_LIMIT = 3;
   330 
   332 
   331         _list_length = std::max( int(LIST_LENGTH_FACTOR * sqrt(_edges.size())),
   333         _list_length = std::max( int(LIST_LENGTH_FACTOR * sqrt(_edge_num)),
   332                                  MIN_LIST_LENGTH );
   334                                  MIN_LIST_LENGTH );
   333         _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
   335         _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
   334                                  MIN_MINOR_LIMIT );
   336                                  MIN_MINOR_LIMIT );
   335         _curr_length = _minor_count = 0;
   337         _curr_length = _minor_count = 0;
   336         _candidates.resize(_list_length);
   338         _candidates.resize(_list_length);
   337       }
   339       }
   338 
   340 
   339       /// Find next entering edge
   341       /// Find next entering edge
   340       bool findEnteringEdge() {
   342       bool findEnteringEdge() {
   341         Cost min, curr;
   343         Cost min, c;
       
   344         int e, min_edge = _next_edge;
   342         if (_curr_length > 0 && _minor_count < _minor_limit) {
   345         if (_curr_length > 0 && _minor_count < _minor_limit) {
   343           // Minor iteration: select the best eligible edge from the
   346           // Minor iteration: select the best eligible edge from the
   344           // current candidate list
   347           // current candidate list
   345           ++_minor_count;
   348           ++_minor_count;
   346           Edge e;
       
   347           min = 0;
   349           min = 0;
   348           for (int i = 0; i < _curr_length; ++i) {
   350           for (int i = 0; i < _curr_length; ++i) {
   349             e = _candidates[i];
   351             e = _candidates[i];
   350             curr = _ns._state[e] * _ns._red_cost[e];
   352             c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   351             if (curr < min) {
   353             if (c < min) {
   352               min = curr;
   354               min = c;
   353               _ns._in_edge = e;
   355               min_edge = e;
   354             }
   356             }
   355             if (curr >= 0) {
   357             if (c >= 0) {
   356               _candidates[i--] = _candidates[--_curr_length];
   358               _candidates[i--] = _candidates[--_curr_length];
   357             }
   359             }
   358           }
   360           }
   359           if (min < 0) return true;
   361           if (min < 0) {
       
   362             _in_edge = min_edge;
       
   363             return true;
       
   364           }
   360         }
   365         }
   361 
   366 
   362         // Major iteration: build a new candidate list
   367         // Major iteration: build a new candidate list
   363         Edge e;
       
   364         min = 0;
   368         min = 0;
   365         _curr_length = 0;
   369         _curr_length = 0;
   366         int i;
   370         for (e = _next_edge; e < _edge_num; ++e) {
   367         for (i = _next_edge; i < int(_edges.size()); ++i) {
   371           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   368           e = _edges[i];
   372           if (c < 0) {
   369           if ((curr = _ns._state[e] * _ns._red_cost[e]) < 0) {
       
   370             _candidates[_curr_length++] = e;
   373             _candidates[_curr_length++] = e;
   371             if (curr < min) {
   374             if (c < min) {
   372               min = curr;
   375               min = c;
   373               _min_edge = i;
   376               min_edge = e;
   374             }
   377             }
   375             if (_curr_length == _list_length) break;
   378             if (_curr_length == _list_length) break;
   376           }
   379           }
   377         }
   380         }
   378         if (_curr_length < _list_length) {
   381         if (_curr_length < _list_length) {
   379           for (i = 0; i < _next_edge; ++i) {
   382           for (e = 0; e < _next_edge; ++e) {
   380             e = _edges[i];
   383             c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   381             if ((curr = _ns._state[e] * _ns._red_cost[e]) < 0) {
   384             if (c < 0) {
   382               _candidates[_curr_length++] = e;
   385               _candidates[_curr_length++] = e;
   383               if (curr < min) {
   386               if (c < min) {
   384                 min = curr;
   387                 min = c;
   385                 _min_edge = i;
   388                 min_edge = e;
   386               }
   389               }
   387               if (_curr_length == _list_length) break;
   390               if (_curr_length == _list_length) break;
   388             }
   391             }
   389           }
   392           }
   390         }
   393         }
   391         if (_curr_length == 0) return false;
   394         if (_curr_length == 0) return false;
   392         _minor_count = 1;
   395         _minor_count = 1;
   393         _ns._in_edge = _edges[_min_edge];
   396         _in_edge = min_edge;
   394         _next_edge = i;
   397         _next_edge = e;
   395         return true;
   398         return true;
   396       }
   399       }
       
   400 
   397     }; //class CandidateListPivotRule
   401     }; //class CandidateListPivotRule
       
   402 
   398 
   403 
   399     /// \brief Implementation of the "Altering Candidate List" pivot rule
   404     /// \brief Implementation of the "Altering Candidate List" pivot rule
   400     /// for the \ref NetworkSimplex "network simplex" algorithm.
   405     /// for the \ref NetworkSimplex "network simplex" algorithm.
   401     ///
   406     ///
   402     /// This class implements the "Altering Candidate List" pivot rule
   407     /// This class implements the "Altering Candidate List" pivot rule
   406     class AlteringListPivotRule
   411     class AlteringListPivotRule
   407     {
   412     {
   408     private:
   413     private:
   409 
   414 
   410       // References to the NetworkSimplex class
   415       // References to the NetworkSimplex class
   411       NetworkSimplex &_ns;
   416       const EdgeVector &_edge;
   412       EdgeVector &_edges;
   417       const IntVector  &_source;
   413 
   418       const IntVector  &_target;
   414       EdgeVector _candidates;
   419       const CostVector &_cost;
   415       SCostMap _cand_cost;
   420       const IntVector  &_state;
       
   421       const CostVector &_pi;
       
   422       int &_in_edge;
       
   423       int _edge_num;
       
   424 
   416       int _block_size, _head_length, _curr_length;
   425       int _block_size, _head_length, _curr_length;
   417       int _next_edge;
   426       int _next_edge;
       
   427       IntVector _candidates;
       
   428       CostVector _cand_cost;
   418 
   429 
   419       // Functor class to compare edges during sort of the candidate list
   430       // Functor class to compare edges during sort of the candidate list
   420       class SortFunc
   431       class SortFunc
   421       {
   432       {
   422       private:
   433       private:
   423         const SCostMap &_map;
   434         const CostVector &_map;
   424       public:
   435       public:
   425         SortFunc(const SCostMap &map) : _map(map) {}
   436         SortFunc(const CostVector &map) : _map(map) {}
   426         bool operator()(const Edge &e1, const Edge &e2) {
   437         bool operator()(int left, int right) {
   427           return _map[e1] > _map[e2];
   438           return _map[left] > _map[right];
   428         }
   439         }
   429       };
   440       };
   430 
   441 
   431       SortFunc _sort_func;
   442       SortFunc _sort_func;
   432 
   443 
   433     public:
   444     public:
   434 
   445 
   435       /// Constructor
   446       /// Constructor
   436       AlteringListPivotRule(NetworkSimplex &ns, EdgeVector &edges) :
   447       AlteringListPivotRule(NetworkSimplex &ns) :
   437         _ns(ns), _edges(edges), _cand_cost(_ns._graph),
   448         _edge(ns._edge), _source(ns._source), _target(ns._target),
   438         _next_edge(0), _sort_func(_cand_cost)
   449         _cost(ns._cost), _state(ns._state), _pi(ns._pi),
       
   450         _in_edge(ns._in_edge), _edge_num(ns._edge_num),
       
   451          _next_edge(0), _cand_cost(ns._edge_num),_sort_func(_cand_cost)
   439       {
   452       {
   440         // The main parameters of the pivot rule
   453         // The main parameters of the pivot rule
   441         const double BLOCK_SIZE_FACTOR = 1.5;
   454         const double BLOCK_SIZE_FACTOR = 1.5;
   442         const int MIN_BLOCK_SIZE = 10;
   455         const int MIN_BLOCK_SIZE = 10;
   443         const double HEAD_LENGTH_FACTOR = 0.1;
   456         const double HEAD_LENGTH_FACTOR = 0.1;
   444         const int MIN_HEAD_LENGTH = 3;
   457         const int MIN_HEAD_LENGTH = 3;
   445 
   458 
   446         _block_size = std::max( int(BLOCK_SIZE_FACTOR * sqrt(_edges.size())),
   459         _block_size = std::max( int(BLOCK_SIZE_FACTOR * sqrt(_edge_num)),
   447                                 MIN_BLOCK_SIZE );
   460                                 MIN_BLOCK_SIZE );
   448         _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
   461         _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
   449                                  MIN_HEAD_LENGTH );
   462                                  MIN_HEAD_LENGTH );
   450         _candidates.resize(_head_length + _block_size);
   463         _candidates.resize(_head_length + _block_size);
   451         _curr_length = 0;
   464         _curr_length = 0;
   452       }
   465       }
   453 
   466 
   454       /// Find next entering edge
   467       /// Find next entering edge
   455       bool findEnteringEdge() {
   468       bool findEnteringEdge() {
   456         // Check the current candidate list
   469         // Check the current candidate list
   457         Edge e;
   470         int e;
   458         for (int ix = 0; ix < _curr_length; ++ix) {
   471         for (int i = 0; i < _curr_length; ++i) {
   459           e = _candidates[ix];
   472           e = _candidates[i];
   460           if ((_cand_cost[e] = _ns._state[e] * _ns._red_cost[e]) >= 0) {
   473           _cand_cost[e] = _state[e] * 
   461             _candidates[ix--] = _candidates[--_curr_length];
   474             (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
       
   475           if (_cand_cost[e] >= 0) {
       
   476             _candidates[i--] = _candidates[--_curr_length];
   462           }
   477           }
   463         }
   478         }
   464 
   479 
   465         // Extend the list
   480         // Extend the list
   466         int cnt = _block_size;
   481         int cnt = _block_size;
   467         int last_edge = 0;
   482         int last_edge = 0;
   468         int limit = _head_length;
   483         int limit = _head_length;
   469         for (int i = _next_edge; i < int(_edges.size()); ++i) {
   484         
   470           e = _edges[i];
   485         for (int e = _next_edge; e < _edge_num; ++e) {
   471           if ((_cand_cost[e] = _ns._state[e] * _ns._red_cost[e]) < 0) {
   486           _cand_cost[e] = _state[e] *
       
   487             (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
       
   488           if (_cand_cost[e] < 0) {
   472             _candidates[_curr_length++] = e;
   489             _candidates[_curr_length++] = e;
   473             last_edge = i;
   490             last_edge = e;
   474           }
   491           }
   475           if (--cnt == 0) {
   492           if (--cnt == 0) {
   476             if (_curr_length > limit) break;
   493             if (_curr_length > limit) break;
   477             limit = 0;
   494             limit = 0;
   478             cnt = _block_size;
   495             cnt = _block_size;
   479           }
   496           }
   480         }
   497         }
   481         if (_curr_length <= limit) {
   498         if (_curr_length <= limit) {
   482           for (int i = 0; i < _next_edge; ++i) {
   499           for (int e = 0; e < _next_edge; ++e) {
   483             e = _edges[i];
   500             _cand_cost[e] = _state[e] *
   484             if ((_cand_cost[e] = _ns._state[e] * _ns._red_cost[e]) < 0) {
   501               (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
       
   502             if (_cand_cost[e] < 0) {
   485               _candidates[_curr_length++] = e;
   503               _candidates[_curr_length++] = e;
   486               last_edge = i;
   504               last_edge = e;
   487             }
   505             }
   488             if (--cnt == 0) {
   506             if (--cnt == 0) {
   489               if (_curr_length > limit) break;
   507               if (_curr_length > limit) break;
   490               limit = 0;
   508               limit = 0;
   491               cnt = _block_size;
   509               cnt = _block_size;
   498         // Make heap of the candidate list (approximating a partial sort)
   516         // Make heap of the candidate list (approximating a partial sort)
   499         make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
   517         make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
   500                    _sort_func );
   518                    _sort_func );
   501 
   519 
   502         // Pop the first element of the heap
   520         // Pop the first element of the heap
   503         _ns._in_edge = _candidates[0];
   521         _in_edge = _candidates[0];
   504         pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
   522         pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
   505                   _sort_func );
   523                   _sort_func );
   506         _curr_length = std::min(_head_length, _curr_length - 1);
   524         _curr_length = std::min(_head_length, _curr_length - 1);
   507         return true;
   525         return true;
   508       }
   526       }
       
   527 
   509     }; //class AlteringListPivotRule
   528     }; //class AlteringListPivotRule
   510 
   529 
   511   private:
   530   private:
   512 
   531 
   513     // State constants for edges
   532     // State constants for edges
   517       STATE_LOWER =  1
   536       STATE_LOWER =  1
   518     };
   537     };
   519 
   538 
   520   private:
   539   private:
   521 
   540 
   522     // The directed graph the algorithm runs on
       
   523     SGraph _graph;
       
   524     // The original graph
   541     // The original graph
   525     const Graph &_graph_ref;
   542     const Graph &_orig_graph;
   526     // The original lower bound map
   543     // The original lower bound map
   527     const LowerMap *_lower;
   544     const LowerMap *_orig_lower;
   528     // The capacity map
   545     // The original capacity map
   529     SCapacityMap _capacity;
   546     const CapacityMap &_orig_cap;
   530     // The cost map
   547     // The original cost map
   531     SCostMap _cost;
   548     const CostMap &_orig_cost;
   532     // The supply map
   549     // The original supply map
   533     SSupplyMap _supply;
   550     const SupplyMap *_orig_supply;
   534     bool _valid_supply;
   551     // The source node (if no supply map was given)
   535 
   552     Node _orig_source;
   536     // Edge map of the current flow
   553     // The target node (if no supply map was given)
   537     SCapacityMap _flow;
   554     Node _orig_target;
   538     // Node map of the current potentials
   555     // The flow value (if no supply map was given)
   539     SPotentialMap _potential;
   556     Capacity _orig_flow_value;
   540 
   557 
   541     // The depth node map of the spanning tree structure
   558     // The flow result map
   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;
   559     FlowMap *_flow_result;
       
   560     // The potential result map
   564     PotentialMap *_potential_result;
   561     PotentialMap *_potential_result;
       
   562     // Indicate if the flow result map is local
   565     bool _local_flow;
   563     bool _local_flow;
       
   564     // Indicate if the potential result map is local
   566     bool _local_potential;
   565     bool _local_potential;
   567     NodeRefMap _node_ref;
   566 
   568     EdgeRefMap _edge_ref;
   567     // The edge references
       
   568     EdgeVector _edge;
       
   569     // The node references
       
   570     NodeVector _node;
       
   571     // The node ids
       
   572     IntNodeMap _node_id;
       
   573     // The source nodes of the edges
       
   574     IntVector _source;
       
   575     // The target nodess of the edges
       
   576     IntVector _target;
       
   577 
       
   578     // The (modified) capacity vector
       
   579     CapacityVector _cap;
       
   580     // The cost vector
       
   581     CostVector _cost;
       
   582     // The (modified) supply vector
       
   583     CostVector _supply;
       
   584     // The current flow vector
       
   585     CapacityVector _flow;
       
   586     // The current potential vector
       
   587     CostVector _pi;
       
   588 
       
   589     // The number of nodes in the original graph
       
   590     int _node_num;
       
   591     // The number of edges in the original graph
       
   592     int _edge_num;
       
   593 
       
   594     // The depth vector of the spanning tree structure
       
   595     IntVector _depth;
       
   596     // The parent vector of the spanning tree structure
       
   597     IntVector _parent;
       
   598     // The pred_edge vector of the spanning tree structure
       
   599     IntVector _pred;
       
   600     // The thread vector of the spanning tree structure
       
   601     IntVector _thread;
       
   602     // The forward vector of the spanning tree structure
       
   603     BoolVector _forward;
       
   604     // The state vector
       
   605     IntVector _state;
       
   606     // The root node
       
   607     int _root;
   569 
   608 
   570     // The entering edge of the current pivot iteration
   609     // The entering edge of the current pivot iteration
   571     Edge _in_edge;
   610     int _in_edge;
   572 
   611 
   573     // Temporary nodes used in the current pivot iteration
   612     // Temporary nodes used in the current pivot iteration
   574     Node join, u_in, v_in, u_out, v_out;
   613     int join, u_in, v_in, u_out, v_out;
   575     Node right, first, second, last;
   614     int right, first, second, last;
   576     Node stem, par_stem, new_stem;
   615     int stem, par_stem, new_stem;
       
   616 
   577     // The maximum augment amount along the found cycle in the current
   617     // The maximum augment amount along the found cycle in the current
   578     // pivot iteration
   618     // pivot iteration
   579     Capacity delta;
   619     Capacity delta;
   580 
   620 
   581   public :
   621   public:
   582 
   622 
   583     /// \brief General constructor (with lower bounds).
   623     /// \brief General constructor (with lower bounds).
   584     ///
   624     ///
   585     /// General constructor (with lower bounds).
   625     /// General constructor (with lower bounds).
   586     ///
   626     ///
   592     NetworkSimplex( const Graph &graph,
   632     NetworkSimplex( const Graph &graph,
   593                     const LowerMap &lower,
   633                     const LowerMap &lower,
   594                     const CapacityMap &capacity,
   634                     const CapacityMap &capacity,
   595                     const CostMap &cost,
   635                     const CostMap &cost,
   596                     const SupplyMap &supply ) :
   636                     const SupplyMap &supply ) :
   597       _graph(), _graph_ref(graph), _lower(&lower), _capacity(_graph),
   637       _orig_graph(graph), _orig_lower(&lower), _orig_cap(capacity),
   598       _cost(_graph), _supply(_graph), _flow(_graph),
   638       _orig_cost(cost), _orig_supply(&supply),
   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),
   639       _flow_result(NULL), _potential_result(NULL),
   603       _local_flow(false), _local_potential(false),
   640       _local_flow(false), _local_potential(false),
   604       _node_ref(graph), _edge_ref(graph)
   641       _node_id(graph)
   605     {
   642     {}
   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 
   643 
   633     /// \brief General constructor (without lower bounds).
   644     /// \brief General constructor (without lower bounds).
   634     ///
   645     ///
   635     /// General constructor (without lower bounds).
   646     /// General constructor (without lower bounds).
   636     ///
   647     ///
   640     /// \param supply The supply values of the nodes (signed).
   651     /// \param supply The supply values of the nodes (signed).
   641     NetworkSimplex( const Graph &graph,
   652     NetworkSimplex( const Graph &graph,
   642                     const CapacityMap &capacity,
   653                     const CapacityMap &capacity,
   643                     const CostMap &cost,
   654                     const CostMap &cost,
   644                     const SupplyMap &supply ) :
   655                     const SupplyMap &supply ) :
   645       _graph(), _graph_ref(graph), _lower(NULL), _capacity(_graph),
   656       _orig_graph(graph), _orig_lower(NULL), _orig_cap(capacity),
   646       _cost(_graph), _supply(_graph), _flow(_graph),
   657       _orig_cost(cost), _orig_supply(&supply),
   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),
   658       _flow_result(NULL), _potential_result(NULL),
   651       _local_flow(false), _local_potential(false),
   659       _local_flow(false), _local_potential(false),
   652       _node_ref(graph), _edge_ref(graph)
   660       _node_id(graph)
   653     {
   661     {}
   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 
   662 
   672     /// \brief Simple constructor (with lower bounds).
   663     /// \brief Simple constructor (with lower bounds).
   673     ///
   664     ///
   674     /// Simple constructor (with lower bounds).
   665     /// Simple constructor (with lower bounds).
   675     ///
   666     ///
   683     /// to node \c t (i.e. the supply of \c s and the demand of \c t).
   674     /// to node \c t (i.e. the supply of \c s and the demand of \c t).
   684     NetworkSimplex( const Graph &graph,
   675     NetworkSimplex( const Graph &graph,
   685                     const LowerMap &lower,
   676                     const LowerMap &lower,
   686                     const CapacityMap &capacity,
   677                     const CapacityMap &capacity,
   687                     const CostMap &cost,
   678                     const CostMap &cost,
   688                     typename Graph::Node s,
   679                     Node s, Node t,
   689                     typename Graph::Node t,
   680                     Capacity flow_value ) :
   690                     typename SupplyMap::Value flow_value ) :
   681       _orig_graph(graph), _orig_lower(&lower), _orig_cap(capacity),
   691       _graph(), _graph_ref(graph), _lower(&lower), _capacity(_graph),
   682       _orig_cost(cost), _orig_supply(NULL),
   692       _cost(_graph), _supply(_graph, 0), _flow(_graph),
   683       _orig_source(s), _orig_target(t), _orig_flow_value(flow_value),
   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),
   684       _flow_result(NULL), _potential_result(NULL),
   697       _local_flow(false), _local_potential(false),
   685       _local_flow(false), _local_potential(false),
   698       _node_ref(graph), _edge_ref(graph)
   686       _node_id(graph)
   699     {
   687     {}
   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 
   688 
   723     /// \brief Simple constructor (without lower bounds).
   689     /// \brief Simple constructor (without lower bounds).
   724     ///
   690     ///
   725     /// Simple constructor (without lower bounds).
   691     /// Simple constructor (without lower bounds).
   726     ///
   692     ///
   732     /// \param flow_value The required amount of flow from node \c s
   698     /// \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).
   699     /// to node \c t (i.e. the supply of \c s and the demand of \c t).
   734     NetworkSimplex( const Graph &graph,
   700     NetworkSimplex( const Graph &graph,
   735                     const CapacityMap &capacity,
   701                     const CapacityMap &capacity,
   736                     const CostMap &cost,
   702                     const CostMap &cost,
   737                     typename Graph::Node s,
   703                     Node s, Node t,
   738                     typename Graph::Node t,
   704                     Capacity flow_value ) :
   739                     typename SupplyMap::Value flow_value ) :
   705       _orig_graph(graph), _orig_lower(NULL), _orig_cap(capacity),
   740       _graph(), _graph_ref(graph), _lower(NULL), _capacity(_graph),
   706       _orig_cost(cost), _orig_supply(NULL),
   741       _cost(_graph), _supply(_graph, 0), _flow(_graph),
   707       _orig_source(s), _orig_target(t), _orig_flow_value(flow_value),
   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),
   708       _flow_result(NULL), _potential_result(NULL),
   746       _local_flow(false), _local_potential(false),
   709       _local_flow(false), _local_potential(false),
   747       _node_ref(graph), _edge_ref(graph)
   710       _node_id(graph)
   748     {
   711     {}
   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 
   712 
   763     /// Destructor.
   713     /// Destructor.
   764     ~NetworkSimplex() {
   714     ~NetworkSimplex() {
   765       if (_local_flow) delete _flow_result;
   715       if (_local_flow) delete _flow_result;
   766       if (_local_potential) delete _potential_result;
   716       if (_local_potential) delete _potential_result;
   892     /// function is \f$ O(e) \f$.
   842     /// function is \f$ O(e) \f$.
   893     ///
   843     ///
   894     /// \pre \ref run() must be called before using this function.
   844     /// \pre \ref run() must be called before using this function.
   895     Cost totalCost() const {
   845     Cost totalCost() const {
   896       Cost c = 0;
   846       Cost c = 0;
   897       for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e)
   847       for (EdgeIt e(_orig_graph); e != INVALID; ++e)
   898         c += (*_flow_result)[e] * _cost[_edge_ref[e]];
   848         c += (*_flow_result)[e] * _orig_cost[e];
   899       return c;
   849       return c;
   900     }
   850     }
   901 
   851 
   902     /// @}
   852     /// @}
   903 
   853 
   904   private:
   854   private:
   905 
   855 
   906     // Extend the underlying graph and initialize all the node and edge maps
   856     // Initialize internal data structures
   907     bool init() {
   857     bool init() {
   908       if (!_valid_supply) return false;
       
   909 
       
   910       // Initialize result maps
   858       // Initialize result maps
   911       if (!_flow_result) {
   859       if (!_flow_result) {
   912         _flow_result = new FlowMap(_graph_ref);
   860         _flow_result = new FlowMap(_orig_graph);
   913         _local_flow = true;
   861         _local_flow = true;
   914       }
   862       }
   915       if (!_potential_result) {
   863       if (!_potential_result) {
   916         _potential_result = new PotentialMap(_graph_ref);
   864         _potential_result = new PotentialMap(_orig_graph);
   917         _local_potential = true;
   865         _local_potential = true;
   918       }
   866       }
   919 
   867       
   920       // Initialize the edge vector and the edge maps
   868       // Initialize vectors
   921       _edges.reserve(countEdges(_graph));
   869       _node_num = countNodes(_orig_graph);
   922       for (EdgeIt e(_graph); e != INVALID; ++e) {
   870       _edge_num = countEdges(_orig_graph);
   923         _edges.push_back(e);
   871       int all_node_num = _node_num + 1;
   924         _flow[e] = 0;
   872       int all_edge_num = _edge_num + _node_num;
   925         _state[e] = STATE_LOWER;
   873       
   926       }
   874       _edge.resize(_edge_num);
   927 
   875       _node.reserve(_node_num);
   928       // Add an artificial root node to the graph
   876       _source.resize(all_edge_num);
   929       _root = _graph.addNode();
   877       _target.resize(all_edge_num);
   930       _parent[_root] = INVALID;
   878       
   931       _pred_edge[_root] = INVALID;
   879       _cap.resize(all_edge_num);
       
   880       _cost.resize(all_edge_num);
       
   881       _supply.resize(all_node_num);
       
   882       _flow.resize(all_edge_num, 0);
       
   883       _pi.resize(all_node_num, 0);
       
   884       
       
   885       _depth.resize(all_node_num);
       
   886       _parent.resize(all_node_num);
       
   887       _pred.resize(all_node_num);
       
   888       _thread.resize(all_node_num);
       
   889       _forward.resize(all_node_num);
       
   890       _state.resize(all_edge_num, STATE_LOWER);
       
   891       
       
   892       // Initialize node related data
       
   893       bool valid_supply = true;
       
   894       if (_orig_supply) {
       
   895         Supply sum = 0;
       
   896         int i = 0;
       
   897         for (NodeIt n(_orig_graph); n != INVALID; ++n, ++i) {
       
   898           _node.push_back(n);
       
   899           _node_id[n] = i;
       
   900           _supply[i] = (*_orig_supply)[n];
       
   901           sum += _supply[i];
       
   902         }
       
   903         valid_supply = (sum == 0);
       
   904       } else {
       
   905         int i = 0;
       
   906         for (NodeIt n(_orig_graph); n != INVALID; ++n, ++i) {
       
   907           _node.push_back(n);
       
   908           _node_id[n] = i;
       
   909           _supply[i] = 0;
       
   910         }
       
   911         _supply[_node_id[_orig_source]] =  _orig_flow_value;
       
   912         _supply[_node_id[_orig_target]] = -_orig_flow_value;
       
   913       }
       
   914       if (!valid_supply) return false;
       
   915       
       
   916       // Set data for the artificial root node
       
   917       _root = _node_num;
   932       _depth[_root] = 0;
   918       _depth[_root] = 0;
       
   919       _parent[_root] = -1;
       
   920       _pred[_root] = -1;
       
   921       _thread[_root] = 0;
   933       _supply[_root] = 0;
   922       _supply[_root] = 0;
   934       _potential[_root] = 0;
   923       _pi[_root] = 0;
   935 
   924       
   936       // Add artificial edges to the graph and initialize the node maps
   925       // Store the edges in a mixed order
   937       // of the spanning tree data structure
   926       int k = std::max(int(sqrt(_edge_num)), 10);
   938       Node last = _root;
   927       int i = 0;
   939       Edge e;
   928       for (EdgeIt e(_orig_graph); e != INVALID; ++e) {
       
   929         _edge[i] = e;
       
   930         if ((i += k) >= _edge_num) i = (i % k) + 1;
       
   931       }
       
   932 
       
   933       // Initialize edge maps
       
   934       for (int i = 0; i != _edge_num; ++i) {
       
   935         Edge e = _edge[i];
       
   936         _source[i] = _node_id[_orig_graph.source(e)];
       
   937         _target[i] = _node_id[_orig_graph.target(e)];
       
   938         _cost[i] = _orig_cost[e];
       
   939         _cap[i] = _orig_cap[e];
       
   940       }
       
   941 
       
   942       // Remove non-zero lower bounds
       
   943       if (_orig_lower) {
       
   944         for (int i = 0; i != _edge_num; ++i) {
       
   945           Capacity c = (*_orig_lower)[_edge[i]];
       
   946           if (c != 0) {
       
   947             _cap[i] -= c;
       
   948             _supply[_source[i]] -= c;
       
   949             _supply[_target[i]] += c;
       
   950           }
       
   951         }
       
   952       }
       
   953 
       
   954       // Add artificial edges and initialize the spanning tree data structure
   940       Cost max_cost = std::numeric_limits<Cost>::max() / 4;
   955       Cost max_cost = std::numeric_limits<Cost>::max() / 4;
   941       for (NodeIt u(_graph); u != INVALID; ++u) {
   956       Capacity max_cap = std::numeric_limits<Capacity>::max();
   942         if (u == _root) continue;
   957       for (int u = 0, e = _edge_num; u != _node_num; ++u, ++e) {
   943         _thread[last] = u;
   958         _thread[u] = u + 1;
   944         last = u;
   959         _depth[u] = 1;
   945         _parent[u] = _root;
   960         _parent[u] = _root;
   946         _depth[u] = 1;
   961         _pred[u] = e;
   947         if (_supply[u] >= 0) {
   962         if (_supply[u] >= 0) {
   948           e = _graph.addEdge(u, _root);
       
   949           _flow[e] = _supply[u];
   963           _flow[e] = _supply[u];
   950           _forward[u] = true;
   964           _forward[u] = true;
   951           _potential[u] = -max_cost;
   965           _pi[u] = -max_cost;
   952         } else {
   966         } else {
   953           e = _graph.addEdge(_root, u);
       
   954           _flow[e] = -_supply[u];
   967           _flow[e] = -_supply[u];
   955           _forward[u] = false;
   968           _forward[u] = false;
   956           _potential[u] = max_cost;
   969           _pi[u] = max_cost;
   957         }
   970         }
   958         _cost[e] = max_cost;
   971         _cost[e] = max_cost;
   959         _capacity[e] = std::numeric_limits<Capacity>::max();
   972         _cap[e] = max_cap;
   960         _state[e] = STATE_TREE;
   973         _state[e] = STATE_TREE;
   961         _pred_edge[u] = e;
   974       }
   962       }
       
   963       _thread[last] = _root;
       
   964 
   975 
   965       return true;
   976       return true;
   966     }
   977     }
   967 
   978 
   968     // Find the join node
   979     // Find the join node
   969     void findJoinNode() {
   980     void findJoinNode() {
   970       Node u = _graph.source(_in_edge);
   981       int u = _source[_in_edge];
   971       Node v = _graph.target(_in_edge);
   982       int v = _target[_in_edge];
       
   983       while (_depth[u] > _depth[v]) u = _parent[u];
       
   984       while (_depth[v] > _depth[u]) v = _parent[v];
   972       while (u != v) {
   985       while (u != v) {
   973         if (_depth[u] == _depth[v]) {
   986         u = _parent[u];
   974           u = _parent[u];
   987         v = _parent[v];
   975           v = _parent[v];
       
   976         }
       
   977         else if (_depth[u] > _depth[v]) u = _parent[u];
       
   978         else v = _parent[v];
       
   979       }
   988       }
   980       join = u;
   989       join = u;
   981     }
   990     }
   982 
   991 
   983     // Find the leaving edge of the cycle and returns true if the 
   992     // Find the leaving edge of the cycle and returns true if the
   984     // leaving edge is not the same as the entering edge
   993     // leaving edge is not the same as the entering edge
   985     bool findLeavingEdge() {
   994     bool findLeavingEdge() {
   986       // Initialize first and second nodes according to the direction
   995       // Initialize first and second nodes according to the direction
   987       // of the cycle
   996       // of the cycle
   988       if (_state[_in_edge] == STATE_LOWER) {
   997       if (_state[_in_edge] == STATE_LOWER) {
   989         first  = _graph.source(_in_edge);
   998         first  = _source[_in_edge];
   990         second = _graph.target(_in_edge);
   999         second = _target[_in_edge];
   991       } else {
  1000       } else {
   992         first  = _graph.target(_in_edge);
  1001         first  = _target[_in_edge];
   993         second = _graph.source(_in_edge);
  1002         second = _source[_in_edge];
   994       }
  1003       }
   995       delta = _capacity[_in_edge];
  1004       delta = _cap[_in_edge];
   996       bool result = false;
  1005       int result = 0;
   997       Capacity d;
  1006       Capacity d;
   998       Edge e;
  1007       int e;
   999 
  1008 
  1000       // Search the cycle along the path form the first node to the root
  1009       // Search the cycle along the path form the first node to the root
  1001       for (Node u = first; u != join; u = _parent[u]) {
  1010       for (int u = first; u != join; u = _parent[u]) {
  1002         e = _pred_edge[u];
  1011         e = _pred[u];
  1003         d = _forward[u] ? _flow[e] : _capacity[e] - _flow[e];
  1012         d = _forward[u] ? _flow[e] : _cap[e] - _flow[e];
  1004         if (d < delta) {
  1013         if (d < delta) {
  1005           delta = d;
  1014           delta = d;
  1006           u_out = u;
  1015           u_out = u;
  1007           u_in = first;
  1016           result = 1;
  1008           v_in = second;
       
  1009           result = true;
       
  1010         }
  1017         }
  1011       }
  1018       }
  1012       // Search the cycle along the path form the second node to the root
  1019       // Search the cycle along the path form the second node to the root
  1013       for (Node u = second; u != join; u = _parent[u]) {
  1020       for (int u = second; u != join; u = _parent[u]) {
  1014         e = _pred_edge[u];
  1021         e = _pred[u];
  1015         d = _forward[u] ? _capacity[e] - _flow[e] : _flow[e];
  1022         d = _forward[u] ? _cap[e] - _flow[e] : _flow[e];
  1016         if (d <= delta) {
  1023         if (d <= delta) {
  1017           delta = d;
  1024           delta = d;
  1018           u_out = u;
  1025           u_out = u;
  1019           u_in = second;
  1026           result = 2;
  1020           v_in = first;
  1027         }
  1021           result = true;
  1028       }
  1022         }
  1029 
  1023       }
  1030       if (result == 1) {
  1024       return result;
  1031         u_in = first;
  1025     }
  1032         v_in = second;
  1026 
  1033       } else {
  1027     // Change _flow and _state edge maps
  1034         u_in = second;
  1028     void changeFlows(bool change) {
  1035         v_in = first;
       
  1036       }
       
  1037       return result != 0;
       
  1038     }
       
  1039 
       
  1040     // Change _flow and _state vectors
       
  1041     void changeFlow(bool change) {
  1029       // Augment along the cycle
  1042       // Augment along the cycle
  1030       if (delta > 0) {
  1043       if (delta > 0) {
  1031         Capacity val = _state[_in_edge] * delta;
  1044         Capacity val = _state[_in_edge] * delta;
  1032         _flow[_in_edge] += val;
  1045         _flow[_in_edge] += val;
  1033         for (Node u = _graph.source(_in_edge); u != join; u = _parent[u]) {
  1046         for (int u = _source[_in_edge]; u != join; u = _parent[u]) {
  1034           _flow[_pred_edge[u]] += _forward[u] ? -val : val;
  1047           _flow[_pred[u]] += _forward[u] ? -val : val;
  1035         }
  1048         }
  1036         for (Node u = _graph.target(_in_edge); u != join; u = _parent[u]) {
  1049         for (int u = _target[_in_edge]; u != join; u = _parent[u]) {
  1037           _flow[_pred_edge[u]] += _forward[u] ? val : -val;
  1050           _flow[_pred[u]] += _forward[u] ? val : -val;
  1038         }
  1051         }
  1039       }
  1052       }
  1040       // Update the state of the entering and leaving edges
  1053       // Update the state of the entering and leaving edges
  1041       if (change) {
  1054       if (change) {
  1042         _state[_in_edge] = STATE_TREE;
  1055         _state[_in_edge] = STATE_TREE;
  1043         _state[_pred_edge[u_out]] =
  1056         _state[_pred[u_out]] =
  1044           (_flow[_pred_edge[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
  1057           (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
  1045       } else {
  1058       } else {
  1046         _state[_in_edge] = -_state[_in_edge];
  1059         _state[_in_edge] = -_state[_in_edge];
  1047       }
  1060       }
  1048     }
  1061     }
  1049 
  1062 
  1050     // Update _thread and _parent node maps
  1063     // Update _thread and _parent vectors
  1051     void updateThreadParent() {
  1064     void updateThreadParent() {
  1052       Node u;
  1065       int u;
  1053       v_out = _parent[u_out];
  1066       v_out = _parent[u_out];
  1054 
  1067 
  1055       // Handle the case when join and v_out coincide
  1068       // Handle the case when join and v_out coincide
  1056       bool par_first = false;
  1069       bool par_first = false;
  1057       if (join == v_out) {
  1070       if (join == v_out) {
  1103         for (u = v_out; _thread[u] != u_out; u = _thread[u]) ;
  1116         for (u = v_out; _thread[u] != u_out; u = _thread[u]) ;
  1104         _thread[u] = right;
  1117         _thread[u] = right;
  1105       }
  1118       }
  1106     }
  1119     }
  1107 
  1120 
  1108     // Update _pred_edge and _forward node maps.
  1121     // Update _pred and _forward vectors
  1109     void updatePredEdge() {
  1122     void updatePredEdge() {
  1110       Node u = u_out, v;
  1123       int u = u_out, v;
  1111       while (u != u_in) {
  1124       while (u != u_in) {
  1112         v = _parent[u];
  1125         v = _parent[u];
  1113         _pred_edge[u] = _pred_edge[v];
  1126         _pred[u] = _pred[v];
  1114         _forward[u] = !_forward[v];
  1127         _forward[u] = !_forward[v];
  1115         u = v;
  1128         u = v;
  1116       }
  1129       }
  1117       _pred_edge[u_in] = _in_edge;
  1130       _pred[u_in] = _in_edge;
  1118       _forward[u_in] = (u_in == _graph.source(_in_edge));
  1131       _forward[u_in] = (u_in == _source[_in_edge]);
  1119     }
  1132     }
  1120 
  1133 
  1121     // Update _depth and _potential node maps
  1134     // Update _depth and _potential vectors
  1122     void updateDepthPotential() {
  1135     void updateDepthPotential() {
  1123       _depth[u_in] = _depth[v_in] + 1;
  1136       _depth[u_in] = _depth[v_in] + 1;
  1124       Cost sigma = _forward[u_in] ?
  1137       Cost sigma = _forward[u_in] ?
  1125         _potential[v_in] - _potential[u_in] - _cost[_pred_edge[u_in]] :
  1138         _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
  1126         _potential[v_in] - _potential[u_in] + _cost[_pred_edge[u_in]];
  1139         _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
  1127       _potential[u_in] += sigma;
  1140       _pi[u_in] += sigma;
  1128       for(Node u = _thread[u_in]; _parent[u] != INVALID; u = _thread[u]) {
  1141       for(int u = _thread[u_in]; _parent[u] != -1; u = _thread[u]) {
  1129         _depth[u] = _depth[_parent[u]] + 1;
  1142         _depth[u] = _depth[_parent[u]] + 1;
  1130         if (_depth[u] <= _depth[u_in]) break;
  1143         if (_depth[u] <= _depth[u_in]) break;
  1131         _potential[u] += sigma;
  1144         _pi[u] += sigma;
  1132       }
  1145       }
  1133     }
  1146     }
  1134 
  1147 
  1135     // Execute the algorithm
  1148     // Execute the algorithm
  1136     bool start(PivotRuleEnum pivot_rule) {
  1149     bool start(PivotRuleEnum pivot_rule) {
  1150       return false;
  1163       return false;
  1151     }
  1164     }
  1152 
  1165 
  1153     template<class PivotRuleImplementation>
  1166     template<class PivotRuleImplementation>
  1154     bool start() {
  1167     bool start() {
  1155       PivotRuleImplementation pivot(*this, _edges);
  1168       PivotRuleImplementation pivot(*this);
  1156 
  1169 
  1157       // Execute the network simplex algorithm
  1170       // Execute the network simplex algorithm
  1158       while (pivot.findEnteringEdge()) {
  1171       while (pivot.findEnteringEdge()) {
  1159         findJoinNode();
  1172         findJoinNode();
  1160         bool change = findLeavingEdge();
  1173         bool change = findLeavingEdge();
  1161         changeFlows(change);
  1174         changeFlow(change);
  1162         if (change) {
  1175         if (change) {
  1163           updateThreadParent();
  1176           updateThreadParent();
  1164           updatePredEdge();
  1177           updatePredEdge();
  1165           updateDepthPotential();
  1178           updateDepthPotential();
  1166         }
  1179         }
  1167       }
  1180       }
  1168 
  1181 
  1169       // Check if the flow amount equals zero on all the artificial edges
  1182       // Check if the flow amount equals zero on all the artificial edges
  1170       for (InEdgeIt e(_graph, _root); e != INVALID; ++e)
  1183       for (int e = _edge_num; e != _edge_num + _node_num; ++e) {
  1171         if (_flow[e] > 0) return false;
  1184         if (_flow[e] > 0) return false;
  1172       for (OutEdgeIt e(_graph, _root); e != INVALID; ++e)
  1185       }
  1173         if (_flow[e] > 0) return false;
       
  1174 
  1186 
  1175       // Copy flow values to _flow_result
  1187       // Copy flow values to _flow_result
  1176       if (_lower) {
  1188       if (_orig_lower) {
  1177         for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e)
  1189         for (int i = 0; i != _edge_num; ++i) {
  1178           (*_flow_result)[e] = (*_lower)[e] + _flow[_edge_ref[e]];
  1190           Edge e = _edge[i];
       
  1191           (*_flow_result)[e] = (*_orig_lower)[e] + _flow[i];
       
  1192         }
  1179       } else {
  1193       } else {
  1180         for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e)
  1194         for (int i = 0; i != _edge_num; ++i) {
  1181           (*_flow_result)[e] = _flow[_edge_ref[e]];
  1195           (*_flow_result)[_edge[i]] = _flow[i];
       
  1196         }
  1182       }
  1197       }
  1183       // Copy potential values to _potential_result
  1198       // Copy potential values to _potential_result
  1184       for (typename Graph::NodeIt n(_graph_ref); n != INVALID; ++n)
  1199       for (int i = 0; i != _node_num; ++i) {
  1185         (*_potential_result)[n] = _potential[_node_ref[n]];
  1200         (*_potential_result)[_node[i]] = _pi[i];
       
  1201       }
  1186 
  1202 
  1187       return true;
  1203       return true;
  1188     }
  1204     }
  1189 
  1205 
  1190   }; //class NetworkSimplex
  1206   }; //class NetworkSimplex