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_algs
24 /// \brief Cost scaling algorithm for finding a minimum cost flow.
30 #include <lemon/core.h>
31 #include <lemon/maps.h>
32 #include <lemon/math.h>
33 #include <lemon/adaptors.h>
34 #include <lemon/circulation.h>
35 #include <lemon/bellman_ford.h>
39 /// \addtogroup min_cost_flow_algs
42 /// \brief Implementation of the cost scaling algorithm for finding a
43 /// minimum cost flow.
45 /// \ref CostScaling implements the cost scaling algorithm performing
46 /// augment/push and relabel operations for finding a minimum cost
49 /// \tparam Digraph The digraph type the algorithm runs on.
50 /// \tparam LowerMap The type of the lower bound map.
51 /// \tparam CapacityMap The type of the capacity (upper bound) map.
52 /// \tparam CostMap The type of the cost (length) map.
53 /// \tparam SupplyMap The type of the supply map.
56 /// - Arc capacities and costs should be \e non-negative \e integers.
57 /// - Supply values should be \e signed \e integers.
58 /// - The value types of the maps should be convertible to each other.
59 /// - \c CostMap::Value must be signed type.
61 /// \note Arc costs are multiplied with the number of nodes during
62 /// the algorithm so overflow problems may arise more easily than with
63 /// other minimum cost flow algorithms.
64 /// If it is available, <tt>long long int</tt> type is used instead of
65 /// <tt>long int</tt> in the inside computations.
67 /// \author Peter Kovacs
68 template < typename Digraph,
69 typename LowerMap = typename Digraph::template ArcMap<int>,
70 typename CapacityMap = typename Digraph::template ArcMap<int>,
71 typename CostMap = typename Digraph::template ArcMap<int>,
72 typename SupplyMap = typename Digraph::template NodeMap<int> >
75 TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
77 typedef typename CapacityMap::Value Capacity;
78 typedef typename CostMap::Value Cost;
79 typedef typename SupplyMap::Value Supply;
80 typedef typename Digraph::template ArcMap<Capacity> CapacityArcMap;
81 typedef typename Digraph::template NodeMap<Supply> SupplyNodeMap;
83 typedef ResidualDigraph< const Digraph,
84 CapacityArcMap, CapacityArcMap > ResDigraph;
85 typedef typename ResDigraph::Arc ResArc;
87 #if defined __GNUC__ && !defined __STRICT_ANSI__
88 typedef long long int LCost;
90 typedef long int LCost;
92 typedef typename Digraph::template ArcMap<LCost> LargeCostMap;
96 /// The type of the flow map.
97 typedef typename Digraph::template ArcMap<Capacity> FlowMap;
98 /// The type of the potential map.
99 typedef typename Digraph::template NodeMap<LCost> PotentialMap;
103 /// \brief Map adaptor class for handling residual arc costs.
105 /// Map adaptor class for handling residual arc costs.
106 template <typename Map>
107 class ResidualCostMap : public MapBase<ResArc, typename Map::Value>
111 const Map &_cost_map;
116 ResidualCostMap(const Map &cost_map) :
117 _cost_map(cost_map) {}
120 inline typename Map::Value operator[](const ResArc &e) const {
121 return ResDigraph::forward(e) ? _cost_map[e] : -_cost_map[e];
124 }; //class ResidualCostMap
126 /// \brief Map adaptor class for handling reduced arc costs.
128 /// Map adaptor class for handling reduced arc costs.
129 class ReducedCostMap : public MapBase<Arc, LCost>
134 const LargeCostMap &_cost_map;
135 const PotentialMap &_pot_map;
140 ReducedCostMap( const Digraph &gr,
141 const LargeCostMap &cost_map,
142 const PotentialMap &pot_map ) :
143 _gr(gr), _cost_map(cost_map), _pot_map(pot_map) {}
146 inline LCost operator[](const Arc &e) const {
147 return _cost_map[e] + _pot_map[_gr.source(e)]
148 - _pot_map[_gr.target(e)];
151 }; //class ReducedCostMap
155 // The digraph the algorithm runs on
156 const Digraph &_graph;
157 // The original lower bound map
158 const LowerMap *_lower;
159 // The modified capacity map
160 CapacityArcMap _capacity;
161 // The original cost map
162 const CostMap &_orig_cost;
163 // The scaled cost map
165 // The modified supply map
166 SupplyNodeMap _supply;
169 // Arc map of the current flow
172 // Node map of the current potentials
173 PotentialMap *_potential;
174 bool _local_potential;
176 // The residual cost map
177 ResidualCostMap<LargeCostMap> _res_cost;
178 // The residual digraph
179 ResDigraph *_res_graph;
180 // The reduced cost map
181 ReducedCostMap *_red_cost;
183 SupplyNodeMap _excess;
184 // The epsilon parameter used for cost scaling
186 // The scaling factor
191 /// \brief General constructor (with lower bounds).
193 /// General constructor (with lower bounds).
195 /// \param digraph The digraph the algorithm runs on.
196 /// \param lower The lower bounds of the arcs.
197 /// \param capacity The capacities (upper bounds) of the arcs.
198 /// \param cost The cost (length) values of the arcs.
199 /// \param supply The supply values of the nodes (signed).
200 CostScaling( const Digraph &digraph,
201 const LowerMap &lower,
202 const CapacityMap &capacity,
204 const SupplyMap &supply ) :
205 _graph(digraph), _lower(&lower), _capacity(digraph), _orig_cost(cost),
206 _cost(digraph), _supply(digraph), _flow(NULL), _local_flow(false),
207 _potential(NULL), _local_potential(false), _res_cost(_cost),
208 _res_graph(NULL), _red_cost(NULL), _excess(digraph, 0)
210 // Check the sum of supply values
212 for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
213 _valid_supply = sum == 0;
215 for (ArcIt e(_graph); e != INVALID; ++e) _capacity[e] = capacity[e];
216 for (NodeIt n(_graph); n != INVALID; ++n) _supply[n] = supply[n];
218 // Remove non-zero lower bounds
219 for (ArcIt e(_graph); e != INVALID; ++e) {
221 _capacity[e] -= lower[e];
222 _supply[_graph.source(e)] -= lower[e];
223 _supply[_graph.target(e)] += lower[e];
228 /// \brief General constructor (without lower bounds).
230 /// General constructor (without lower bounds).
232 /// \param digraph The digraph the algorithm runs on.
233 /// \param capacity The capacities (upper bounds) of the arcs.
234 /// \param cost The cost (length) values of the arcs.
235 /// \param supply The supply values of the nodes (signed).
236 CostScaling( const Digraph &digraph,
237 const CapacityMap &capacity,
239 const SupplyMap &supply ) :
240 _graph(digraph), _lower(NULL), _capacity(capacity), _orig_cost(cost),
241 _cost(digraph), _supply(supply), _flow(NULL), _local_flow(false),
242 _potential(NULL), _local_potential(false), _res_cost(_cost),
243 _res_graph(NULL), _red_cost(NULL), _excess(digraph, 0)
245 // Check the sum of supply values
247 for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
248 _valid_supply = sum == 0;
251 /// \brief Simple constructor (with lower bounds).
253 /// Simple constructor (with lower bounds).
255 /// \param digraph The digraph the algorithm runs on.
256 /// \param lower The lower bounds of the arcs.
257 /// \param capacity The capacities (upper bounds) of the arcs.
258 /// \param cost The cost (length) values of the arcs.
259 /// \param s The source node.
260 /// \param t The target node.
261 /// \param flow_value The required amount of flow from node \c s
262 /// to node \c t (i.e. the supply of \c s and the demand of \c t).
263 CostScaling( const Digraph &digraph,
264 const LowerMap &lower,
265 const CapacityMap &capacity,
268 Supply flow_value ) :
269 _graph(digraph), _lower(&lower), _capacity(capacity), _orig_cost(cost),
270 _cost(digraph), _supply(digraph, 0), _flow(NULL), _local_flow(false),
271 _potential(NULL), _local_potential(false), _res_cost(_cost),
272 _res_graph(NULL), _red_cost(NULL), _excess(digraph, 0)
274 // Remove non-zero lower bounds
275 _supply[s] = flow_value;
276 _supply[t] = -flow_value;
277 for (ArcIt e(_graph); e != INVALID; ++e) {
279 _capacity[e] -= lower[e];
280 _supply[_graph.source(e)] -= lower[e];
281 _supply[_graph.target(e)] += lower[e];
284 _valid_supply = true;
287 /// \brief Simple constructor (without lower bounds).
289 /// Simple constructor (without lower bounds).
291 /// \param digraph The digraph the algorithm runs on.
292 /// \param capacity The capacities (upper bounds) of the arcs.
293 /// \param cost The cost (length) values of the arcs.
294 /// \param s The source node.
295 /// \param t The target node.
296 /// \param flow_value The required amount of flow from node \c s
297 /// to node \c t (i.e. the supply of \c s and the demand of \c t).
298 CostScaling( const Digraph &digraph,
299 const CapacityMap &capacity,
302 Supply flow_value ) :
303 _graph(digraph), _lower(NULL), _capacity(capacity), _orig_cost(cost),
304 _cost(digraph), _supply(digraph, 0), _flow(NULL), _local_flow(false),
305 _potential(NULL), _local_potential(false), _res_cost(_cost),
306 _res_graph(NULL), _red_cost(NULL), _excess(digraph, 0)
308 _supply[s] = flow_value;
309 _supply[t] = -flow_value;
310 _valid_supply = true;
315 if (_local_flow) delete _flow;
316 if (_local_potential) delete _potential;
321 /// \brief Set the flow map.
323 /// Set the flow map.
325 /// \return \c (*this)
326 CostScaling& flowMap(FlowMap &map) {
335 /// \brief Set the potential map.
337 /// Set the potential map.
339 /// \return \c (*this)
340 CostScaling& potentialMap(PotentialMap &map) {
341 if (_local_potential) {
343 _local_potential = false;
349 /// \name Execution control
353 /// \brief Run the algorithm.
355 /// Run the algorithm.
357 /// \param partial_augment By default the algorithm performs
358 /// partial augment and relabel operations in the cost scaling
359 /// phases. Set this parameter to \c false for using local push and
360 /// relabel operations instead.
362 /// \return \c true if a feasible flow can be found.
363 bool run(bool partial_augment = true) {
364 if (partial_augment) {
365 return init() && startPartialAugment();
367 return init() && startPushRelabel();
373 /// \name Query Functions
374 /// The result of the algorithm can be obtained using these
376 /// \ref lemon::CostScaling::run() "run()" must be called before
381 /// \brief Return a const reference to the arc map storing the
384 /// Return a const reference to the arc map storing the found flow.
386 /// \pre \ref run() must be called before using this function.
387 const FlowMap& flowMap() const {
391 /// \brief Return a const reference to the node map storing the
392 /// found potentials (the dual solution).
394 /// Return a const reference to the node map storing the found
395 /// potentials (the dual solution).
397 /// \pre \ref run() must be called before using this function.
398 const PotentialMap& potentialMap() const {
402 /// \brief Return the flow on the given arc.
404 /// Return the flow on the given arc.
406 /// \pre \ref run() must be called before using this function.
407 Capacity flow(const Arc& arc) const {
408 return (*_flow)[arc];
411 /// \brief Return the potential of the given node.
413 /// Return the potential of the given node.
415 /// \pre \ref run() must be called before using this function.
416 Cost potential(const Node& node) const {
417 return (*_potential)[node];
420 /// \brief Return the total cost of the found flow.
422 /// Return the total cost of the found flow. The complexity of the
423 /// function is \f$ O(e) \f$.
425 /// \pre \ref run() must be called before using this function.
426 Cost totalCost() const {
428 for (ArcIt e(_graph); e != INVALID; ++e)
429 c += (*_flow)[e] * _orig_cost[e];
437 /// Initialize the algorithm.
439 if (!_valid_supply) return false;
440 // The scaling factor
443 // Initialize flow and potential maps
445 _flow = new FlowMap(_graph);
449 _potential = new PotentialMap(_graph);
450 _local_potential = true;
453 _red_cost = new ReducedCostMap(_graph, _cost, *_potential);
454 _res_graph = new ResDigraph(_graph, _capacity, *_flow);
456 // Initialize the scaled cost map and the epsilon parameter
458 int node_num = countNodes(_graph);
459 for (ArcIt e(_graph); e != INVALID; ++e) {
460 _cost[e] = LCost(_orig_cost[e]) * node_num * _alpha;
461 if (_orig_cost[e] > max_cost) max_cost = _orig_cost[e];
463 _epsilon = max_cost * node_num;
465 // Find a feasible flow using Circulation
466 Circulation< Digraph, ConstMap<Arc, Capacity>, CapacityArcMap,
468 circulation( _graph, constMap<Arc>(Capacity(0)), _capacity,
470 return circulation.flowMap(*_flow).run();
473 /// Execute the algorithm performing partial augmentation and
474 /// relabel operations.
475 bool startPartialAugment() {
476 // Paramters for heuristics
477 // const int BF_HEURISTIC_EPSILON_BOUND = 1000;
478 // const int BF_HEURISTIC_BOUND_FACTOR = 3;
479 // Maximum augment path length
480 const int MAX_PATH_LENGTH = 4;
483 typename Digraph::template NodeMap<Arc> pred_arc(_graph);
484 typename Digraph::template NodeMap<bool> forward(_graph);
485 typename Digraph::template NodeMap<OutArcIt> next_out(_graph);
486 typename Digraph::template NodeMap<InArcIt> next_in(_graph);
487 typename Digraph::template NodeMap<bool> next_dir(_graph);
488 std::deque<Node> active_nodes;
489 std::vector<Node> path_nodes;
491 // int node_num = countNodes(_graph);
492 for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
493 1 : _epsilon / _alpha )
496 // "Early Termination" heuristic: use Bellman-Ford algorithm
497 // to check if the current flow is optimal
498 if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
499 typedef ShiftMap< ResidualCostMap<LargeCostMap> > ShiftCostMap;
500 ShiftCostMap shift_cost(_res_cost, 1);
501 BellmanFord<ResDigraph, ShiftCostMap> bf(*_res_graph, shift_cost);
504 int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(node_num));
505 for (int i = 0; i < K && !done; ++i)
506 done = bf.processNextWeakRound();
510 // Saturate arcs not satisfying the optimality condition
512 for (ArcIt e(_graph); e != INVALID; ++e) {
513 if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
514 delta = _capacity[e] - (*_flow)[e];
515 _excess[_graph.source(e)] -= delta;
516 _excess[_graph.target(e)] += delta;
517 (*_flow)[e] = _capacity[e];
519 if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
520 _excess[_graph.target(e)] -= (*_flow)[e];
521 _excess[_graph.source(e)] += (*_flow)[e];
526 // Find active nodes (i.e. nodes with positive excess)
527 for (NodeIt n(_graph); n != INVALID; ++n) {
528 if (_excess[n] > 0) active_nodes.push_back(n);
531 // Initialize the next arc maps
532 for (NodeIt n(_graph); n != INVALID; ++n) {
533 next_out[n] = OutArcIt(_graph, n);
534 next_in[n] = InArcIt(_graph, n);
538 // Perform partial augment and relabel operations
539 while (active_nodes.size() > 0) {
540 // Select an active node (FIFO selection)
541 if (_excess[active_nodes[0]] <= 0) {
542 active_nodes.pop_front();
545 Node start = active_nodes[0];
547 path_nodes.push_back(start);
549 // Find an augmenting path from the start node
552 while ( _excess[tip] >= 0 &&
553 int(path_nodes.size()) <= MAX_PATH_LENGTH )
556 for (OutArcIt e = next_out[tip]; e != INVALID; ++e) {
557 if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
558 u = _graph.target(e);
563 path_nodes.push_back(tip);
567 next_dir[tip] = false;
569 for (InArcIt e = next_in[tip]; e != INVALID; ++e) {
570 if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
571 u = _graph.source(e);
576 path_nodes.push_back(tip);
582 min_red_cost = std::numeric_limits<LCost>::max() / 2;
583 for (OutArcIt oe(_graph, tip); oe != INVALID; ++oe) {
584 if ( _capacity[oe] - (*_flow)[oe] > 0 &&
585 (*_red_cost)[oe] < min_red_cost )
586 min_red_cost = (*_red_cost)[oe];
588 for (InArcIt ie(_graph, tip); ie != INVALID; ++ie) {
589 if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < min_red_cost)
590 min_red_cost = -(*_red_cost)[ie];
592 (*_potential)[tip] -= min_red_cost + _epsilon;
594 // Reset the next arc maps
595 next_out[tip] = OutArcIt(_graph, tip);
596 next_in[tip] = InArcIt(_graph, tip);
597 next_dir[tip] = true;
601 path_nodes.pop_back();
602 tip = path_nodes[path_nodes.size()-1];
609 // Augment along the found path (as much flow as possible)
611 for (int i = 1; i < int(path_nodes.size()); ++i) {
614 _capacity[pred_arc[u]] - (*_flow)[pred_arc[u]] :
615 (*_flow)[pred_arc[u]];
616 delta = std::min(delta, _excess[path_nodes[i-1]]);
617 (*_flow)[pred_arc[u]] += forward[u] ? delta : -delta;
618 _excess[path_nodes[i-1]] -= delta;
620 if (_excess[u] > 0 && _excess[u] <= delta) active_nodes.push_back(u);
625 // Compute node potentials for the original costs
626 ResidualCostMap<CostMap> res_cost(_orig_cost);
627 BellmanFord< ResDigraph, ResidualCostMap<CostMap> >
628 bf(*_res_graph, res_cost);
629 bf.init(0); bf.start();
630 for (NodeIt n(_graph); n != INVALID; ++n)
631 (*_potential)[n] = bf.dist(n);
633 // Handle non-zero lower bounds
635 for (ArcIt e(_graph); e != INVALID; ++e)
636 (*_flow)[e] += (*_lower)[e];
641 /// Execute the algorithm performing push and relabel operations.
642 bool startPushRelabel() {
643 // Paramters for heuristics
644 // const int BF_HEURISTIC_EPSILON_BOUND = 1000;
645 // const int BF_HEURISTIC_BOUND_FACTOR = 3;
647 typename Digraph::template NodeMap<bool> hyper(_graph, false);
648 typename Digraph::template NodeMap<Arc> pred_arc(_graph);
649 typename Digraph::template NodeMap<bool> forward(_graph);
650 typename Digraph::template NodeMap<OutArcIt> next_out(_graph);
651 typename Digraph::template NodeMap<InArcIt> next_in(_graph);
652 typename Digraph::template NodeMap<bool> next_dir(_graph);
653 std::deque<Node> active_nodes;
655 // int node_num = countNodes(_graph);
656 for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
657 1 : _epsilon / _alpha )
660 // "Early Termination" heuristic: use Bellman-Ford algorithm
661 // to check if the current flow is optimal
662 if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
663 typedef ShiftMap< ResidualCostMap<LargeCostMap> > ShiftCostMap;
664 ShiftCostMap shift_cost(_res_cost, 1);
665 BellmanFord<ResDigraph, ShiftCostMap> bf(*_res_graph, shift_cost);
668 int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(node_num));
669 for (int i = 0; i < K && !done; ++i)
670 done = bf.processNextWeakRound();
675 // Saturate arcs not satisfying the optimality condition
677 for (ArcIt e(_graph); e != INVALID; ++e) {
678 if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
679 delta = _capacity[e] - (*_flow)[e];
680 _excess[_graph.source(e)] -= delta;
681 _excess[_graph.target(e)] += delta;
682 (*_flow)[e] = _capacity[e];
684 if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
685 _excess[_graph.target(e)] -= (*_flow)[e];
686 _excess[_graph.source(e)] += (*_flow)[e];
691 // Find active nodes (i.e. nodes with positive excess)
692 for (NodeIt n(_graph); n != INVALID; ++n) {
693 if (_excess[n] > 0) active_nodes.push_back(n);
696 // Initialize the next arc maps
697 for (NodeIt n(_graph); n != INVALID; ++n) {
698 next_out[n] = OutArcIt(_graph, n);
699 next_in[n] = InArcIt(_graph, n);
703 // Perform push and relabel operations
704 while (active_nodes.size() > 0) {
705 // Select an active node (FIFO selection)
706 Node n = active_nodes[0], t;
707 bool relabel_enabled = true;
709 // Perform push operations if there are admissible arcs
710 if (_excess[n] > 0 && next_dir[n]) {
711 OutArcIt e = next_out[n];
712 for ( ; e != INVALID; ++e) {
713 if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
714 delta = std::min(_capacity[e] - (*_flow)[e], _excess[n]);
715 t = _graph.target(e);
717 // Push-look-ahead heuristic
718 Capacity ahead = -_excess[t];
719 for (OutArcIt oe(_graph, t); oe != INVALID; ++oe) {
720 if (_capacity[oe] - (*_flow)[oe] > 0 && (*_red_cost)[oe] < 0)
721 ahead += _capacity[oe] - (*_flow)[oe];
723 for (InArcIt ie(_graph, t); ie != INVALID; ++ie) {
724 if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
725 ahead += (*_flow)[ie];
727 if (ahead < 0) ahead = 0;
729 // Push flow along the arc
731 (*_flow)[e] += ahead;
734 active_nodes.push_front(t);
736 relabel_enabled = false;
739 (*_flow)[e] += delta;
742 if (_excess[t] > 0 && _excess[t] <= delta)
743 active_nodes.push_back(t);
746 if (_excess[n] == 0) break;
756 if (_excess[n] > 0 && !next_dir[n]) {
757 InArcIt e = next_in[n];
758 for ( ; e != INVALID; ++e) {
759 if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
760 delta = std::min((*_flow)[e], _excess[n]);
761 t = _graph.source(e);
763 // Push-look-ahead heuristic
764 Capacity ahead = -_excess[t];
765 for (OutArcIt oe(_graph, t); oe != INVALID; ++oe) {
766 if (_capacity[oe] - (*_flow)[oe] > 0 && (*_red_cost)[oe] < 0)
767 ahead += _capacity[oe] - (*_flow)[oe];
769 for (InArcIt ie(_graph, t); ie != INVALID; ++ie) {
770 if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
771 ahead += (*_flow)[ie];
773 if (ahead < 0) ahead = 0;
775 // Push flow along the arc
777 (*_flow)[e] -= ahead;
780 active_nodes.push_front(t);
782 relabel_enabled = false;
785 (*_flow)[e] -= delta;
788 if (_excess[t] > 0 && _excess[t] <= delta)
789 active_nodes.push_back(t);
792 if (_excess[n] == 0) break;
798 // Relabel the node if it is still active (or hyper)
799 if (relabel_enabled && (_excess[n] > 0 || hyper[n])) {
800 LCost min_red_cost = std::numeric_limits<LCost>::max() / 2;
801 for (OutArcIt oe(_graph, n); oe != INVALID; ++oe) {
802 if ( _capacity[oe] - (*_flow)[oe] > 0 &&
803 (*_red_cost)[oe] < min_red_cost )
804 min_red_cost = (*_red_cost)[oe];
806 for (InArcIt ie(_graph, n); ie != INVALID; ++ie) {
807 if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < min_red_cost)
808 min_red_cost = -(*_red_cost)[ie];
810 (*_potential)[n] -= min_red_cost + _epsilon;
813 // Reset the next arc maps
814 next_out[n] = OutArcIt(_graph, n);
815 next_in[n] = InArcIt(_graph, n);
819 // Remove nodes that are not active nor hyper
820 while ( active_nodes.size() > 0 &&
821 _excess[active_nodes[0]] <= 0 &&
822 !hyper[active_nodes[0]] ) {
823 active_nodes.pop_front();
828 // Compute node potentials for the original costs
829 ResidualCostMap<CostMap> res_cost(_orig_cost);
830 BellmanFord< ResDigraph, ResidualCostMap<CostMap> >
831 bf(*_res_graph, res_cost);
832 bf.init(0); bf.start();
833 for (NodeIt n(_graph); n != INVALID; ++n)
834 (*_potential)[n] = bf.dist(n);
836 // Handle non-zero lower bounds
838 for (ArcIt e(_graph); e != INVALID; ++e)
839 (*_flow)[e] += (*_lower)[e];
844 }; //class CostScaling
850 #endif //LEMON_COST_SCALING_H