lemon/network_simplex.h
changeset 2442 27b7c7de9cac
child 2444 06f3702bf18d
equal deleted inserted replaced
-1:000000000000 0:7ef6c97ad0ab
       
     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