COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/cost_scaling.h @ 2629:84354c78b068

Last change on this file since 2629:84354c78b068 was 2629:84354c78b068, checked in by Peter Kovacs, 15 years ago

Improved constructors for min cost flow classes
Removing the non-zero lower bounds is faster

File size: 28.5 KB
Line 
1/* -*- C++ -*-
2 *
3 * This file is a part of LEMON, a generic C++ optimization library
4 *
5 * Copyright (C) 2003-2008
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_COST_SCALING_H
20#define LEMON_COST_SCALING_H
21
22/// \ingroup min_cost_flow
23/// \file
24/// \brief Cost scaling algorithm for finding a minimum cost flow.
25
26#include <deque>
27#include <lemon/graph_adaptor.h>
28#include <lemon/graph_utils.h>
29#include <lemon/maps.h>
30#include <lemon/math.h>
31
32#include <lemon/circulation.h>
33#include <lemon/bellman_ford.h>
34
35namespace lemon {
36
37  /// \addtogroup min_cost_flow
38  /// @{
39
40  /// \brief Implementation of the cost scaling algorithm for finding a
41  /// minimum cost flow.
42  ///
43  /// \ref CostScaling implements the cost scaling algorithm performing
44  /// augment/push and relabel operations for finding a minimum cost
45  /// flow.
46  ///
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.
52  ///
53  /// \warning
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.
58  ///
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.
64  ///
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> >
71  class CostScaling
72  {
73    GRAPH_TYPEDEFS(typename Graph);
74
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;
80
81    typedef ResGraphAdaptor< const Graph, Capacity,
82                             CapacityEdgeMap, CapacityEdgeMap > ResGraph;
83    typedef typename ResGraph::Edge ResEdge;
84
85#if defined __GNUC__ && !defined __STRICT_ANSI__
86    typedef long long int LCost;
87#else
88    typedef long int LCost;
89#endif
90    typedef typename Graph::template EdgeMap<LCost> LargeCostMap;
91
92  public:
93
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;
98
99  private:
100
101    /// \brief Map adaptor class for handling residual edge costs.
102    ///
103    /// Map adaptor class for handling residual edge costs.
104    template <typename Map>
105    class ResidualCostMap : public MapBase<ResEdge, typename Map::Value>
106    {
107    private:
108
109      const Map &_cost_map;
110
111    public:
112
113      ///\e
114      ResidualCostMap(const Map &cost_map) :
115        _cost_map(cost_map) {}
116
117      ///\e
118      inline typename Map::Value operator[](const ResEdge &e) const {
119        return ResGraph::forward(e) ? _cost_map[e] : -_cost_map[e];
120      }
121
122    }; //class ResidualCostMap
123
124    /// \brief Map adaptor class for handling reduced edge costs.
125    ///
126    /// Map adaptor class for handling reduced edge costs.
127    class ReducedCostMap : public MapBase<Edge, LCost>
128    {
129    private:
130
131      const Graph &_gr;
132      const LargeCostMap &_cost_map;
133      const PotentialMap &_pot_map;
134
135    public:
136
137      ///\e
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) {}
142
143      ///\e
144      inline LCost operator[](const Edge &e) const {
145        return _cost_map[e] + _pot_map[_gr.source(e)]
146                            - _pot_map[_gr.target(e)];
147      }
148
149    }; //class ReducedCostMap
150
151  private:
152
153    // The directed graph the algorithm runs on
154    const Graph &_graph;
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
162    LargeCostMap _cost;
163    // The modified supply map
164    SupplyNodeMap _supply;
165    bool _valid_supply;
166
167    // Edge map of the current flow
168    FlowMap *_flow;
169    bool _local_flow;
170    // Node map of the current potentials
171    PotentialMap *_potential;
172    bool _local_potential;
173
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;
180    // The excess map
181    SupplyNodeMap _excess;
182    // The epsilon parameter used for cost scaling
183    LCost _epsilon;
184    // The scaling factor
185    int _alpha;
186
187  public:
188
189    /// \brief General constructor (with lower bounds).
190    ///
191    /// General constructor (with lower bounds).
192    ///
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,
201                 const CostMap &cost,
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)
207    {
208      // Check the sum of supply values
209      Supply sum = 0;
210      for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
211      _valid_supply = sum == 0;
212
213      // Remove non-zero lower bounds
214      for (EdgeIt e(_graph); e != INVALID; ++e) {
215        if (lower[e] != 0) {
216          _capacity[e] -= lower[e];
217          _supply[_graph.source(e)] -= lower[e];
218          _supply[_graph.target(e)] += lower[e];
219        }
220      }
221    }
222
223    /// \brief General constructor (without lower bounds).
224    ///
225    /// General constructor (without lower bounds).
226    ///
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,
233                 const CostMap &cost,
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)
239    {
240      // Check the sum of supply values
241      Supply sum = 0;
242      for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
243      _valid_supply = sum == 0;
244    }
245
246    /// \brief Simple constructor (with lower bounds).
247    ///
248    /// Simple constructor (with lower bounds).
249    ///
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,
261                 const CostMap &cost,
262                 Node s, Node t,
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)
268    {
269      // Remove non-zero lower bounds
270      _supply[s] =  flow_value;
271      _supply[t] = -flow_value;
272      for (EdgeIt e(_graph); e != INVALID; ++e) {
273        if (lower[e] != 0) {
274          _capacity[e] -= lower[e];
275          _supply[_graph.source(e)] -= lower[e];
276          _supply[_graph.target(e)] += lower[e];
277        }
278      }
279      _valid_supply = true;
280    }
281
282    /// \brief Simple constructor (without lower bounds).
283    ///
284    /// Simple constructor (without lower bounds).
285    ///
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,
295                 const CostMap &cost,
296                 Node s, Node t,
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)
302    {
303      _supply[s] =  flow_value;
304      _supply[t] = -flow_value;
305      _valid_supply = true;
306    }
307
308    /// Destructor.
309    ~CostScaling() {
310      if (_local_flow) delete _flow;
311      if (_local_potential) delete _potential;
312      delete _res_graph;
313      delete _red_cost;
314    }
315
316    /// \brief Set the flow map.
317    ///
318    /// Set the flow map.
319    ///
320    /// \return \c (*this)
321    CostScaling& flowMap(FlowMap &map) {
322      if (_local_flow) {
323        delete _flow;
324        _local_flow = false;
325      }
326      _flow = &map;
327      return *this;
328    }
329
330    /// \brief Set the potential map.
331    ///
332    /// Set the potential map.
333    ///
334    /// \return \c (*this)
335    CostScaling& potentialMap(PotentialMap &map) {
336      if (_local_potential) {
337        delete _potential;
338        _local_potential = false;
339      }
340      _potential = &map;
341      return *this;
342    }
343
344    /// \name Execution control
345
346    /// @{
347
348    /// \brief Run the algorithm.
349    ///
350    /// Run the algorithm.
351    ///
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.
356    ///
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();
361      } else {
362        return init() && startPushRelabel();
363      }
364    }
365
366    /// @}
367
368    /// \name Query Functions
369    /// The result of the algorithm can be obtained using these
370    /// functions.\n
371    /// \ref lemon::CostScaling::run() "run()" must be called before
372    /// using them.
373
374    /// @{
375
376    /// \brief Return a const reference to the edge map storing the
377    /// found flow.
378    ///
379    /// Return a const reference to the edge map storing the found flow.
380    ///
381    /// \pre \ref run() must be called before using this function.
382    const FlowMap& flowMap() const {
383      return *_flow;
384    }
385
386    /// \brief Return a const reference to the node map storing the
387    /// found potentials (the dual solution).
388    ///
389    /// Return a const reference to the node map storing the found
390    /// potentials (the dual solution).
391    ///
392    /// \pre \ref run() must be called before using this function.
393    const PotentialMap& potentialMap() const {
394      return *_potential;
395    }
396
397    /// \brief Return the flow on the given edge.
398    ///
399    /// Return the flow on the given edge.
400    ///
401    /// \pre \ref run() must be called before using this function.
402    Capacity flow(const Edge& edge) const {
403      return (*_flow)[edge];
404    }
405
406    /// \brief Return the potential of the given node.
407    ///
408    /// Return the potential of the given node.
409    ///
410    /// \pre \ref run() must be called before using this function.
411    Cost potential(const Node& node) const {
412      return (*_potential)[node];
413    }
414
415    /// \brief Return the total cost of the found flow.
416    ///
417    /// Return the total cost of the found flow. The complexity of the
418    /// function is \f$ O(e) \f$.
419    ///
420    /// \pre \ref run() must be called before using this function.
421    Cost totalCost() const {
422      Cost c = 0;
423      for (EdgeIt e(_graph); e != INVALID; ++e)
424        c += (*_flow)[e] * _orig_cost[e];
425      return c;
426    }
427
428    /// @}
429
430  private:
431
432    /// Initialize the algorithm.
433    bool init() {
434      if (!_valid_supply) return false;
435      // The scaling factor
436      _alpha = 8;
437
438      // Initialize flow and potential maps
439      if (!_flow) {
440        _flow = new FlowMap(_graph);
441        _local_flow = true;
442      }
443      if (!_potential) {
444        _potential = new PotentialMap(_graph);
445        _local_potential = true;
446      }
447
448      _red_cost = new ReducedCostMap(_graph, _cost, *_potential);
449      _res_graph = new ResGraph(_graph, _capacity, *_flow);
450
451      // Initialize the scaled cost map and the epsilon parameter
452      Cost max_cost = 0;
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];
457      }
458      _epsilon = max_cost * node_num;
459
460      // Find a feasible flow using Circulation
461      Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap,
462                   SupplyMap >
463        circulation( _graph, constMap<Edge>(Capacity(0)), _capacity,
464                     _supply );
465      return circulation.flowMap(*_flow).run();
466    }
467
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;
476
477      // Variables
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;
485
486      int node_num = countNodes(_graph);
487      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
488                                        1 : _epsilon / _alpha )
489      {
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);
496          bf.init(0);
497          bool done = false;
498          int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(node_num));
499          for (int i = 0; i < K && !done; ++i)
500            done = bf.processNextWeakRound();
501          if (done) break;
502        }
503
504        // Saturate edges not satisfying the optimality condition
505        Capacity delta;
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];
512          }
513          if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
514            _excess[_graph.target(e)] -= (*_flow)[e];
515            _excess[_graph.source(e)] += (*_flow)[e];
516            (*_flow)[e] = 0;
517          }
518        }
519
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);
523        }
524
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);
529          next_dir[n] = true;
530        }
531
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();
537            continue;
538          }
539          Node start = active_nodes[0];
540          path_nodes.clear();
541          path_nodes.push_back(start);
542
543          // Find an augmenting path from the start node
544          Node u, tip = start;
545          LCost min_red_cost;
546          while ( _excess[tip] >= 0 &&
547                  int(path_nodes.size()) <= MAX_PATH_LENGTH )
548          {
549            if (next_dir[tip]) {
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);
553                  pred_edge[u] = e;
554                  forward[u] = true;
555                  next_out[tip] = e;
556                  tip = u;
557                  path_nodes.push_back(tip);
558                  goto next_step;
559                }
560              }
561              next_dir[tip] = false;
562            }
563            for (InEdgeIt e = next_in[tip]; e != INVALID; ++e) {
564              if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
565                u = _graph.source(e);
566                pred_edge[u] = e;
567                forward[u] = false;
568                next_in[tip] = e;
569                tip = u;
570                path_nodes.push_back(tip);
571                goto next_step;
572              }
573            }
574
575            // Relabel tip node
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];
581            }
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];
585            }
586            (*_potential)[tip] -= min_red_cost + _epsilon;
587
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;
592
593            // Step back
594            if (tip != start) {
595              path_nodes.pop_back();
596              tip = path_nodes[path_nodes.size()-1];
597            }
598
599          next_step:
600            continue;
601          }
602
603          // Augment along the found path (as much flow as possible)
604          Capacity delta;
605          for (int i = 1; i < int(path_nodes.size()); ++i) {
606            u = path_nodes[i];
607            delta = forward[u] ?
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;
613            _excess[u] += delta;
614            if (_excess[u] > 0 && _excess[u] <= delta) active_nodes.push_back(u);
615          }
616        }
617      }
618
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);
626
627      // Handle non-zero lower bounds
628      if (_lower) {
629        for (EdgeIt e(_graph); e != INVALID; ++e)
630          (*_flow)[e] += (*_lower)[e];
631      }
632      return true;
633    }
634
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;
640
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;
648
649      int node_num = countNodes(_graph);
650      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
651                                        1 : _epsilon / _alpha )
652      {
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);
659          bf.init(0);
660          bool done = false;
661          int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(node_num));
662          for (int i = 0; i < K && !done; ++i)
663            done = bf.processNextWeakRound();
664          if (done) break;
665        }
666
667        // Saturate edges not satisfying the optimality condition
668        Capacity delta;
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];
675          }
676          if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
677            _excess[_graph.target(e)] -= (*_flow)[e];
678            _excess[_graph.source(e)] += (*_flow)[e];
679            (*_flow)[e] = 0;
680          }
681        }
682
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);
686        }
687
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);
692          next_dir[n] = true;
693        }
694
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;
700
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);
708
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];
714                }
715                for (InEdgeIt ie(_graph, t); ie != INVALID; ++ie) {
716                  if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
717                    ahead += (*_flow)[ie];
718                }
719                if (ahead < 0) ahead = 0;
720
721                // Push flow along the edge
722                if (ahead < delta) {
723                  (*_flow)[e] += ahead;
724                  _excess[n] -= ahead;
725                  _excess[t] += ahead;
726                  active_nodes.push_front(t);
727                  hyper[t] = true;
728                  relabel_enabled = false;
729                  break;
730                } else {
731                  (*_flow)[e] += delta;
732                  _excess[n] -= delta;
733                  _excess[t] += delta;
734                  if (_excess[t] > 0 && _excess[t] <= delta)
735                    active_nodes.push_back(t);
736                }
737
738                if (_excess[n] == 0) break;
739              }
740            }
741            if (e != INVALID) {
742              next_out[n] = e;
743            } else {
744              next_dir[n] = false;
745            }
746          }
747
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);
754
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];
760                }
761                for (InEdgeIt ie(_graph, t); ie != INVALID; ++ie) {
762                  if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
763                    ahead += (*_flow)[ie];
764                }
765                if (ahead < 0) ahead = 0;
766
767                // Push flow along the edge
768                if (ahead < delta) {
769                  (*_flow)[e] -= ahead;
770                  _excess[n] -= ahead;
771                  _excess[t] += ahead;
772                  active_nodes.push_front(t);
773                  hyper[t] = true;
774                  relabel_enabled = false;
775                  break;
776                } else {
777                  (*_flow)[e] -= delta;
778                  _excess[n] -= delta;
779                  _excess[t] += delta;
780                  if (_excess[t] > 0 && _excess[t] <= delta)
781                    active_nodes.push_back(t);
782                }
783
784                if (_excess[n] == 0) break;
785              }
786            }
787            next_in[n] = e;
788          }
789
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];
797            }
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];
801            }
802            (*_potential)[n] -= min_red_cost + _epsilon;
803            hyper[n] = false;
804
805            // Reset the next edge maps
806            next_out[n] = OutEdgeIt(_graph, n);
807            next_in[n] = InEdgeIt(_graph, n);
808            next_dir[n] = true;
809          }
810
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();
816          }
817        }
818      }
819
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);
827
828      // Handle non-zero lower bounds
829      if (_lower) {
830        for (EdgeIt e(_graph); e != INVALID; ++e)
831          (*_flow)[e] += (*_lower)[e];
832      }
833      return true;
834    }
835
836  }; //class CostScaling
837
838  ///@}
839
840} //namespace lemon
841
842#endif //LEMON_COST_SCALING_H
Note: See TracBrowser for help on using the repository browser.