lemon/cost_scaling.h
changeset 2625 c51b320bc51c
parent 2623 90defb96ee61
child 2629 84354c78b068
equal deleted inserted replaced
4:42fe7654f163 5:64c49446f513
    18 
    18 
    19 #ifndef LEMON_COST_SCALING_H
    19 #ifndef LEMON_COST_SCALING_H
    20 #define LEMON_COST_SCALING_H
    20 #define LEMON_COST_SCALING_H
    21 
    21 
    22 /// \ingroup min_cost_flow
    22 /// \ingroup min_cost_flow
    23 ///
       
    24 /// \file
    23 /// \file
    25 /// \brief Cost scaling algorithm for finding a minimum cost flow.
    24 /// \brief Cost scaling algorithm for finding a minimum cost flow.
    26 
    25 
    27 #include <deque>
    26 #include <deque>
    28 #include <lemon/graph_adaptor.h>
    27 #include <lemon/graph_adaptor.h>
    40 
    39 
    41   /// \brief Implementation of the cost scaling algorithm for finding a
    40   /// \brief Implementation of the cost scaling algorithm for finding a
    42   /// minimum cost flow.
    41   /// minimum cost flow.
    43   ///
    42   ///
    44   /// \ref CostScaling implements the cost scaling algorithm performing
    43   /// \ref CostScaling implements the cost scaling algorithm performing
    45   /// generalized push-relabel operations for finding a minimum cost
    44   /// augment/push and relabel operations for finding a minimum cost
    46   /// flow.
    45   /// flow.
    47   ///
    46   ///
    48   /// \tparam Graph The directed graph type the algorithm runs on.
    47   /// \tparam Graph The directed graph type the algorithm runs on.
    49   /// \tparam LowerMap The type of the lower bound map.
    48   /// \tparam LowerMap The type of the lower bound map.
    50   /// \tparam CapacityMap The type of the capacity (upper bound) map.
    49   /// \tparam CapacityMap The type of the capacity (upper bound) map.
   114       ///\e
   113       ///\e
   115       ResidualCostMap(const Map &cost_map) :
   114       ResidualCostMap(const Map &cost_map) :
   116         _cost_map(cost_map) {}
   115         _cost_map(cost_map) {}
   117 
   116 
   118       ///\e
   117       ///\e
   119       typename Map::Value operator[](const ResEdge &e) const {
   118       inline typename Map::Value operator[](const ResEdge &e) const {
   120         return ResGraph::forward(e) ?  _cost_map[e] : -_cost_map[e];
   119         return ResGraph::forward(e) ? _cost_map[e] : -_cost_map[e];
   121       }
   120       }
   122 
   121 
   123     }; //class ResidualCostMap
   122     }; //class ResidualCostMap
   124 
   123 
   125     /// \brief Map adaptor class for handling reduced edge costs.
   124     /// \brief Map adaptor class for handling reduced edge costs.
   140                       const LargeCostMap &cost_map,
   139                       const LargeCostMap &cost_map,
   141                       const PotentialMap &pot_map ) :
   140                       const PotentialMap &pot_map ) :
   142         _gr(gr), _cost_map(cost_map), _pot_map(pot_map) {}
   141         _gr(gr), _cost_map(cost_map), _pot_map(pot_map) {}
   143 
   142 
   144       ///\e
   143       ///\e
   145       LCost operator[](const Edge &e) const {
   144       inline LCost operator[](const Edge &e) const {
   146         return _cost_map[e] + _pot_map[_gr.source(e)]
   145         return _cost_map[e] + _pot_map[_gr.source(e)]
   147                             - _pot_map[_gr.target(e)];
   146                             - _pot_map[_gr.target(e)];
   148       }
   147       }
   149 
   148 
   150     }; //class ReducedCostMap
   149     }; //class ReducedCostMap
   151 
       
   152   private:
       
   153 
       
   154     // Scaling factor
       
   155     static const int ALPHA = 4;
       
   156 
       
   157     // Paramters for heuristics
       
   158     static const int BF_HEURISTIC_EPSILON_BOUND = 5000;
       
   159     static const int BF_HEURISTIC_BOUND_FACTOR  = 3;
       
   160 
   150 
   161   private:
   151   private:
   162 
   152 
   163     // The directed graph the algorithm runs on
   153     // The directed graph the algorithm runs on
   164     const Graph &_graph;
   154     const Graph &_graph;
   189     ReducedCostMap *_red_cost;
   179     ReducedCostMap *_red_cost;
   190     // The excess map
   180     // The excess map
   191     SupplyNodeMap _excess;
   181     SupplyNodeMap _excess;
   192     // The epsilon parameter used for cost scaling
   182     // The epsilon parameter used for cost scaling
   193     LCost _epsilon;
   183     LCost _epsilon;
       
   184     // The scaling factor
       
   185     int _alpha;
   194 
   186 
   195   public:
   187   public:
   196 
   188 
   197     /// \brief General constructor (with lower bounds).
   189     /// \brief General constructor (with lower bounds).
   198     ///
   190     ///
   211       _graph(graph), _lower(&lower), _capacity(graph), _orig_cost(cost),
   203       _graph(graph), _lower(&lower), _capacity(graph), _orig_cost(cost),
   212       _cost(graph), _supply(graph), _flow(NULL), _local_flow(false),
   204       _cost(graph), _supply(graph), _flow(NULL), _local_flow(false),
   213       _potential(NULL), _local_potential(false), _res_cost(_cost),
   205       _potential(NULL), _local_potential(false), _res_cost(_cost),
   214       _res_graph(NULL), _red_cost(NULL), _excess(graph, 0)
   206       _res_graph(NULL), _red_cost(NULL), _excess(graph, 0)
   215     {
   207     {
   216       // Removing non-zero lower bounds
   208       // Remove non-zero lower bounds
   217       _capacity = subMap(capacity, lower);
   209       _capacity = subMap(capacity, lower);
   218       Supply sum = 0;
   210       Supply sum = 0;
   219       for (NodeIt n(_graph); n != INVALID; ++n) {
   211       for (NodeIt n(_graph); n != INVALID; ++n) {
   220         Supply s = supply[n];
   212         Supply s = supply[n];
   221         for (InEdgeIt e(_graph, n); e != INVALID; ++e)
   213         for (InEdgeIt e(_graph, n); e != INVALID; ++e)
   243       _graph(graph), _lower(NULL), _capacity(capacity), _orig_cost(cost),
   235       _graph(graph), _lower(NULL), _capacity(capacity), _orig_cost(cost),
   244       _cost(graph), _supply(supply), _flow(NULL), _local_flow(false),
   236       _cost(graph), _supply(supply), _flow(NULL), _local_flow(false),
   245       _potential(NULL), _local_potential(false), _res_cost(_cost),
   237       _potential(NULL), _local_potential(false), _res_cost(_cost),
   246       _res_graph(NULL), _red_cost(NULL), _excess(graph, 0)
   238       _res_graph(NULL), _red_cost(NULL), _excess(graph, 0)
   247     {
   239     {
   248       // Checking the sum of supply values
   240       // Check the sum of supply values
   249       Supply sum = 0;
   241       Supply sum = 0;
   250       for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
   242       for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
   251       _valid_supply = sum == 0;
   243       _valid_supply = sum == 0;
   252     }
   244     }
   253 
   245 
   272       _graph(graph), _lower(&lower), _capacity(graph), _orig_cost(cost),
   264       _graph(graph), _lower(&lower), _capacity(graph), _orig_cost(cost),
   273       _cost(graph), _supply(graph), _flow(NULL), _local_flow(false),
   265       _cost(graph), _supply(graph), _flow(NULL), _local_flow(false),
   274       _potential(NULL), _local_potential(false), _res_cost(_cost),
   266       _potential(NULL), _local_potential(false), _res_cost(_cost),
   275       _res_graph(NULL), _red_cost(NULL), _excess(graph, 0)
   267       _res_graph(NULL), _red_cost(NULL), _excess(graph, 0)
   276     {
   268     {
   277       // Removing nonzero lower bounds
   269       // Remove nonzero lower bounds
   278       _capacity = subMap(capacity, lower);
   270       _capacity = subMap(capacity, lower);
   279       for (NodeIt n(_graph); n != INVALID; ++n) {
   271       for (NodeIt n(_graph); n != INVALID; ++n) {
   280         Supply sum = 0;
   272         Supply sum = 0;
   281         if (n == s) sum =  flow_value;
   273         if (n == s) sum =  flow_value;
   282         if (n == t) sum = -flow_value;
   274         if (n == t) sum = -flow_value;
   357 
   349 
   358     /// \brief Run the algorithm.
   350     /// \brief Run the algorithm.
   359     ///
   351     ///
   360     /// Run the algorithm.
   352     /// Run the algorithm.
   361     ///
   353     ///
       
   354     /// \param partial_augment By default the algorithm performs
       
   355     /// partial augment and relabel operations in the cost scaling
       
   356     /// phases. Set this parameter to \c false for using local push and
       
   357     /// relabel operations instead.
       
   358     ///
   362     /// \return \c true if a feasible flow can be found.
   359     /// \return \c true if a feasible flow can be found.
   363     bool run() {
   360     bool run(bool partial_augment = true) {
   364       return init() && start();
   361       if (partial_augment) {
       
   362         return init() && startPartialAugment();
       
   363       } else {
       
   364         return init() && startPushRelabel();
       
   365       }
   365     }
   366     }
   366 
   367 
   367     /// @}
   368     /// @}
   368 
   369 
   369     /// \name Query Functions
   370     /// \name Query Functions
   431   private:
   432   private:
   432 
   433 
   433     /// Initialize the algorithm.
   434     /// Initialize the algorithm.
   434     bool init() {
   435     bool init() {
   435       if (!_valid_supply) return false;
   436       if (!_valid_supply) return false;
   436 
   437       // The scaling factor
   437       // Initializing flow and potential maps
   438       _alpha = 8;
       
   439 
       
   440       // Initialize flow and potential maps
   438       if (!_flow) {
   441       if (!_flow) {
   439         _flow = new FlowMap(_graph);
   442         _flow = new FlowMap(_graph);
   440         _local_flow = true;
   443         _local_flow = true;
   441       }
   444       }
   442       if (!_potential) {
   445       if (!_potential) {
   445       }
   448       }
   446 
   449 
   447       _red_cost = new ReducedCostMap(_graph, _cost, *_potential);
   450       _red_cost = new ReducedCostMap(_graph, _cost, *_potential);
   448       _res_graph = new ResGraph(_graph, _capacity, *_flow);
   451       _res_graph = new ResGraph(_graph, _capacity, *_flow);
   449 
   452 
   450       // Initializing the scaled cost map and the epsilon parameter
   453       // Initialize the scaled cost map and the epsilon parameter
   451       Cost max_cost = 0;
   454       Cost max_cost = 0;
   452       int node_num = countNodes(_graph);
   455       int node_num = countNodes(_graph);
   453       for (EdgeIt e(_graph); e != INVALID; ++e) {
   456       for (EdgeIt e(_graph); e != INVALID; ++e) {
   454         _cost[e] = LCost(_orig_cost[e]) * node_num * ALPHA;
   457         _cost[e] = LCost(_orig_cost[e]) * node_num * _alpha;
   455         if (_orig_cost[e] > max_cost) max_cost = _orig_cost[e];
   458         if (_orig_cost[e] > max_cost) max_cost = _orig_cost[e];
   456       }
   459       }
   457       _epsilon = max_cost * node_num;
   460       _epsilon = max_cost * node_num;
   458 
   461 
   459       // Finding a feasible flow using Circulation
   462       // Find a feasible flow using Circulation
   460       Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap,
   463       Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap,
   461                    SupplyMap >
   464                    SupplyMap >
   462         circulation( _graph, constMap<Edge>(Capacity(0)), _capacity,
   465         circulation( _graph, constMap<Edge>(Capacity(0)), _capacity,
   463                      _supply );
   466                      _supply );
   464       return circulation.flowMap(*_flow).run();
   467       return circulation.flowMap(*_flow).run();
   465     }
   468     }
   466 
   469 
   467 
   470     /// Execute the algorithm performing partial augmentation and
   468     /// Execute the algorithm.
   471     /// relabel operations.
   469     bool start() {
   472     bool startPartialAugment() {
       
   473       // Paramters for heuristics
       
   474       const int BF_HEURISTIC_EPSILON_BOUND = 1000;
       
   475       const int BF_HEURISTIC_BOUND_FACTOR  = 3;
       
   476       // Maximum augment path length
       
   477       const int MAX_PATH_LENGTH = 4;
       
   478 
       
   479       // Variables
       
   480       typename Graph::template NodeMap<Edge> pred_edge(_graph);
       
   481       typename Graph::template NodeMap<bool> forward(_graph);
       
   482       typename Graph::template NodeMap<OutEdgeIt> next_out(_graph);
       
   483       typename Graph::template NodeMap<InEdgeIt> next_in(_graph);
       
   484       typename Graph::template NodeMap<bool> next_dir(_graph);
   470       std::deque<Node> active_nodes;
   485       std::deque<Node> active_nodes;
   471       typename Graph::template NodeMap<bool> hyper(_graph, false);
   486       std::vector<Node> path_nodes;
   472 
   487 
   473       int node_num = countNodes(_graph);
   488       int node_num = countNodes(_graph);
   474       for ( ; _epsilon >= 1; _epsilon = _epsilon < ALPHA && _epsilon > 1 ?
   489       for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
   475                                         1 : _epsilon / ALPHA )
   490                                         1 : _epsilon / _alpha )
   476       {
   491       {
   477         // Performing price refinement heuristic using Bellman-Ford
   492         // "Early Termination" heuristic: use Bellman-Ford algorithm
   478         // algorithm
   493         // to check if the current flow is optimal
   479         if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
   494         if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
   480           typedef ShiftMap< ResidualCostMap<LargeCostMap> > ShiftCostMap;
   495           typedef ShiftMap< ResidualCostMap<LargeCostMap> > ShiftCostMap;
   481           ShiftCostMap shift_cost(_res_cost, _epsilon);
   496           ShiftCostMap shift_cost(_res_cost, 1);
   482           BellmanFord<ResGraph, ShiftCostMap> bf(*_res_graph, shift_cost);
   497           BellmanFord<ResGraph, ShiftCostMap> bf(*_res_graph, shift_cost);
   483           bf.init(0);
   498           bf.init(0);
   484           bool done = false;
   499           bool done = false;
   485           int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(node_num));
   500           int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(node_num));
   486           for (int i = 0; i < K && !done; ++i)
   501           for (int i = 0; i < K && !done; ++i)
   487             done = bf.processNextWeakRound();
   502             done = bf.processNextWeakRound();
   488           if (done) {
   503           if (done) break;
   489             for (NodeIt n(_graph); n != INVALID; ++n)
   504         }
   490               (*_potential)[n] = bf.dist(n);
   505 
   491             continue;
   506         // Saturate edges not satisfying the optimality condition
   492           }
       
   493         }
       
   494 
       
   495         // Saturating edges not satisfying the optimality condition
       
   496         Capacity delta;
   507         Capacity delta;
   497         for (EdgeIt e(_graph); e != INVALID; ++e) {
   508         for (EdgeIt e(_graph); e != INVALID; ++e) {
   498           if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
   509           if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
   499             delta = _capacity[e] - (*_flow)[e];
   510             delta = _capacity[e] - (*_flow)[e];
   500             _excess[_graph.source(e)] -= delta;
   511             _excess[_graph.source(e)] -= delta;
   506             _excess[_graph.source(e)] += (*_flow)[e];
   517             _excess[_graph.source(e)] += (*_flow)[e];
   507             (*_flow)[e] = 0;
   518             (*_flow)[e] = 0;
   508           }
   519           }
   509         }
   520         }
   510 
   521 
   511         // Finding active nodes (i.e. nodes with positive excess)
   522         // Find active nodes (i.e. nodes with positive excess)
   512         for (NodeIt n(_graph); n != INVALID; ++n)
   523         for (NodeIt n(_graph); n != INVALID; ++n) {
   513           if (_excess[n] > 0) active_nodes.push_back(n);
   524           if (_excess[n] > 0) active_nodes.push_back(n);
   514 
   525         }
   515         // Performing push and relabel operations
   526 
       
   527         // Initialize the next edge maps
       
   528         for (NodeIt n(_graph); n != INVALID; ++n) {
       
   529           next_out[n] = OutEdgeIt(_graph, n);
       
   530           next_in[n] = InEdgeIt(_graph, n);
       
   531           next_dir[n] = true;
       
   532         }
       
   533 
       
   534         // Perform partial augment and relabel operations
   516         while (active_nodes.size() > 0) {
   535         while (active_nodes.size() > 0) {
       
   536           // Select an active node (FIFO selection)
       
   537           if (_excess[active_nodes[0]] <= 0) {
       
   538             active_nodes.pop_front();
       
   539             continue;
       
   540           }
       
   541           Node start = active_nodes[0];
       
   542           path_nodes.clear();
       
   543           path_nodes.push_back(start);
       
   544 
       
   545           // Find an augmenting path from the start node
       
   546           Node u, tip = start;
       
   547           LCost min_red_cost;
       
   548           while ( _excess[tip] >= 0 &&
       
   549                   int(path_nodes.size()) <= MAX_PATH_LENGTH )
       
   550           {
       
   551             if (next_dir[tip]) {
       
   552               for (OutEdgeIt e = next_out[tip]; e != INVALID; ++e) {
       
   553                 if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
       
   554                   u = _graph.target(e);
       
   555                   pred_edge[u] = e;
       
   556                   forward[u] = true;
       
   557                   next_out[tip] = e;
       
   558                   tip = u;
       
   559                   path_nodes.push_back(tip);
       
   560                   goto next_step;
       
   561                 }
       
   562               }
       
   563               next_dir[tip] = false;
       
   564             }
       
   565             for (InEdgeIt e = next_in[tip]; e != INVALID; ++e) {
       
   566               if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
       
   567                 u = _graph.source(e);
       
   568                 pred_edge[u] = e;
       
   569                 forward[u] = false;
       
   570                 next_in[tip] = e;
       
   571                 tip = u;
       
   572                 path_nodes.push_back(tip);
       
   573                 goto next_step;
       
   574               }
       
   575             }
       
   576 
       
   577             // Relabel tip node
       
   578             min_red_cost = std::numeric_limits<LCost>::max() / 2;
       
   579             for (OutEdgeIt oe(_graph, tip); oe != INVALID; ++oe) {
       
   580               if ( _capacity[oe] - (*_flow)[oe] > 0 &&
       
   581                    (*_red_cost)[oe] < min_red_cost )
       
   582                 min_red_cost = (*_red_cost)[oe];
       
   583             }
       
   584             for (InEdgeIt ie(_graph, tip); ie != INVALID; ++ie) {
       
   585               if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < min_red_cost)
       
   586                 min_red_cost = -(*_red_cost)[ie];
       
   587             }
       
   588             (*_potential)[tip] -= min_red_cost + _epsilon;
       
   589 
       
   590             // Reset the next edge maps
       
   591             next_out[tip] = OutEdgeIt(_graph, tip);
       
   592             next_in[tip] = InEdgeIt(_graph, tip);
       
   593             next_dir[tip] = true;
       
   594 
       
   595             // Step back
       
   596             if (tip != start) {
       
   597               path_nodes.pop_back();
       
   598               tip = path_nodes[path_nodes.size()-1];
       
   599             }
       
   600 
       
   601           next_step:
       
   602             continue;
       
   603           }
       
   604 
       
   605           // Augment along the found path (as much flow as possible)
       
   606           Capacity delta;
       
   607           for (int i = 1; i < int(path_nodes.size()); ++i) {
       
   608             u = path_nodes[i];
       
   609             delta = forward[u] ?
       
   610               _capacity[pred_edge[u]] - (*_flow)[pred_edge[u]] :
       
   611               (*_flow)[pred_edge[u]];
       
   612             delta = std::min(delta, _excess[path_nodes[i-1]]);
       
   613             (*_flow)[pred_edge[u]] += forward[u] ? delta : -delta;
       
   614             _excess[path_nodes[i-1]] -= delta;
       
   615             _excess[u] += delta;
       
   616             if (_excess[u] > 0 && _excess[u] <= delta) active_nodes.push_back(u);
       
   617           }
       
   618         }
       
   619       }
       
   620 
       
   621       // Compute node potentials for the original costs
       
   622       ResidualCostMap<CostMap> res_cost(_orig_cost);
       
   623       BellmanFord< ResGraph, ResidualCostMap<CostMap> >
       
   624         bf(*_res_graph, res_cost);
       
   625       bf.init(0); bf.start();
       
   626       for (NodeIt n(_graph); n != INVALID; ++n)
       
   627         (*_potential)[n] = bf.dist(n);
       
   628 
       
   629       // Handle non-zero lower bounds
       
   630       if (_lower) {
       
   631         for (EdgeIt e(_graph); e != INVALID; ++e)
       
   632           (*_flow)[e] += (*_lower)[e];
       
   633       }
       
   634       return true;
       
   635     }
       
   636 
       
   637     /// Execute the algorithm performing push and relabel operations.
       
   638     bool startPushRelabel() {
       
   639       // Paramters for heuristics
       
   640       const int BF_HEURISTIC_EPSILON_BOUND = 1000;
       
   641       const int BF_HEURISTIC_BOUND_FACTOR  = 3;
       
   642 
       
   643       typename Graph::template NodeMap<bool> hyper(_graph, false);
       
   644       typename Graph::template NodeMap<Edge> pred_edge(_graph);
       
   645       typename Graph::template NodeMap<bool> forward(_graph);
       
   646       typename Graph::template NodeMap<OutEdgeIt> next_out(_graph);
       
   647       typename Graph::template NodeMap<InEdgeIt> next_in(_graph);
       
   648       typename Graph::template NodeMap<bool> next_dir(_graph);
       
   649       std::deque<Node> active_nodes;
       
   650 
       
   651       int node_num = countNodes(_graph);
       
   652       for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
       
   653                                         1 : _epsilon / _alpha )
       
   654       {
       
   655         // "Early Termination" heuristic: use Bellman-Ford algorithm
       
   656         // to check if the current flow is optimal
       
   657         if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
       
   658           typedef ShiftMap< ResidualCostMap<LargeCostMap> > ShiftCostMap;
       
   659           ShiftCostMap shift_cost(_res_cost, 1);
       
   660           BellmanFord<ResGraph, ShiftCostMap> bf(*_res_graph, shift_cost);
       
   661           bf.init(0);
       
   662           bool done = false;
       
   663           int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(node_num));
       
   664           for (int i = 0; i < K && !done; ++i)
       
   665             done = bf.processNextWeakRound();
       
   666           if (done) break;
       
   667         }
       
   668 
       
   669         // Saturate edges not satisfying the optimality condition
       
   670         Capacity delta;
       
   671         for (EdgeIt e(_graph); e != INVALID; ++e) {
       
   672           if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
       
   673             delta = _capacity[e] - (*_flow)[e];
       
   674             _excess[_graph.source(e)] -= delta;
       
   675             _excess[_graph.target(e)] += delta;
       
   676             (*_flow)[e] = _capacity[e];
       
   677           }
       
   678           if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
       
   679             _excess[_graph.target(e)] -= (*_flow)[e];
       
   680             _excess[_graph.source(e)] += (*_flow)[e];
       
   681             (*_flow)[e] = 0;
       
   682           }
       
   683         }
       
   684 
       
   685         // Find active nodes (i.e. nodes with positive excess)
       
   686         for (NodeIt n(_graph); n != INVALID; ++n) {
       
   687           if (_excess[n] > 0) active_nodes.push_back(n);
       
   688         }
       
   689 
       
   690         // Initialize the next edge maps
       
   691         for (NodeIt n(_graph); n != INVALID; ++n) {
       
   692           next_out[n] = OutEdgeIt(_graph, n);
       
   693           next_in[n] = InEdgeIt(_graph, n);
       
   694           next_dir[n] = true;
       
   695         }
       
   696 
       
   697         // Perform push and relabel operations
       
   698         while (active_nodes.size() > 0) {
       
   699           // Select an active node (FIFO selection)
   517           Node n = active_nodes[0], t;
   700           Node n = active_nodes[0], t;
   518           bool relabel_enabled = true;
   701           bool relabel_enabled = true;
   519 
   702 
   520           // Performing push operations if there are admissible edges
   703           // Perform push operations if there are admissible edges
   521           if (_excess[n] > 0) {
   704           if (_excess[n] > 0 && next_dir[n]) {
   522             for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
   705             OutEdgeIt e = next_out[n];
       
   706             for ( ; e != INVALID; ++e) {
   523               if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
   707               if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
   524                 delta = _capacity[e] - (*_flow)[e] <= _excess[n] ?
   708                 delta = std::min(_capacity[e] - (*_flow)[e], _excess[n]);
   525                         _capacity[e] - (*_flow)[e] : _excess[n];
       
   526                 t = _graph.target(e);
   709                 t = _graph.target(e);
   527 
   710 
   528                 // Push-look-ahead heuristic
   711                 // Push-look-ahead heuristic
   529                 Capacity ahead = -_excess[t];
   712                 Capacity ahead = -_excess[t];
   530                 for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) {
   713                 for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) {
   535                   if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
   718                   if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
   536                     ahead += (*_flow)[ie];
   719                     ahead += (*_flow)[ie];
   537                 }
   720                 }
   538                 if (ahead < 0) ahead = 0;
   721                 if (ahead < 0) ahead = 0;
   539 
   722 
   540                 // Pushing flow along the edge
   723                 // Push flow along the edge
   541                 if (ahead < delta) {
   724                 if (ahead < delta) {
   542                   (*_flow)[e] += ahead;
   725                   (*_flow)[e] += ahead;
   543                   _excess[n] -= ahead;
   726                   _excess[n] -= ahead;
   544                   _excess[t] += ahead;
   727                   _excess[t] += ahead;
   545                   active_nodes.push_front(t);
   728                   active_nodes.push_front(t);
   555                 }
   738                 }
   556 
   739 
   557                 if (_excess[n] == 0) break;
   740                 if (_excess[n] == 0) break;
   558               }
   741               }
   559             }
   742             }
   560           }
   743             if (e != INVALID) {
   561 
   744               next_out[n] = e;
   562           if (_excess[n] > 0) {
   745             } else {
   563             for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
   746               next_dir[n] = false;
       
   747             }
       
   748           }
       
   749 
       
   750           if (_excess[n] > 0 && !next_dir[n]) {
       
   751             InEdgeIt e = next_in[n];
       
   752             for ( ; e != INVALID; ++e) {
   564               if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
   753               if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
   565                 delta = (*_flow)[e] <= _excess[n] ? (*_flow)[e] : _excess[n];
   754                 delta = std::min((*_flow)[e], _excess[n]);
   566                 t = _graph.source(e);
   755                 t = _graph.source(e);
   567 
   756 
   568                 // Push-look-ahead heuristic
   757                 // Push-look-ahead heuristic
   569                 Capacity ahead = -_excess[t];
   758                 Capacity ahead = -_excess[t];
   570                 for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) {
   759                 for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) {
   575                   if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
   764                   if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
   576                     ahead += (*_flow)[ie];
   765                     ahead += (*_flow)[ie];
   577                 }
   766                 }
   578                 if (ahead < 0) ahead = 0;
   767                 if (ahead < 0) ahead = 0;
   579 
   768 
   580                 // Pushing flow along the edge
   769                 // Push flow along the edge
   581                 if (ahead < delta) {
   770                 if (ahead < delta) {
   582                   (*_flow)[e] -= ahead;
   771                   (*_flow)[e] -= ahead;
   583                   _excess[n] -= ahead;
   772                   _excess[n] -= ahead;
   584                   _excess[t] += ahead;
   773                   _excess[t] += ahead;
   585                   active_nodes.push_front(t);
   774                   active_nodes.push_front(t);
   595                 }
   784                 }
   596 
   785 
   597                 if (_excess[n] == 0) break;
   786                 if (_excess[n] == 0) break;
   598               }
   787               }
   599             }
   788             }
   600           }
   789             next_in[n] = e;
   601 
   790           }
       
   791 
       
   792           // Relabel the node if it is still active (or hyper)
   602           if (relabel_enabled && (_excess[n] > 0 || hyper[n])) {
   793           if (relabel_enabled && (_excess[n] > 0 || hyper[n])) {
   603             // Performing relabel operation if the node is still active
   794             LCost min_red_cost = std::numeric_limits<LCost>::max() / 2;
   604             LCost min_red_cost = std::numeric_limits<LCost>::max();
       
   605             for (OutEdgeIt oe(_graph, n); oe != INVALID; ++oe) {
   795             for (OutEdgeIt oe(_graph, n); oe != INVALID; ++oe) {
   606               if ( _capacity[oe] - (*_flow)[oe] > 0 &&
   796               if ( _capacity[oe] - (*_flow)[oe] > 0 &&
   607                    (*_red_cost)[oe] < min_red_cost )
   797                    (*_red_cost)[oe] < min_red_cost )
   608                 min_red_cost = (*_red_cost)[oe];
   798                 min_red_cost = (*_red_cost)[oe];
   609             }
   799             }
   611               if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < min_red_cost)
   801               if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < min_red_cost)
   612                 min_red_cost = -(*_red_cost)[ie];
   802                 min_red_cost = -(*_red_cost)[ie];
   613             }
   803             }
   614             (*_potential)[n] -= min_red_cost + _epsilon;
   804             (*_potential)[n] -= min_red_cost + _epsilon;
   615             hyper[n] = false;
   805             hyper[n] = false;
   616           }
   806 
   617 
   807             // Reset the next edge maps
   618           // Removing active nodes with non-positive excess
   808             next_out[n] = OutEdgeIt(_graph, n);
       
   809             next_in[n] = InEdgeIt(_graph, n);
       
   810             next_dir[n] = true;
       
   811           }
       
   812 
       
   813           // Remove nodes that are not active nor hyper
   619           while ( active_nodes.size() > 0 &&
   814           while ( active_nodes.size() > 0 &&
   620                   _excess[active_nodes[0]] <= 0 &&
   815                   _excess[active_nodes[0]] <= 0 &&
   621                   !hyper[active_nodes[0]] ) {
   816                   !hyper[active_nodes[0]] ) {
   622             active_nodes.pop_front();
   817             active_nodes.pop_front();
   623           }
   818           }
   624         }
   819         }
   625       }
   820       }
   626 
   821 
   627       // Computing node potentials for the original costs
   822       // Compute node potentials for the original costs
   628       ResidualCostMap<CostMap> res_cost(_orig_cost);
   823       ResidualCostMap<CostMap> res_cost(_orig_cost);
   629       BellmanFord< ResGraph, ResidualCostMap<CostMap> >
   824       BellmanFord< ResGraph, ResidualCostMap<CostMap> >
   630         bf(*_res_graph, res_cost);
   825         bf(*_res_graph, res_cost);
   631       bf.init(0); bf.start();
   826       bf.init(0); bf.start();
   632       for (NodeIt n(_graph); n != INVALID; ++n)
   827       for (NodeIt n(_graph); n != INVALID; ++n)
   633         (*_potential)[n] = bf.dist(n);
   828         (*_potential)[n] = bf.dist(n);
   634 
   829 
   635       // Handling non-zero lower bounds
   830       // Handle non-zero lower bounds
   636       if (_lower) {
   831       if (_lower) {
   637         for (EdgeIt e(_graph); e != INVALID; ++e)
   832         for (EdgeIt e(_graph); e != INVALID; ++e)
   638           (*_flow)[e] += (*_lower)[e];
   833           (*_flow)[e] += (*_lower)[e];
   639       }
   834       }
   640       return true;
   835       return true;