3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
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.
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
19 #ifndef LEMON_COST_SCALING_H
20 #define LEMON_COST_SCALING_H
22 /// \ingroup min_cost_flow
24 /// \brief Cost scaling algorithm for finding a minimum cost flow.
27 #include <lemon/graph_adaptor.h>
28 #include <lemon/graph_utils.h>
29 #include <lemon/maps.h>
30 #include <lemon/math.h>
32 #include <lemon/circulation.h>
33 #include <lemon/bellman_ford.h>
37 /// \addtogroup min_cost_flow
40 /// \brief Implementation of the cost scaling algorithm for finding a
41 /// minimum cost flow.
43 /// \ref CostScaling implements the cost scaling algorithm performing
44 /// augment/push and relabel operations for finding a minimum cost
47 /// \tparam Graph The directed graph type the algorithm runs on.
48 /// \tparam LowerMap The type of the lower bound map.
49 /// \tparam CapacityMap The type of the capacity (upper bound) map.
50 /// \tparam CostMap The type of the cost (length) map.
51 /// \tparam SupplyMap The type of the supply map.
54 /// - Edge capacities and costs should be \e non-negative \e integers.
55 /// - Supply values should be \e signed \e integers.
56 /// - The value types of the maps should be convertible to each other.
57 /// - \c CostMap::Value must be signed type.
59 /// \note Edge costs are multiplied with the number of nodes during
60 /// the algorithm so overflow problems may arise more easily than with
61 /// other minimum cost flow algorithms.
62 /// If it is available, <tt>long long int</tt> type is used instead of
63 /// <tt>long int</tt> in the inside computations.
65 /// \author Peter Kovacs
66 template < typename Graph,
67 typename LowerMap = typename Graph::template EdgeMap<int>,
68 typename CapacityMap = typename Graph::template EdgeMap<int>,
69 typename CostMap = typename Graph::template EdgeMap<int>,
70 typename SupplyMap = typename Graph::template NodeMap<int> >
73 GRAPH_TYPEDEFS(typename Graph);
75 typedef typename CapacityMap::Value Capacity;
76 typedef typename CostMap::Value Cost;
77 typedef typename SupplyMap::Value Supply;
78 typedef typename Graph::template EdgeMap<Capacity> CapacityEdgeMap;
79 typedef typename Graph::template NodeMap<Supply> SupplyNodeMap;
81 typedef ResGraphAdaptor< const Graph, Capacity,
82 CapacityEdgeMap, CapacityEdgeMap > ResGraph;
83 typedef typename ResGraph::Edge ResEdge;
85 #if defined __GNUC__ && !defined __STRICT_ANSI__
86 typedef long long int LCost;
88 typedef long int LCost;
90 typedef typename Graph::template EdgeMap<LCost> LargeCostMap;
94 /// The type of the flow map.
95 typedef typename Graph::template EdgeMap<Capacity> FlowMap;
96 /// The type of the potential map.
97 typedef typename Graph::template NodeMap<LCost> PotentialMap;
101 /// \brief Map adaptor class for handling residual edge costs.
103 /// Map adaptor class for handling residual edge costs.
104 template <typename Map>
105 class ResidualCostMap : public MapBase<ResEdge, typename Map::Value>
109 const Map &_cost_map;
114 ResidualCostMap(const Map &cost_map) :
115 _cost_map(cost_map) {}
118 inline typename Map::Value operator[](const ResEdge &e) const {
119 return ResGraph::forward(e) ? _cost_map[e] : -_cost_map[e];
122 }; //class ResidualCostMap
124 /// \brief Map adaptor class for handling reduced edge costs.
126 /// Map adaptor class for handling reduced edge costs.
127 class ReducedCostMap : public MapBase<Edge, LCost>
132 const LargeCostMap &_cost_map;
133 const PotentialMap &_pot_map;
138 ReducedCostMap( const Graph &gr,
139 const LargeCostMap &cost_map,
140 const PotentialMap &pot_map ) :
141 _gr(gr), _cost_map(cost_map), _pot_map(pot_map) {}
144 inline LCost operator[](const Edge &e) const {
145 return _cost_map[e] + _pot_map[_gr.source(e)]
146 - _pot_map[_gr.target(e)];
149 }; //class ReducedCostMap
153 // The directed graph the algorithm runs on
155 // The original lower bound map
156 const LowerMap *_lower;
157 // The modified capacity map
158 CapacityEdgeMap _capacity;
159 // The original cost map
160 const CostMap &_orig_cost;
161 // The scaled cost map
163 // The modified supply map
164 SupplyNodeMap _supply;
167 // Edge map of the current flow
170 // Node map of the current potentials
171 PotentialMap *_potential;
172 bool _local_potential;
174 // The residual cost map
175 ResidualCostMap<LargeCostMap> _res_cost;
176 // The residual graph
177 ResGraph *_res_graph;
178 // The reduced cost map
179 ReducedCostMap *_red_cost;
181 SupplyNodeMap _excess;
182 // The epsilon parameter used for cost scaling
184 // The scaling factor
189 /// \brief General constructor (with lower bounds).
191 /// General constructor (with lower bounds).
193 /// \param graph The directed graph the algorithm runs on.
194 /// \param lower The lower bounds of the edges.
195 /// \param capacity The capacities (upper bounds) of the edges.
196 /// \param cost The cost (length) values of the edges.
197 /// \param supply The supply values of the nodes (signed).
198 CostScaling( const Graph &graph,
199 const LowerMap &lower,
200 const CapacityMap &capacity,
202 const SupplyMap &supply ) :
203 _graph(graph), _lower(&lower), _capacity(capacity), _orig_cost(cost),
204 _cost(graph), _supply(supply), _flow(NULL), _local_flow(false),
205 _potential(NULL), _local_potential(false), _res_cost(_cost),
206 _res_graph(NULL), _red_cost(NULL), _excess(graph, 0)
208 // Check the sum of supply values
210 for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
211 _valid_supply = sum == 0;
213 // Remove non-zero lower bounds
214 for (EdgeIt e(_graph); e != INVALID; ++e) {
216 _capacity[e] -= lower[e];
217 _supply[_graph.source(e)] -= lower[e];
218 _supply[_graph.target(e)] += lower[e];
223 /// \brief General constructor (without lower bounds).
225 /// General constructor (without lower bounds).
227 /// \param graph The directed graph the algorithm runs on.
228 /// \param capacity The capacities (upper bounds) of the edges.
229 /// \param cost The cost (length) values of the edges.
230 /// \param supply The supply values of the nodes (signed).
231 CostScaling( const Graph &graph,
232 const CapacityMap &capacity,
234 const SupplyMap &supply ) :
235 _graph(graph), _lower(NULL), _capacity(capacity), _orig_cost(cost),
236 _cost(graph), _supply(supply), _flow(NULL), _local_flow(false),
237 _potential(NULL), _local_potential(false), _res_cost(_cost),
238 _res_graph(NULL), _red_cost(NULL), _excess(graph, 0)
240 // Check the sum of supply values
242 for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
243 _valid_supply = sum == 0;
246 /// \brief Simple constructor (with lower bounds).
248 /// Simple constructor (with lower bounds).
250 /// \param graph The directed graph the algorithm runs on.
251 /// \param lower The lower bounds of the edges.
252 /// \param capacity The capacities (upper bounds) of the edges.
253 /// \param cost The cost (length) values of the edges.
254 /// \param s The source node.
255 /// \param t The target node.
256 /// \param flow_value The required amount of flow from node \c s
257 /// to node \c t (i.e. the supply of \c s and the demand of \c t).
258 CostScaling( const Graph &graph,
259 const LowerMap &lower,
260 const CapacityMap &capacity,
263 Supply flow_value ) :
264 _graph(graph), _lower(&lower), _capacity(capacity), _orig_cost(cost),
265 _cost(graph), _supply(graph, 0), _flow(NULL), _local_flow(false),
266 _potential(NULL), _local_potential(false), _res_cost(_cost),
267 _res_graph(NULL), _red_cost(NULL), _excess(graph, 0)
269 // Remove non-zero lower bounds
270 _supply[s] = flow_value;
271 _supply[t] = -flow_value;
272 for (EdgeIt e(_graph); e != INVALID; ++e) {
274 _capacity[e] -= lower[e];
275 _supply[_graph.source(e)] -= lower[e];
276 _supply[_graph.target(e)] += lower[e];
279 _valid_supply = true;
282 /// \brief Simple constructor (without lower bounds).
284 /// Simple constructor (without lower bounds).
286 /// \param graph The directed graph the algorithm runs on.
287 /// \param capacity The capacities (upper bounds) of the edges.
288 /// \param cost The cost (length) values of the edges.
289 /// \param s The source node.
290 /// \param t The target node.
291 /// \param flow_value The required amount of flow from node \c s
292 /// to node \c t (i.e. the supply of \c s and the demand of \c t).
293 CostScaling( const Graph &graph,
294 const CapacityMap &capacity,
297 Supply flow_value ) :
298 _graph(graph), _lower(NULL), _capacity(capacity), _orig_cost(cost),
299 _cost(graph), _supply(graph, 0), _flow(NULL), _local_flow(false),
300 _potential(NULL), _local_potential(false), _res_cost(_cost),
301 _res_graph(NULL), _red_cost(NULL), _excess(graph, 0)
303 _supply[s] = flow_value;
304 _supply[t] = -flow_value;
305 _valid_supply = true;
310 if (_local_flow) delete _flow;
311 if (_local_potential) delete _potential;
316 /// \brief Set the flow map.
318 /// Set the flow map.
320 /// \return \c (*this)
321 CostScaling& flowMap(FlowMap &map) {
330 /// \brief Set the potential map.
332 /// Set the potential map.
334 /// \return \c (*this)
335 CostScaling& potentialMap(PotentialMap &map) {
336 if (_local_potential) {
338 _local_potential = false;
344 /// \name Execution control
348 /// \brief Run the algorithm.
350 /// Run the algorithm.
352 /// \param partial_augment By default the algorithm performs
353 /// partial augment and relabel operations in the cost scaling
354 /// phases. Set this parameter to \c false for using local push and
355 /// relabel operations instead.
357 /// \return \c true if a feasible flow can be found.
358 bool run(bool partial_augment = true) {
359 if (partial_augment) {
360 return init() && startPartialAugment();
362 return init() && startPushRelabel();
368 /// \name Query Functions
369 /// The result of the algorithm can be obtained using these
371 /// \ref lemon::CostScaling::run() "run()" must be called before
376 /// \brief Return a const reference to the edge map storing the
379 /// Return a const reference to the edge map storing the found flow.
381 /// \pre \ref run() must be called before using this function.
382 const FlowMap& flowMap() const {
386 /// \brief Return a const reference to the node map storing the
387 /// found potentials (the dual solution).
389 /// Return a const reference to the node map storing the found
390 /// potentials (the dual solution).
392 /// \pre \ref run() must be called before using this function.
393 const PotentialMap& potentialMap() const {
397 /// \brief Return the flow on the given edge.
399 /// Return the flow on the given edge.
401 /// \pre \ref run() must be called before using this function.
402 Capacity flow(const Edge& edge) const {
403 return (*_flow)[edge];
406 /// \brief Return the potential of the given node.
408 /// Return the potential of the given node.
410 /// \pre \ref run() must be called before using this function.
411 Cost potential(const Node& node) const {
412 return (*_potential)[node];
415 /// \brief Return the total cost of the found flow.
417 /// Return the total cost of the found flow. The complexity of the
418 /// function is \f$ O(e) \f$.
420 /// \pre \ref run() must be called before using this function.
421 Cost totalCost() const {
423 for (EdgeIt e(_graph); e != INVALID; ++e)
424 c += (*_flow)[e] * _orig_cost[e];
432 /// Initialize the algorithm.
434 if (!_valid_supply) return false;
435 // The scaling factor
438 // Initialize flow and potential maps
440 _flow = new FlowMap(_graph);
444 _potential = new PotentialMap(_graph);
445 _local_potential = true;
448 _red_cost = new ReducedCostMap(_graph, _cost, *_potential);
449 _res_graph = new ResGraph(_graph, _capacity, *_flow);
451 // Initialize the scaled cost map and the epsilon parameter
453 int node_num = countNodes(_graph);
454 for (EdgeIt e(_graph); e != INVALID; ++e) {
455 _cost[e] = LCost(_orig_cost[e]) * node_num * _alpha;
456 if (_orig_cost[e] > max_cost) max_cost = _orig_cost[e];
458 _epsilon = max_cost * node_num;
460 // Find a feasible flow using Circulation
461 Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap,
463 circulation( _graph, constMap<Edge>(Capacity(0)), _capacity,
465 return circulation.flowMap(*_flow).run();
468 /// Execute the algorithm performing partial augmentation and
469 /// relabel operations.
470 bool startPartialAugment() {
471 // Paramters for heuristics
472 const int BF_HEURISTIC_EPSILON_BOUND = 1000;
473 const int BF_HEURISTIC_BOUND_FACTOR = 3;
474 // Maximum augment path length
475 const int MAX_PATH_LENGTH = 4;
478 typename Graph::template NodeMap<Edge> pred_edge(_graph);
479 typename Graph::template NodeMap<bool> forward(_graph);
480 typename Graph::template NodeMap<OutEdgeIt> next_out(_graph);
481 typename Graph::template NodeMap<InEdgeIt> next_in(_graph);
482 typename Graph::template NodeMap<bool> next_dir(_graph);
483 std::deque<Node> active_nodes;
484 std::vector<Node> path_nodes;
486 int node_num = countNodes(_graph);
487 for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
488 1 : _epsilon / _alpha )
490 // "Early Termination" heuristic: use Bellman-Ford algorithm
491 // to check if the current flow is optimal
492 if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
493 typedef ShiftMap< ResidualCostMap<LargeCostMap> > ShiftCostMap;
494 ShiftCostMap shift_cost(_res_cost, 1);
495 BellmanFord<ResGraph, ShiftCostMap> bf(*_res_graph, shift_cost);
498 int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(node_num));
499 for (int i = 0; i < K && !done; ++i)
500 done = bf.processNextWeakRound();
504 // Saturate edges not satisfying the optimality condition
506 for (EdgeIt e(_graph); e != INVALID; ++e) {
507 if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
508 delta = _capacity[e] - (*_flow)[e];
509 _excess[_graph.source(e)] -= delta;
510 _excess[_graph.target(e)] += delta;
511 (*_flow)[e] = _capacity[e];
513 if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
514 _excess[_graph.target(e)] -= (*_flow)[e];
515 _excess[_graph.source(e)] += (*_flow)[e];
520 // Find active nodes (i.e. nodes with positive excess)
521 for (NodeIt n(_graph); n != INVALID; ++n) {
522 if (_excess[n] > 0) active_nodes.push_back(n);
525 // Initialize the next edge maps
526 for (NodeIt n(_graph); n != INVALID; ++n) {
527 next_out[n] = OutEdgeIt(_graph, n);
528 next_in[n] = InEdgeIt(_graph, n);
532 // Perform partial augment and relabel operations
533 while (active_nodes.size() > 0) {
534 // Select an active node (FIFO selection)
535 if (_excess[active_nodes[0]] <= 0) {
536 active_nodes.pop_front();
539 Node start = active_nodes[0];
541 path_nodes.push_back(start);
543 // Find an augmenting path from the start node
546 while ( _excess[tip] >= 0 &&
547 int(path_nodes.size()) <= MAX_PATH_LENGTH )
550 for (OutEdgeIt e = next_out[tip]; e != INVALID; ++e) {
551 if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
552 u = _graph.target(e);
557 path_nodes.push_back(tip);
561 next_dir[tip] = false;
563 for (InEdgeIt e = next_in[tip]; e != INVALID; ++e) {
564 if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
565 u = _graph.source(e);
570 path_nodes.push_back(tip);
576 min_red_cost = std::numeric_limits<LCost>::max() / 2;
577 for (OutEdgeIt oe(_graph, tip); oe != INVALID; ++oe) {
578 if ( _capacity[oe] - (*_flow)[oe] > 0 &&
579 (*_red_cost)[oe] < min_red_cost )
580 min_red_cost = (*_red_cost)[oe];
582 for (InEdgeIt ie(_graph, tip); ie != INVALID; ++ie) {
583 if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < min_red_cost)
584 min_red_cost = -(*_red_cost)[ie];
586 (*_potential)[tip] -= min_red_cost + _epsilon;
588 // Reset the next edge maps
589 next_out[tip] = OutEdgeIt(_graph, tip);
590 next_in[tip] = InEdgeIt(_graph, tip);
591 next_dir[tip] = true;
595 path_nodes.pop_back();
596 tip = path_nodes[path_nodes.size()-1];
603 // Augment along the found path (as much flow as possible)
605 for (int i = 1; i < int(path_nodes.size()); ++i) {
608 _capacity[pred_edge[u]] - (*_flow)[pred_edge[u]] :
609 (*_flow)[pred_edge[u]];
610 delta = std::min(delta, _excess[path_nodes[i-1]]);
611 (*_flow)[pred_edge[u]] += forward[u] ? delta : -delta;
612 _excess[path_nodes[i-1]] -= delta;
614 if (_excess[u] > 0 && _excess[u] <= delta) active_nodes.push_back(u);
619 // Compute node potentials for the original costs
620 ResidualCostMap<CostMap> res_cost(_orig_cost);
621 BellmanFord< ResGraph, ResidualCostMap<CostMap> >
622 bf(*_res_graph, res_cost);
623 bf.init(0); bf.start();
624 for (NodeIt n(_graph); n != INVALID; ++n)
625 (*_potential)[n] = bf.dist(n);
627 // Handle non-zero lower bounds
629 for (EdgeIt e(_graph); e != INVALID; ++e)
630 (*_flow)[e] += (*_lower)[e];
635 /// Execute the algorithm performing push and relabel operations.
636 bool startPushRelabel() {
637 // Paramters for heuristics
638 const int BF_HEURISTIC_EPSILON_BOUND = 1000;
639 const int BF_HEURISTIC_BOUND_FACTOR = 3;
641 typename Graph::template NodeMap<bool> hyper(_graph, false);
642 typename Graph::template NodeMap<Edge> pred_edge(_graph);
643 typename Graph::template NodeMap<bool> forward(_graph);
644 typename Graph::template NodeMap<OutEdgeIt> next_out(_graph);
645 typename Graph::template NodeMap<InEdgeIt> next_in(_graph);
646 typename Graph::template NodeMap<bool> next_dir(_graph);
647 std::deque<Node> active_nodes;
649 int node_num = countNodes(_graph);
650 for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
651 1 : _epsilon / _alpha )
653 // "Early Termination" heuristic: use Bellman-Ford algorithm
654 // to check if the current flow is optimal
655 if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
656 typedef ShiftMap< ResidualCostMap<LargeCostMap> > ShiftCostMap;
657 ShiftCostMap shift_cost(_res_cost, 1);
658 BellmanFord<ResGraph, ShiftCostMap> bf(*_res_graph, shift_cost);
661 int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(node_num));
662 for (int i = 0; i < K && !done; ++i)
663 done = bf.processNextWeakRound();
667 // Saturate edges not satisfying the optimality condition
669 for (EdgeIt e(_graph); e != INVALID; ++e) {
670 if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
671 delta = _capacity[e] - (*_flow)[e];
672 _excess[_graph.source(e)] -= delta;
673 _excess[_graph.target(e)] += delta;
674 (*_flow)[e] = _capacity[e];
676 if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
677 _excess[_graph.target(e)] -= (*_flow)[e];
678 _excess[_graph.source(e)] += (*_flow)[e];
683 // Find active nodes (i.e. nodes with positive excess)
684 for (NodeIt n(_graph); n != INVALID; ++n) {
685 if (_excess[n] > 0) active_nodes.push_back(n);
688 // Initialize the next edge maps
689 for (NodeIt n(_graph); n != INVALID; ++n) {
690 next_out[n] = OutEdgeIt(_graph, n);
691 next_in[n] = InEdgeIt(_graph, n);
695 // Perform push and relabel operations
696 while (active_nodes.size() > 0) {
697 // Select an active node (FIFO selection)
698 Node n = active_nodes[0], t;
699 bool relabel_enabled = true;
701 // Perform push operations if there are admissible edges
702 if (_excess[n] > 0 && next_dir[n]) {
703 OutEdgeIt e = next_out[n];
704 for ( ; e != INVALID; ++e) {
705 if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
706 delta = std::min(_capacity[e] - (*_flow)[e], _excess[n]);
707 t = _graph.target(e);
709 // Push-look-ahead heuristic
710 Capacity ahead = -_excess[t];
711 for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) {
712 if (_capacity[oe] - (*_flow)[oe] > 0 && (*_red_cost)[oe] < 0)
713 ahead += _capacity[oe] - (*_flow)[oe];
715 for (InEdgeIt ie(_graph, t); ie != INVALID; ++ie) {
716 if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
717 ahead += (*_flow)[ie];
719 if (ahead < 0) ahead = 0;
721 // Push flow along the edge
723 (*_flow)[e] += ahead;
726 active_nodes.push_front(t);
728 relabel_enabled = false;
731 (*_flow)[e] += delta;
734 if (_excess[t] > 0 && _excess[t] <= delta)
735 active_nodes.push_back(t);
738 if (_excess[n] == 0) break;
748 if (_excess[n] > 0 && !next_dir[n]) {
749 InEdgeIt e = next_in[n];
750 for ( ; e != INVALID; ++e) {
751 if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
752 delta = std::min((*_flow)[e], _excess[n]);
753 t = _graph.source(e);
755 // Push-look-ahead heuristic
756 Capacity ahead = -_excess[t];
757 for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) {
758 if (_capacity[oe] - (*_flow)[oe] > 0 && (*_red_cost)[oe] < 0)
759 ahead += _capacity[oe] - (*_flow)[oe];
761 for (InEdgeIt ie(_graph, t); ie != INVALID; ++ie) {
762 if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
763 ahead += (*_flow)[ie];
765 if (ahead < 0) ahead = 0;
767 // Push flow along the edge
769 (*_flow)[e] -= ahead;
772 active_nodes.push_front(t);
774 relabel_enabled = false;
777 (*_flow)[e] -= delta;
780 if (_excess[t] > 0 && _excess[t] <= delta)
781 active_nodes.push_back(t);
784 if (_excess[n] == 0) break;
790 // Relabel the node if it is still active (or hyper)
791 if (relabel_enabled && (_excess[n] > 0 || hyper[n])) {
792 LCost min_red_cost = std::numeric_limits<LCost>::max() / 2;
793 for (OutEdgeIt oe(_graph, n); oe != INVALID; ++oe) {
794 if ( _capacity[oe] - (*_flow)[oe] > 0 &&
795 (*_red_cost)[oe] < min_red_cost )
796 min_red_cost = (*_red_cost)[oe];
798 for (InEdgeIt ie(_graph, n); ie != INVALID; ++ie) {
799 if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < min_red_cost)
800 min_red_cost = -(*_red_cost)[ie];
802 (*_potential)[n] -= min_red_cost + _epsilon;
805 // Reset the next edge maps
806 next_out[n] = OutEdgeIt(_graph, n);
807 next_in[n] = InEdgeIt(_graph, n);
811 // Remove nodes that are not active nor hyper
812 while ( active_nodes.size() > 0 &&
813 _excess[active_nodes[0]] <= 0 &&
814 !hyper[active_nodes[0]] ) {
815 active_nodes.pop_front();
820 // Compute node potentials for the original costs
821 ResidualCostMap<CostMap> res_cost(_orig_cost);
822 BellmanFord< ResGraph, ResidualCostMap<CostMap> >
823 bf(*_res_graph, res_cost);
824 bf.init(0); bf.start();
825 for (NodeIt n(_graph); n != INVALID; ++n)
826 (*_potential)[n] = bf.dist(n);
828 // Handle non-zero lower bounds
830 for (EdgeIt e(_graph); e != INVALID; ++e)
831 (*_flow)[e] += (*_lower)[e];
836 }; //class CostScaling
842 #endif //LEMON_COST_SCALING_H