lemon/network_simplex.h
author deba
Mon, 07 May 2007 11:42:18 +0000
changeset 2440 c9218405595b
child 2444 06f3702bf18d
permissions -rw-r--r--
Various min cost flow solvers

Patch from Peter Kovacs
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2007
     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 The network simplex algorithm for finding a minimum cost
    26 /// flow.
    27 
    28 #include <limits>
    29 #include <lemon/smart_graph.h>
    30 #include <lemon/graph_utils.h>
    31 
    32 /// \brief The pivot rule used in the algorithm.
    33 #define EDGE_BLOCK_PIVOT
    34 //#define FIRST_ELIGIBLE_PIVOT
    35 //#define BEST_ELIGIBLE_PIVOT
    36 //#define CANDIDATE_LIST_PIVOT
    37 //#define SORTED_LIST_PIVOT
    38 
    39 /// \brief State constant for edges at their lower bounds.
    40 #define LOWER	1
    41 /// \brief State constant for edges in the spanning tree.
    42 #define TREE	0
    43 /// \brief State constant for edges at their upper bounds.
    44 #define UPPER	-1
    45 
    46 #ifdef EDGE_BLOCK_PIVOT
    47   /// \brief Number of blocks for the "Edge Block" pivot rule.
    48   #define BLOCK_NUM	  100
    49   /// \brief Lower bound for the number of edges to use "Edge Block"
    50   // pivot rule instead of "First Eligible" pivot rule.
    51   #define MIN_BOUND	  1000
    52 #endif
    53 
    54 #ifdef CANDIDATE_LIST_PIVOT
    55   #include <list>
    56   /// \brief The maximum length of the edge list for the
    57   /// "Candidate List" pivot rule.
    58   #define LIST_LENGTH	  100
    59   /// \brief The maximum number of minor iterations between two major
    60   /// itarations.
    61   #define MINOR_LIMIT	  50
    62 #endif
    63 
    64 #ifdef SORTED_LIST_PIVOT
    65   #include <deque>
    66   #include <algorithm>
    67   /// \brief The maximum length of the edge list for the
    68   /// "Sorted List" pivot rule.
    69   #define LIST_LENGTH	  500
    70   #define LOWER_DIV	  4
    71 #endif
    72 
    73 //#define _DEBUG_ITER_
    74 
    75 namespace lemon {
    76 
    77   /// \addtogroup min_cost_flow
    78   /// @{
    79 
    80   /// \brief Implementation of the network simplex algorithm for
    81   /// finding a minimum cost flow.
    82   ///
    83   /// \ref lemon::NetworkSimplex "NetworkSimplex" implements the
    84   /// network simplex algorithm for finding a minimum cost flow.
    85   ///
    86   /// \param Graph The directed graph type the algorithm runs on.
    87   /// \param LowerMap The type of the lower bound map.
    88   /// \param CapacityMap The type of the capacity (upper bound) map.
    89   /// \param CostMap The type of the cost (length) map.
    90   /// \param SupplyMap The type of the supply map.
    91   ///
    92   /// \warning
    93   /// - Edge capacities and costs should be nonnegative integers.
    94   ///	However \c CostMap::Value should be signed type.
    95   /// - Supply values should be integers.
    96   /// - \c LowerMap::Value must be convertible to
    97   ///	\c CapacityMap::Value and \c CapacityMap::Value must be
    98   ///	convertible to \c SupplyMap::Value.
    99   ///
   100   /// \author Peter Kovacs
   101 
   102 template < typename Graph,
   103 	   typename LowerMap = typename Graph::template EdgeMap<int>,
   104 	   typename CapacityMap = LowerMap,
   105 	   typename CostMap = typename Graph::template EdgeMap<int>,
   106 	   typename SupplyMap = typename Graph::template NodeMap
   107 				<typename CapacityMap::Value> >
   108   class NetworkSimplex
   109   {
   110     typedef typename LowerMap::Value Lower;
   111     typedef typename CapacityMap::Value Capacity;
   112     typedef typename CostMap::Value Cost;
   113     typedef typename SupplyMap::Value Supply;
   114 
   115     typedef SmartGraph SGraph;
   116     typedef typename SGraph::Node Node;
   117     typedef typename SGraph::NodeIt NodeIt;
   118     typedef typename SGraph::Edge Edge;
   119     typedef typename SGraph::EdgeIt EdgeIt;
   120     typedef typename SGraph::InEdgeIt InEdgeIt;
   121     typedef typename SGraph::OutEdgeIt OutEdgeIt;
   122 
   123     typedef typename SGraph::template EdgeMap<Lower> SLowerMap;
   124     typedef typename SGraph::template EdgeMap<Capacity> SCapacityMap;
   125     typedef typename SGraph::template EdgeMap<Cost> SCostMap;
   126     typedef typename SGraph::template NodeMap<Supply> SSupplyMap;
   127     typedef typename SGraph::template NodeMap<Cost> SPotentialMap;
   128 
   129     typedef typename SGraph::template NodeMap<int> IntNodeMap;
   130     typedef typename SGraph::template NodeMap<bool> BoolNodeMap;
   131     typedef typename SGraph::template NodeMap<Node> NodeNodeMap;
   132     typedef typename SGraph::template NodeMap<Edge> EdgeNodeMap;
   133     typedef typename SGraph::template EdgeMap<int> IntEdgeMap;
   134 
   135     typedef typename Graph::template NodeMap<Node> NodeRefMap;
   136     typedef typename Graph::template EdgeMap<Edge> EdgeRefMap;
   137 
   138   public:
   139 
   140     /// \brief The type of the flow map.
   141     typedef typename Graph::template EdgeMap<Capacity> FlowMap;
   142     /// \brief The type of the potential map.
   143     typedef typename Graph::template NodeMap<Cost> PotentialMap;
   144 
   145   protected:
   146 
   147     /// \brief Map adaptor class for handling reduced edge costs.
   148     class ReducedCostMap : public MapBase<Edge, Cost>
   149     {
   150     private:
   151 
   152       const SGraph &gr;
   153       const SCostMap &cost_map;
   154       const SPotentialMap &pot_map;
   155 
   156     public:
   157 
   158       typedef typename MapBase<Edge, Cost>::Value Value;
   159       typedef typename MapBase<Edge, Cost>::Key Key;
   160 
   161       ReducedCostMap( const SGraph &_gr,
   162 		      const SCostMap &_cm,
   163 		      const SPotentialMap &_pm ) :
   164 	gr(_gr), cost_map(_cm), pot_map(_pm) {}
   165 
   166       Value operator[](const Key &e) const {
   167 	return cost_map[e] - pot_map[gr.source(e)] + pot_map[gr.target(e)];
   168       }
   169 
   170     }; //class ReducedCostMap
   171 
   172   protected:
   173 
   174     /// \brief The directed graph the algorithm runs on.
   175     SGraph graph;
   176     /// \brief The original graph.
   177     const Graph &graph_ref;
   178     /// \brief The original lower bound map.
   179     const LowerMap *lower;
   180     /// \brief The capacity map.
   181     SCapacityMap capacity;
   182     /// \brief The cost map.
   183     SCostMap cost;
   184     /// \brief The supply map.
   185     SSupplyMap supply;
   186     /// \brief The reduced cost map.
   187     ReducedCostMap red_cost;
   188     /// \brief The sum of supply values equals zero.
   189     bool valid_supply;
   190 
   191     /// \brief The edge map of the current flow.
   192     SCapacityMap flow;
   193     /// \brief The edge map of the found flow on the original graph.
   194     FlowMap flow_result;
   195     /// \brief The potential node map.
   196     SPotentialMap potential;
   197     /// \brief The potential node map on the original graph.
   198     PotentialMap potential_result;
   199 
   200     /// \brief Node reference for the original graph.
   201     NodeRefMap node_ref;
   202     /// \brief Edge reference for the original graph.
   203     EdgeRefMap edge_ref;
   204 
   205     /// \brief The depth node map of the spanning tree structure.
   206     IntNodeMap depth;
   207     /// \brief The parent node map of the spanning tree structure.
   208     NodeNodeMap parent;
   209     /// \brief The pred_edge node map of the spanning tree structure.
   210     EdgeNodeMap pred_edge;
   211     /// \brief The thread node map of the spanning tree structure.
   212     NodeNodeMap thread;
   213     /// \brief The forward node map of the spanning tree structure.
   214     BoolNodeMap forward;
   215     /// \brief The state edge map.
   216     IntEdgeMap state;
   217 
   218 
   219 #ifdef EDGE_BLOCK_PIVOT
   220     /// \brief The size of blocks for the "Edge Block" pivot rule.
   221     int block_size;
   222 #endif
   223 #ifdef CANDIDATE_LIST_PIVOT
   224     /// \brief The list of candidate edges for the "Candidate List"
   225     /// pivot rule.
   226     std::list<Edge> candidates;
   227     /// \brief The number of minor iterations.
   228     int minor_count;
   229 #endif
   230 #ifdef SORTED_LIST_PIVOT
   231     /// \brief The list of candidate edges for the "Sorted List"
   232     /// pivot rule.
   233     std::deque<Edge> candidates;
   234 #endif
   235 
   236     // Root node of the starting spanning tree.
   237     Node root;
   238     // The entering edge of the current pivot iteration.
   239     Edge in_edge;
   240     // Temporary nodes used in the current pivot iteration.
   241     Node join, u_in, v_in, u_out, v_out;
   242     Node right, first, second, last;
   243     Node stem, par_stem, new_stem;
   244     // The maximum augment amount along the cycle in the current pivot
   245     // iteration.
   246     Capacity delta;
   247 
   248   public :
   249 
   250     /// \brief General constructor of the class (with lower bounds).
   251     ///
   252     /// General constructor of the class (with lower bounds).
   253     ///
   254     /// \param _graph The directed graph the algorithm runs on.
   255     /// \param _lower The lower bounds of the edges.
   256     /// \param _capacity The capacities (upper bounds) of the edges.
   257     /// \param _cost The cost (length) values of the edges.
   258     /// \param _supply The supply values of the nodes (signed).
   259     NetworkSimplex( const Graph &_graph,
   260 		    const LowerMap &_lower,
   261 		    const CapacityMap &_capacity,
   262 		    const CostMap &_cost,
   263 		    const SupplyMap &_supply ) :
   264       graph_ref(_graph), lower(&_lower), capacity(graph), cost(graph),
   265       supply(graph), flow(graph), flow_result(_graph), potential(graph),
   266       potential_result(_graph), depth(graph), parent(graph),
   267       pred_edge(graph), thread(graph), forward(graph), state(graph),
   268       node_ref(graph_ref), edge_ref(graph_ref),
   269       red_cost(graph, cost, potential)
   270     {
   271       // Checking the sum of supply values
   272       Supply sum = 0;
   273       for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n)
   274 	sum += _supply[n];
   275       if (!(valid_supply = sum == 0)) return;
   276 
   277       // Copying graph_ref to graph
   278       copyGraph(graph, graph_ref)
   279 	.edgeMap(cost, _cost)
   280 	.nodeRef(node_ref)
   281 	.edgeRef(edge_ref)
   282 	.run();
   283 
   284       // Removing nonzero lower bounds
   285       for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e) {
   286 	capacity[edge_ref[e]] = _capacity[e] - _lower[e];
   287       }
   288       for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n) {
   289 	Supply s = _supply[n];
   290 	for (typename Graph::InEdgeIt e(graph_ref, n); e != INVALID; ++e)
   291 	  s += _lower[e];
   292 	for (typename Graph::OutEdgeIt e(graph_ref, n); e != INVALID; ++e)
   293 	  s -= _lower[e];
   294 	supply[node_ref[n]] = s;
   295       }
   296     }
   297 
   298     /// \brief General constructor of the class (without lower bounds).
   299     ///
   300     /// General constructor of the class (without lower bounds).
   301     ///
   302     /// \param _graph The directed graph the algorithm runs on.
   303     /// \param _capacity The capacities (upper bounds) of the edges.
   304     /// \param _cost The cost (length) values of the edges.
   305     /// \param _supply The supply values of the nodes (signed).
   306     NetworkSimplex( const Graph &_graph,
   307 		    const CapacityMap &_capacity,
   308 		    const CostMap &_cost,
   309 		    const SupplyMap &_supply ) :
   310       graph_ref(_graph), lower(NULL), capacity(graph), cost(graph),
   311       supply(graph), flow(graph), flow_result(_graph), potential(graph),
   312       potential_result(_graph), depth(graph), parent(graph),
   313       pred_edge(graph), thread(graph), forward(graph), state(graph),
   314       node_ref(graph_ref), edge_ref(graph_ref),
   315       red_cost(graph, cost, potential)
   316     {
   317       // Checking the sum of supply values
   318       Supply sum = 0;
   319       for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n)
   320 	sum += _supply[n];
   321       if (!(valid_supply = sum == 0)) return;
   322 
   323       // Copying graph_ref to graph
   324       copyGraph(graph, graph_ref)
   325 	.edgeMap(capacity, _capacity)
   326 	.edgeMap(cost, _cost)
   327 	.nodeMap(supply, _supply)
   328 	.nodeRef(node_ref)
   329 	.edgeRef(edge_ref)
   330 	.run();
   331     }
   332 
   333     /// \brief Simple constructor of the class (with lower bounds).
   334     ///
   335     /// Simple constructor of the class (with lower bounds).
   336     ///
   337     /// \param _graph The directed graph the algorithm runs on.
   338     /// \param _lower The lower bounds of the edges.
   339     /// \param _capacity The capacities (upper bounds) of the edges.
   340     /// \param _cost The cost (length) values of the edges.
   341     /// \param _s The source node.
   342     /// \param _t The target node.
   343     /// \param _flow_value The required amount of flow from node \c _s
   344     /// to node \c _t (i.e. the supply of \c _s and the demand of
   345     /// \c _t).
   346     NetworkSimplex( const Graph &_graph,
   347 		    const LowerMap &_lower,
   348 		    const CapacityMap &_capacity,
   349 		    const CostMap &_cost,
   350 		    typename Graph::Node _s,
   351 		    typename Graph::Node _t,
   352 		    typename SupplyMap::Value _flow_value ) :
   353       graph_ref(_graph), lower(&_lower), capacity(graph), cost(graph),
   354       supply(graph), flow(graph), flow_result(_graph), potential(graph),
   355       potential_result(_graph), depth(graph), parent(graph),
   356       pred_edge(graph), thread(graph), forward(graph), state(graph),
   357       node_ref(graph_ref), edge_ref(graph_ref),
   358       red_cost(graph, cost, potential)
   359     {
   360       // Copying graph_ref to graph
   361       copyGraph(graph, graph_ref)
   362 	.edgeMap(cost, _cost)
   363 	.nodeRef(node_ref)
   364 	.edgeRef(edge_ref)
   365 	.run();
   366 
   367       // Removing nonzero lower bounds
   368       for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e) {
   369 	capacity[edge_ref[e]] = _capacity[e] - _lower[e];
   370       }
   371       for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n) {
   372 	Supply s = 0;
   373 	if (n == _s) s =  _flow_value;
   374 	if (n == _t) s = -_flow_value;
   375 	for (typename Graph::InEdgeIt e(graph_ref, n); e != INVALID; ++e)
   376 	  s += _lower[e];
   377 	for (typename Graph::OutEdgeIt e(graph_ref, n); e != INVALID; ++e)
   378 	  s -= _lower[e];
   379 	supply[node_ref[n]] = s;
   380       }
   381       valid_supply = true;
   382     }
   383 
   384     /// \brief Simple constructor of the class (without lower bounds).
   385     ///
   386     /// Simple constructor of the class (without lower bounds).
   387     ///
   388     /// \param _graph The directed graph the algorithm runs on.
   389     /// \param _capacity The capacities (upper bounds) of the edges.
   390     /// \param _cost The cost (length) values of the edges.
   391     /// \param _s The source node.
   392     /// \param _t The target node.
   393     /// \param _flow_value The required amount of flow from node \c _s
   394     /// to node \c _t (i.e. the supply of \c _s and the demand of
   395     /// \c _t).
   396     NetworkSimplex( const Graph &_graph,
   397 		    const CapacityMap &_capacity,
   398 		    const CostMap &_cost,
   399 		    typename Graph::Node _s,
   400 		    typename Graph::Node _t,
   401 		    typename SupplyMap::Value _flow_value ) :
   402       graph_ref(_graph), lower(NULL), capacity(graph), cost(graph),
   403       supply(graph, 0), flow(graph), flow_result(_graph), potential(graph),
   404       potential_result(_graph), depth(graph), parent(graph),
   405       pred_edge(graph), thread(graph), forward(graph), state(graph),
   406       node_ref(graph_ref), edge_ref(graph_ref),
   407       red_cost(graph, cost, potential)
   408     {
   409       // Copying graph_ref to graph
   410       copyGraph(graph, graph_ref)
   411 	.edgeMap(capacity, _capacity)
   412 	.edgeMap(cost, _cost)
   413 	.nodeRef(node_ref)
   414 	.edgeRef(edge_ref)
   415 	.run();
   416       supply[node_ref[_s]] =  _flow_value;
   417       supply[node_ref[_t]] = -_flow_value;
   418       valid_supply = true;
   419     }
   420 
   421     /// \brief Returns a const reference to the flow map.
   422     ///
   423     /// Returns a const reference to the flow map.
   424     ///
   425     /// \pre \ref run() must be called before using this function.
   426     const FlowMap& flowMap() const {
   427       return flow_result;
   428     }
   429 
   430     /// \brief Returns a const reference to the potential map (the dual
   431     /// solution).
   432     ///
   433     /// Returns a const reference to the potential map (the dual
   434     /// solution).
   435     ///
   436     /// \pre \ref run() must be called before using this function.
   437     const PotentialMap& potentialMap() const {
   438       return potential_result;
   439     }
   440 
   441     /// \brief Returns the total cost of the found flow.
   442     ///
   443     /// Returns the total cost of the found flow. The complexity of the
   444     /// function is \f$ O(e) \f$.
   445     ///
   446     /// \pre \ref run() must be called before using this function.
   447     Cost totalCost() const {
   448       Cost c = 0;
   449       for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e)
   450 	c += flow_result[e] * cost[edge_ref[e]];
   451       return c;
   452     }
   453 
   454     /// \brief Runs the algorithm.
   455     ///
   456     /// Runs the algorithm.
   457     ///
   458     /// \return \c true if a feasible flow can be found.
   459     bool run() {
   460       return init() && start();
   461     }
   462 
   463   protected:
   464 
   465     /// \brief Extends the underlaying graph and initializes all the
   466     /// node and edge maps.
   467     bool init() {
   468       if (!valid_supply) return false;
   469 
   470       // Initializing state and flow maps
   471       for (EdgeIt e(graph); e != INVALID; ++e) {
   472 	flow[e] = 0;
   473 	state[e] = LOWER;
   474       }
   475 
   476       // Adding an artificial root node to the graph
   477       root = graph.addNode();
   478       parent[root] = INVALID;
   479       pred_edge[root] = INVALID;
   480       depth[root] = supply[root] = potential[root] = 0;
   481 
   482       // Adding artificial edges to the graph and initializing the node
   483       // maps of the spanning tree data structure
   484       Supply sum = 0;
   485       Node last = root;
   486       Edge e;
   487       Cost max_cost = std::numeric_limits<Cost>::max() / 4;
   488       for (NodeIt u(graph); u != INVALID; ++u) {
   489 	if (u == root) continue;
   490 	thread[last] = u;
   491 	last = u;
   492 	parent[u] = root;
   493 	depth[u] = 1;
   494 	sum += supply[u];
   495 	if (supply[u] >= 0) {
   496 	  e = graph.addEdge(u, root);
   497 	  flow[e] = supply[u];
   498 	  forward[u] = true;
   499 	  potential[u] = max_cost;
   500 	} else {
   501 	  e = graph.addEdge(root, u);
   502 	  flow[e] = -supply[u];
   503 	  forward[u] = false;
   504 	  potential[u] = -max_cost;
   505 	}
   506 	cost[e] = max_cost;
   507 	capacity[e] = std::numeric_limits<Capacity>::max();
   508 	state[e] = TREE;
   509 	pred_edge[u] = e;
   510       }
   511       thread[last] = root;
   512 
   513 #ifdef EDGE_BLOCK_PIVOT
   514       // Initializing block_size for the edge block pivot rule
   515       int edge_num = countEdges(graph);
   516       block_size = edge_num > MIN_BOUND ? edge_num / BLOCK_NUM + 1 : 1;
   517 #endif
   518 #ifdef CANDIDATE_LIST_PIVOT
   519       minor_count = 0;
   520 #endif
   521 
   522       return sum == 0;
   523     }
   524 
   525 #ifdef FIRST_ELIGIBLE_PIVOT
   526     /// \brief Finds entering edge according to the "First Eligible"
   527     /// pivot rule.
   528     bool findEnteringEdge(EdgeIt &next_edge) {
   529       for (EdgeIt e = next_edge; e != INVALID; ++e) {
   530 	if (state[e] * red_cost[e] < 0) {
   531 	  in_edge = e;
   532 	  next_edge = ++e;
   533 	  return true;
   534 	}
   535       }
   536       for (EdgeIt e(graph); e != next_edge; ++e) {
   537 	if (state[e] * red_cost[e] < 0) {
   538 	  in_edge = e;
   539 	  next_edge = ++e;
   540 	  return true;
   541 	}
   542       }
   543       return false;
   544     }
   545 #endif
   546 
   547 #ifdef BEST_ELIGIBLE_PIVOT
   548     /// \brief Finds entering edge according to the "Best Eligible"
   549     /// pivot rule.
   550     bool findEnteringEdge() {
   551       Cost min = 0;
   552       for (EdgeIt e(graph); e != INVALID; ++e) {
   553 	if (state[e] * red_cost[e] < min) {
   554 	  min = state[e] * red_cost[e];
   555 	  in_edge = e;
   556 	}
   557       }
   558       return min < 0;
   559     }
   560 #endif
   561 
   562 #ifdef EDGE_BLOCK_PIVOT
   563     /// \brief Finds entering edge according to the "Edge Block"
   564     /// pivot rule.
   565     bool findEnteringEdge(EdgeIt &next_edge) {
   566       if (block_size == 1) {
   567 	// Performing first eligible selection
   568 	for (EdgeIt e = next_edge; e != INVALID; ++e) {
   569 	  if (state[e] * red_cost[e] < 0) {
   570 	    in_edge = e;
   571 	    next_edge = ++e;
   572 	    return true;
   573 	  }
   574 	}
   575 	for (EdgeIt e(graph); e != next_edge; ++e) {
   576 	  if (state[e] * red_cost[e] < 0) {
   577 	    in_edge = e;
   578 	    next_edge = ++e;
   579 	    return true;
   580 	  }
   581 	}
   582 	return false;
   583       } else {
   584 	// Performing edge block selection
   585 	Cost curr, min = 0;
   586 	EdgeIt min_edge(graph);
   587 	int cnt = 0;
   588 	for (EdgeIt e = next_edge; e != INVALID; ++e) {
   589 	  if ((curr = state[e] * red_cost[e]) < min) {
   590 	    min = curr;
   591 	    min_edge = e;
   592 	  }
   593 	  if (++cnt == block_size) {
   594 	    if (min < 0) break;
   595 	    cnt = 0;
   596 	  }
   597 	}
   598 	if (!(min < 0)) {
   599 	  for (EdgeIt e(graph); e != next_edge; ++e) {
   600 	    if ((curr = state[e] * red_cost[e]) < min) {
   601 	      min = curr;
   602 	      min_edge = e;
   603 	    }
   604 	    if (++cnt == block_size) {
   605 	      if (min < 0) break;
   606 	      cnt = 0;
   607 	    }
   608 	  }
   609 	}
   610 	in_edge = min_edge;
   611 	if ((next_edge = ++min_edge) == INVALID)
   612 	  next_edge = EdgeIt(graph);
   613 	return min < 0;
   614       }
   615     }
   616 #endif
   617 
   618 #ifdef CANDIDATE_LIST_PIVOT
   619     /// \brief Functor class for removing non-eligible edges from the
   620     /// candidate list.
   621     class RemoveFunc
   622     {
   623     private:
   624       const IntEdgeMap &st;
   625       const ReducedCostMap &rc;
   626     public:
   627       RemoveFunc(const IntEdgeMap &_st, const ReducedCostMap &_rc) :
   628 	st(_st), rc(_rc) {}
   629       bool operator()(const Edge &e) {
   630 	return st[e] * rc[e] >= 0;
   631       }
   632     };
   633 
   634     /// \brief Finds entering edge according to the "Candidate List"
   635     /// pivot rule.
   636     bool findEnteringEdge() {
   637       static RemoveFunc remove_func(state, red_cost);
   638       typedef typename std::list<Edge>::iterator ListIt;
   639 
   640       candidates.remove_if(remove_func);
   641       if (minor_count >= MINOR_LIMIT || candidates.size() == 0) {
   642 	// Major iteration
   643 	for (EdgeIt e(graph); e != INVALID; ++e) {
   644 	  if (state[e] * red_cost[e] < 0) {
   645 	    candidates.push_back(e);
   646 	    if (candidates.size() == LIST_LENGTH) break;
   647 	  }
   648 	}
   649 	if (candidates.size() == 0) return false;
   650       }
   651 
   652       // Minor iteration
   653       ++minor_count;
   654       Cost min = 0;
   655       for (ListIt it = candidates.begin(); it != candidates.end(); ++it) {
   656 	if (state[*it] * red_cost[*it] < min) {
   657 	  min = state[*it] * red_cost[*it];
   658 	  in_edge = *it;
   659 	}
   660       }
   661       return true;
   662     }
   663 #endif
   664 
   665 #ifdef SORTED_LIST_PIVOT
   666     /// \brief Functor class to compare edges during sort of the
   667     /// candidate list.
   668     class SortFunc
   669     {
   670     private:
   671       const IntEdgeMap &st;
   672       const ReducedCostMap &rc;
   673     public:
   674       SortFunc(const IntEdgeMap &_st, const ReducedCostMap &_rc) :
   675 	st(_st), rc(_rc) {}
   676       bool operator()(const Edge &e1, const Edge &e2) {
   677 	return st[e1] * rc[e1] < st[e2] * rc[e2];
   678       }
   679     };
   680 
   681     /// \brief Finds entering edge according to the "Sorted List"
   682     /// pivot rule.
   683     bool findEnteringEdge() {
   684       static SortFunc sort_func(state, red_cost);
   685 
   686       // Minor iteration
   687       while (candidates.size() > 0) {
   688 	in_edge = candidates.front();
   689 	candidates.pop_front();
   690 	if (state[in_edge] * red_cost[in_edge] < 0) return true;
   691       }
   692 
   693       // Major iteration
   694       Cost curr, min = 0;
   695       for (EdgeIt e(graph); e != INVALID; ++e) {
   696 	if ((curr = state[e] * red_cost[e]) < min / LOWER_DIV) {
   697 	  candidates.push_back(e);
   698 	  if (curr < min) min = curr;
   699 	  if (candidates.size() >= LIST_LENGTH) break;
   700 	}
   701       }
   702       if (candidates.size() == 0) return false;
   703       sort(candidates.begin(), candidates.end(), sort_func);
   704       return true;
   705     }
   706 #endif
   707 
   708     /// \brief Finds the join node.
   709     Node findJoinNode() {
   710       // Finding the join node
   711       Node u = graph.source(in_edge);
   712       Node v = graph.target(in_edge);
   713       while (u != v) {
   714 	if (depth[u] == depth[v]) {
   715 	  u = parent[u];
   716 	  v = parent[v];
   717 	}
   718 	else if (depth[u] > depth[v]) u = parent[u];
   719 	else v = parent[v];
   720       }
   721       return u;
   722     }
   723 
   724     /// \brief Finds the leaving edge of the cycle. Returns \c true if
   725     /// the leaving edge is not the same as the entering edge.
   726     bool findLeavingEdge() {
   727       // Initializing first and second nodes according to the direction
   728       // of the cycle
   729       if (state[in_edge] == LOWER) {
   730 	first = graph.source(in_edge);
   731 	second	= graph.target(in_edge);
   732       } else {
   733 	first = graph.target(in_edge);
   734 	second	= graph.source(in_edge);
   735       }
   736       delta = capacity[in_edge];
   737       bool result = false;
   738       Capacity d;
   739       Edge e;
   740 
   741       // Searching the cycle along the path form the first node to the
   742       // root node
   743       for (Node u = first; u != join; u = parent[u]) {
   744 	e = pred_edge[u];
   745 	d = forward[u] ? flow[e] : capacity[e] - flow[e];
   746 	if (d < delta) {
   747 	  delta = d;
   748 	  u_out = u;
   749 	  u_in = first;
   750 	  v_in = second;
   751 	  result = true;
   752 	}
   753       }
   754       // Searching the cycle along the path form the second node to the
   755       // root node
   756       for (Node u = second; u != join; u = parent[u]) {
   757 	e = pred_edge[u];
   758 	d = forward[u] ? capacity[e] - flow[e] : flow[e];
   759 	if (d <= delta) {
   760 	  delta = d;
   761 	  u_out = u;
   762 	  u_in = second;
   763 	  v_in = first;
   764 	  result = true;
   765 	}
   766       }
   767       return result;
   768     }
   769 
   770     /// \brief Changes flow and state edge maps.
   771     void changeFlows(bool change) {
   772       // Augmenting along the cycle
   773       if (delta > 0) {
   774 	Capacity val = state[in_edge] * delta;
   775 	flow[in_edge] += val;
   776 	for (Node u = graph.source(in_edge); u != join; u = parent[u]) {
   777 	  flow[pred_edge[u]] += forward[u] ? -val : val;
   778 	}
   779 	for (Node u = graph.target(in_edge); u != join; u = parent[u]) {
   780 	  flow[pred_edge[u]] += forward[u] ? val : -val;
   781 	}
   782       }
   783       // Updating the state of the entering and leaving edges
   784       if (change) {
   785 	state[in_edge] = TREE;
   786 	state[pred_edge[u_out]] =
   787 	  (flow[pred_edge[u_out]] == 0) ? LOWER : UPPER;
   788       } else {
   789 	state[in_edge] = -state[in_edge];
   790       }
   791     }
   792 
   793     /// \brief Updates thread and parent node maps.
   794     void updateThreadParent() {
   795       Node u;
   796       v_out = parent[u_out];
   797 
   798       // Handling the case when join and v_out coincide
   799       bool par_first = false;
   800       if (join == v_out) {
   801 	for (u = join; u != u_in && u != v_in; u = thread[u]) ;
   802 	if (u == v_in) {
   803 	  par_first = true;
   804 	  while (thread[u] != u_out) u = thread[u];
   805 	  first = u;
   806 	}
   807       }
   808 
   809       // Finding the last successor of u_in (u) and the node after it
   810       // (right) according to the thread index
   811       for (u = u_in; depth[thread[u]] > depth[u_in]; u = thread[u]) ;
   812       right = thread[u];
   813       if (thread[v_in] == u_out) {
   814 	for (last = u; depth[last] > depth[u_out]; last = thread[last]) ;
   815 	if (last == u_out) last = thread[last];
   816       }
   817       else last = thread[v_in];
   818 
   819       // Updating stem nodes
   820       thread[v_in] = stem = u_in;
   821       par_stem = v_in;
   822       while (stem != u_out) {
   823 	thread[u] = new_stem = parent[stem];
   824 
   825 	// Finding the node just before the stem node (u) according to
   826 	// the original thread index
   827 	for (u = new_stem; thread[u] != stem; u = thread[u]) ;
   828 	thread[u] = right;
   829 
   830 	// Changing the parent node of stem and shifting stem and
   831 	// par_stem nodes
   832 	parent[stem] = par_stem;
   833 	par_stem = stem;
   834 	stem = new_stem;
   835 
   836 	// Finding the last successor of stem (u) and the node after it
   837 	// (right) according to the thread index
   838 	for (u = stem; depth[thread[u]] > depth[stem]; u = thread[u]) ;
   839 	right = thread[u];
   840       }
   841       parent[u_out] = par_stem;
   842       thread[u] = last;
   843 
   844       if (join == v_out && par_first) {
   845 	if (first != v_in) thread[first] = right;
   846       } else {
   847 	for (u = v_out; thread[u] != u_out; u = thread[u]) ;
   848 	thread[u] = right;
   849       }
   850     }
   851 
   852     /// \brief Updates pred_edge and forward node maps.
   853     void updatePredEdge() {
   854       Node u = u_out, v;
   855       while (u != u_in) {
   856 	v = parent[u];
   857 	pred_edge[u] = pred_edge[v];
   858 	forward[u] = !forward[v];
   859 	u = v;
   860       }
   861       pred_edge[u_in] = in_edge;
   862       forward[u_in] = (u_in == graph.source(in_edge));
   863     }
   864 
   865     /// \brief Updates depth and potential node maps.
   866     void updateDepthPotential() {
   867       depth[u_in] = depth[v_in] + 1;
   868       potential[u_in] = forward[u_in] ?
   869 	potential[v_in] + cost[pred_edge[u_in]] :
   870 	potential[v_in] - cost[pred_edge[u_in]];
   871 
   872       Node u = thread[u_in], v;
   873       while (true) {
   874 	v = parent[u];
   875 	if (v == INVALID) break;
   876 	depth[u] = depth[v] + 1;
   877 	potential[u] = forward[u] ?
   878 	  potential[v] + cost[pred_edge[u]] :
   879 	  potential[v] - cost[pred_edge[u]];
   880 	if (depth[u] <= depth[v_in]) break;
   881 	u = thread[u];
   882       }
   883     }
   884 
   885     /// \brief Executes the algorithm.
   886     bool start() {
   887       // Processing pivots
   888 #ifdef _DEBUG_ITER_
   889       int iter_num = 0;
   890 #endif
   891 #if defined(FIRST_ELIGIBLE_PIVOT) || defined(EDGE_BLOCK_PIVOT)
   892       EdgeIt next_edge(graph);
   893       while (findEnteringEdge(next_edge))
   894 #else
   895       while (findEnteringEdge())
   896 #endif
   897       {
   898 	join = findJoinNode();
   899 	bool change = findLeavingEdge();
   900 	changeFlows(change);
   901 	if (change) {
   902 	  updateThreadParent();
   903 	  updatePredEdge();
   904 	  updateDepthPotential();
   905 	}
   906 #ifdef _DEBUG_ITER_
   907 	++iter_num;
   908 #endif
   909       }
   910 
   911 #ifdef _DEBUG_ITER_
   912       t_iter.stop();
   913       std::cout << "Network Simplex algorithm finished. " << iter_num
   914 		<< " pivot iterations performed.";
   915 #endif
   916 
   917       // Checking if the flow amount equals zero on all the
   918       // artificial edges
   919       for (InEdgeIt e(graph, root); e != INVALID; ++e)
   920 	if (flow[e] > 0) return false;
   921       for (OutEdgeIt e(graph, root); e != INVALID; ++e)
   922 	if (flow[e] > 0) return false;
   923 
   924       // Copying flow values to flow_result
   925       if (lower) {
   926 	for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e)
   927 	  flow_result[e] = (*lower)[e] + flow[edge_ref[e]];
   928       } else {
   929 	for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e)
   930 	  flow_result[e] = flow[edge_ref[e]];
   931       }
   932       // Copying potential values to potential_result
   933       for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n)
   934 	potential_result[n] = potential[node_ref[n]];
   935 
   936       return true;
   937     }
   938 
   939   }; //class NetworkSimplex
   940 
   941   ///@}
   942 
   943 } //namespace lemon
   944 
   945 #endif //LEMON_NETWORK_SIMPLEX_H