COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/capacity_scaling.h @ 2533:aea952a1af99

Last change on this file since 2533:aea952a1af99 was 2533:aea952a1af99, checked in by Peter Kovacs, 16 years ago

Bug fixes.

File size: 20.8 KB
Line 
1/* -*- C++ -*-
2 *
3 * This file is a part of LEMON, a generic C++ optimization library
4 *
5 * Copyright (C) 2003-2007
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 *
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
12 *
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
15 * purpose.
16 *
17 */
18
19#ifndef LEMON_CAPACITY_SCALING_H
20#define LEMON_CAPACITY_SCALING_H
21
22/// \ingroup min_cost_flow
23///
24/// \file
25/// \brief The capacity scaling algorithm for finding a minimum cost
26/// flow.
27
28#include <vector>
29#include <lemon/graph_adaptor.h>
30#include <lemon/dijkstra.h>
31
32#define WITH_SCALING
33
34#ifdef WITH_SCALING
35#define SCALING_FACTOR    2
36#endif
37
38//#define _DEBUG_ITER_
39
40namespace lemon {
41
42  /// \addtogroup min_cost_flow
43  /// @{
44
45  /// \brief Implementation of the capacity scaling version of the
46  /// successive shortest path algorithm for finding a minimum cost
47  /// flow.
48  ///
49  /// \ref lemon::CapacityScaling "CapacityScaling" implements the
50  /// capacity scaling version of the successive shortest path
51  /// algorithm for finding a minimum cost flow.
52  ///
53  /// \param Graph The directed graph type the algorithm runs on.
54  /// \param LowerMap The type of the lower bound map.
55  /// \param CapacityMap The type of the capacity (upper bound) map.
56  /// \param CostMap The type of the cost (length) map.
57  /// \param SupplyMap The type of the supply map.
58  ///
59  /// \warning
60  /// - Edge capacities and costs should be nonnegative integers.
61  ///   However \c CostMap::Value should be signed type.
62  /// - Supply values should be signed integers.
63  /// - \c LowerMap::Value must be convertible to
64  ///   \c CapacityMap::Value and \c CapacityMap::Value must be
65  ///   convertible to \c SupplyMap::Value.
66  ///
67  /// \author Peter Kovacs
68
69  template < typename Graph,
70             typename LowerMap = typename Graph::template EdgeMap<int>,
71             typename CapacityMap = LowerMap,
72             typename CostMap = typename Graph::template EdgeMap<int>,
73             typename SupplyMap = typename Graph::template NodeMap
74                                  <typename CapacityMap::Value> >
75  class CapacityScaling
76  {
77    typedef typename Graph::Node Node;
78    typedef typename Graph::NodeIt NodeIt;
79    typedef typename Graph::Edge Edge;
80    typedef typename Graph::EdgeIt EdgeIt;
81    typedef typename Graph::InEdgeIt InEdgeIt;
82    typedef typename Graph::OutEdgeIt OutEdgeIt;
83
84    typedef typename LowerMap::Value Lower;
85    typedef typename CapacityMap::Value Capacity;
86    typedef typename CostMap::Value Cost;
87    typedef typename SupplyMap::Value Supply;
88    typedef typename Graph::template EdgeMap<Capacity> CapacityRefMap;
89    typedef typename Graph::template NodeMap<Supply> SupplyRefMap;
90
91    typedef ResGraphAdaptor< const Graph, Capacity,
92                             CapacityRefMap, CapacityRefMap > ResGraph;
93    typedef typename ResGraph::Node ResNode;
94    typedef typename ResGraph::NodeIt ResNodeIt;
95    typedef typename ResGraph::Edge ResEdge;
96    typedef typename ResGraph::EdgeIt ResEdgeIt;
97
98  public:
99
100    /// \brief The type of the flow map.
101    typedef CapacityRefMap FlowMap;
102    /// \brief The type of the potential map.
103    typedef typename Graph::template NodeMap<Cost> PotentialMap;
104
105  protected:
106
107    /// \brief Map adaptor class for handling reduced edge costs.
108    class ReducedCostMap : public MapBase<ResEdge, Cost>
109    {
110    private:
111
112      const ResGraph &gr;
113      const CostMap &cost_map;
114      const PotentialMap &pot_map;
115
116    public:
117
118      ReducedCostMap( const ResGraph &_gr,
119                      const CostMap &_cost,
120                      const PotentialMap &_pot ) :
121        gr(_gr), cost_map(_cost), pot_map(_pot) {}
122
123      Cost operator[](const ResEdge &e) const {
124        return ResGraph::forward(e) ?
125           cost_map[e] - pot_map[gr.source(e)] + pot_map[gr.target(e)] :
126          -cost_map[e] - pot_map[gr.source(e)] + pot_map[gr.target(e)];
127      }
128
129    }; //class ReducedCostMap
130
131    /// \brief Map class for the \ref lemon::Dijkstra "Dijkstra"
132    /// algorithm to update node potentials.
133    class PotentialUpdateMap : public MapBase<ResNode, Cost>
134    {
135    private:
136
137      PotentialMap *pot;
138      typedef std::pair<ResNode, Cost> Pair;
139      std::vector<Pair> data;
140
141    public:
142
143      void potentialMap(PotentialMap &_pot) {
144        pot = &_pot;
145      }
146
147      void init() {
148        data.clear();
149      }
150
151      void set(const ResNode &n, const Cost &v) {
152        data.push_back(Pair(n, v));
153      }
154
155      void update() {
156        Cost val = data[data.size()-1].second;
157        for (int i = 0; i < data.size()-1; ++i)
158          (*pot)[data[i].first] += val - data[i].second;
159      }
160
161    }; //class PotentialUpdateMap
162
163#ifdef WITH_SCALING
164    /// \brief Map adaptor class for identifing deficit nodes.
165    class DeficitBoolMap : public MapBase<ResNode, bool>
166    {
167    private:
168
169      const SupplyRefMap &imb;
170      const Capacity &delta;
171
172    public:
173
174      DeficitBoolMap(const SupplyRefMap &_imb, const Capacity &_delta) :
175        imb(_imb), delta(_delta) {}
176
177      bool operator[](const ResNode &n) const {
178        return imb[n] <= -delta;
179      }
180
181    }; //class DeficitBoolMap
182
183    /// \brief Map adaptor class for filtering edges with at least
184    /// \c delta residual capacity.
185    class DeltaFilterMap : public MapBase<ResEdge, bool>
186    {
187    private:
188
189      const ResGraph &gr;
190      const Capacity &delta;
191
192    public:
193
194      DeltaFilterMap(const ResGraph &_gr, const Capacity &_delta) :
195        gr(_gr), delta(_delta) {}
196
197      bool operator[](const ResEdge &e) const {
198        return gr.rescap(e) >= delta;
199      }
200
201    }; //class DeltaFilterMap
202
203    typedef EdgeSubGraphAdaptor<const ResGraph, const DeltaFilterMap>
204      DeltaResGraph;
205
206    /// \brief Traits class for \ref lemon::Dijkstra "Dijkstra" class.
207    class ResDijkstraTraits :
208      public DijkstraDefaultTraits<DeltaResGraph, ReducedCostMap>
209    {
210    public:
211
212      typedef PotentialUpdateMap DistMap;
213
214      static DistMap *createDistMap(const DeltaResGraph&) {
215        return new DistMap();
216      }
217
218    }; //class ResDijkstraTraits
219
220#else //WITHOUT_CAPACITY_SCALING
221    /// \brief Map adaptor class for identifing deficit nodes.
222    class DeficitBoolMap : public MapBase<ResNode, bool>
223    {
224    private:
225
226      const SupplyRefMap &imb;
227
228    public:
229
230      DeficitBoolMap(const SupplyRefMap &_imb) : imb(_imb) {}
231
232      bool operator[](const ResNode &n) const {
233        return imb[n] < 0;
234      }
235
236    }; //class DeficitBoolMap
237
238    /// \brief Traits class for \ref lemon::Dijkstra "Dijkstra" class.
239    class ResDijkstraTraits :
240      public DijkstraDefaultTraits<ResGraph, ReducedCostMap>
241    {
242    public:
243
244      typedef PotentialUpdateMap DistMap;
245
246      static DistMap *createDistMap(const ResGraph&) {
247        return new DistMap();
248      }
249
250    }; //class ResDijkstraTraits
251#endif
252
253  protected:
254
255    /// \brief The directed graph the algorithm runs on.
256    const Graph &graph;
257    /// \brief The original lower bound map.
258    const LowerMap *lower;
259    /// \brief The modified capacity map.
260    CapacityRefMap capacity;
261    /// \brief The cost map.
262    const CostMap &cost;
263    /// \brief The modified supply map.
264    SupplyRefMap supply;
265    /// \brief The sum of supply values equals zero.
266    bool valid_supply;
267
268    /// \brief The edge map of the current flow.
269    FlowMap flow;
270    /// \brief The potential node map.
271    PotentialMap potential;
272    /// \brief The residual graph.
273    ResGraph res_graph;
274    /// \brief The reduced cost map.
275    ReducedCostMap red_cost;
276
277    /// \brief The imbalance map.
278    SupplyRefMap imbalance;
279    /// \brief The excess nodes.
280    std::vector<ResNode> excess_nodes;
281    /// \brief The index of the next excess node.
282    int next_node;
283
284#ifdef WITH_SCALING
285    typedef Dijkstra<DeltaResGraph, ReducedCostMap, ResDijkstraTraits>
286      ResDijkstra;
287    /// \brief \ref lemon::Dijkstra "Dijkstra" class for finding
288    /// shortest paths in the residual graph with respect to the
289    /// reduced edge costs.
290    ResDijkstra dijkstra;
291
292    /// \brief The delta parameter used for capacity scaling.
293    Capacity delta;
294    /// \brief Edge filter map for filtering edges with at least
295    /// \c delta residual capacity.
296    DeltaFilterMap delta_filter;
297    /// \brief The delta residual graph (i.e. the subgraph of the
298    /// residual graph consisting of edges with at least \c delta
299    /// residual capacity).
300    DeltaResGraph dres_graph;
301    /// \brief Map for identifing deficit nodes.
302    DeficitBoolMap delta_deficit;
303
304    /// \brief The deficit nodes.
305    std::vector<ResNode> deficit_nodes;
306
307#else //WITHOUT_CAPACITY_SCALING
308    typedef Dijkstra<ResGraph, ReducedCostMap, ResDijkstraTraits>
309      ResDijkstra;
310    /// \brief \ref lemon::Dijkstra "Dijkstra" class for finding
311    /// shortest paths in the residual graph with respect to the
312    /// reduced edge costs.
313    ResDijkstra dijkstra;
314    /// \brief Map for identifing deficit nodes.
315    DeficitBoolMap has_deficit;
316#endif
317
318    /// \brief Pred map for the \ref lemon::Dijkstra "Dijkstra" class.
319    typename ResDijkstra::PredMap pred;
320    /// \brief Dist map for the \ref lemon::Dijkstra "Dijkstra" class to
321    /// update node potentials.
322    PotentialUpdateMap updater;
323
324  public :
325
326    /// \brief General constructor of the class (with lower bounds).
327    ///
328    /// General constructor of the class (with lower bounds).
329    ///
330    /// \param _graph The directed graph the algorithm runs on.
331    /// \param _lower The lower bounds of the edges.
332    /// \param _capacity The capacities (upper bounds) of the edges.
333    /// \param _cost The cost (length) values of the edges.
334    /// \param _supply The supply values of the nodes (signed).
335    CapacityScaling( const Graph &_graph,
336                     const LowerMap &_lower,
337                     const CapacityMap &_capacity,
338                     const CostMap &_cost,
339                     const SupplyMap &_supply ) :
340      graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
341      supply(_graph), flow(_graph, 0), potential(_graph, 0),
342      res_graph(_graph, capacity, flow),
343      red_cost(res_graph, cost, potential), imbalance(_graph),
344#ifdef WITH_SCALING
345      delta(0), delta_filter(res_graph, delta),
346      dres_graph(res_graph, delta_filter),
347      dijkstra(dres_graph, red_cost), pred(dres_graph),
348      delta_deficit(imbalance, delta)
349#else //WITHOUT_CAPACITY_SCALING
350      dijkstra(res_graph, red_cost), pred(res_graph),
351      has_deficit(imbalance)
352#endif
353    {
354      // Removing nonzero lower bounds
355      capacity = subMap(_capacity, _lower);
356      Supply sum = 0;
357      for (NodeIt n(graph); n != INVALID; ++n) {
358        Supply s = _supply[n];
359        for (InEdgeIt e(graph, n); e != INVALID; ++e)
360          s += _lower[e];
361        for (OutEdgeIt e(graph, n); e != INVALID; ++e)
362          s -= _lower[e];
363        supply[n] = s;
364        sum += s;
365      }
366      valid_supply = sum == 0;
367    }
368
369    /// \brief General constructor of the class (without lower bounds).
370    ///
371    /// General constructor of the class (without lower bounds).
372    ///
373    /// \param _graph The directed graph the algorithm runs on.
374    /// \param _capacity The capacities (upper bounds) of the edges.
375    /// \param _cost The cost (length) values of the edges.
376    /// \param _supply The supply values of the nodes (signed).
377    CapacityScaling( const Graph &_graph,
378                     const CapacityMap &_capacity,
379                     const CostMap &_cost,
380                     const SupplyMap &_supply ) :
381      graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
382      supply(_supply), flow(_graph, 0), potential(_graph, 0),
383      res_graph(_graph, capacity, flow),
384      red_cost(res_graph, cost, potential), imbalance(_graph),
385#ifdef WITH_SCALING
386      delta(0), delta_filter(res_graph, delta),
387      dres_graph(res_graph, delta_filter),
388      dijkstra(dres_graph, red_cost), pred(dres_graph),
389      delta_deficit(imbalance, delta)
390#else //WITHOUT_CAPACITY_SCALING
391      dijkstra(res_graph, red_cost), pred(res_graph),
392      has_deficit(imbalance)
393#endif
394    {
395      // Checking the sum of supply values
396      Supply sum = 0;
397      for (NodeIt n(graph); n != INVALID; ++n) sum += supply[n];
398      valid_supply = sum == 0;
399    }
400
401    /// \brief Simple constructor of the class (with lower bounds).
402    ///
403    /// Simple constructor of the class (with lower bounds).
404    ///
405    /// \param _graph The directed graph the algorithm runs on.
406    /// \param _lower The lower bounds of the edges.
407    /// \param _capacity The capacities (upper bounds) of the edges.
408    /// \param _cost The cost (length) values of the edges.
409    /// \param _s The source node.
410    /// \param _t The target node.
411    /// \param _flow_value The required amount of flow from node \c _s
412    /// to node \c _t (i.e. the supply of \c _s and the demand of
413    /// \c _t).
414    CapacityScaling( const Graph &_graph,
415                     const LowerMap &_lower,
416                     const CapacityMap &_capacity,
417                     const CostMap &_cost,
418                     Node _s, Node _t,
419                     Supply _flow_value ) :
420      graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
421      supply(_graph), flow(_graph, 0), potential(_graph, 0),
422      res_graph(_graph, capacity, flow),
423      red_cost(res_graph, cost, potential), imbalance(_graph),
424#ifdef WITH_SCALING
425      delta(0), delta_filter(res_graph, delta),
426      dres_graph(res_graph, delta_filter),
427      dijkstra(dres_graph, red_cost), pred(dres_graph),
428      delta_deficit(imbalance, delta)
429#else //WITHOUT_CAPACITY_SCALING
430      dijkstra(res_graph, red_cost), pred(res_graph),
431      has_deficit(imbalance)
432#endif
433    {
434      // Removing nonzero lower bounds
435      capacity = subMap(_capacity, _lower);
436      for (NodeIt n(graph); n != INVALID; ++n) {
437        Supply s = 0;
438        if (n == _s) s =  _flow_value;
439        if (n == _t) s = -_flow_value;
440        for (InEdgeIt e(graph, n); e != INVALID; ++e)
441          s += _lower[e];
442        for (OutEdgeIt e(graph, n); e != INVALID; ++e)
443          s -= _lower[e];
444        supply[n] = s;
445      }
446      valid_supply = true;
447    }
448
449    /// \brief Simple constructor of the class (without lower bounds).
450    ///
451    /// Simple constructor of the class (without lower bounds).
452    ///
453    /// \param _graph The directed graph the algorithm runs on.
454    /// \param _capacity The capacities (upper bounds) of the edges.
455    /// \param _cost The cost (length) values of the edges.
456    /// \param _s The source node.
457    /// \param _t The target node.
458    /// \param _flow_value The required amount of flow from node \c _s
459    /// to node \c _t (i.e. the supply of \c _s and the demand of
460    /// \c _t).
461    CapacityScaling( const Graph &_graph,
462                     const CapacityMap &_capacity,
463                     const CostMap &_cost,
464                     Node _s, Node _t,
465                     Supply _flow_value ) :
466      graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
467      supply(_graph, 0), flow(_graph, 0), potential(_graph, 0),
468      res_graph(_graph, capacity, flow),
469      red_cost(res_graph, cost, potential), imbalance(_graph),
470#ifdef WITH_SCALING
471      delta(0), delta_filter(res_graph, delta),
472      dres_graph(res_graph, delta_filter),
473      dijkstra(dres_graph, red_cost), pred(dres_graph),
474      delta_deficit(imbalance, delta)
475#else //WITHOUT_CAPACITY_SCALING
476      dijkstra(res_graph, red_cost), pred(res_graph),
477      has_deficit(imbalance)
478#endif
479    {
480      supply[_s] =  _flow_value;
481      supply[_t] = -_flow_value;
482      valid_supply = true;
483    }
484
485    /// \brief Returns a const reference to the flow map.
486    ///
487    /// Returns a const reference to the flow map.
488    ///
489    /// \pre \ref run() must be called before using this function.
490    const FlowMap& flowMap() const {
491      return flow;
492    }
493
494    /// \brief Returns a const reference to the potential map (the dual
495    /// solution).
496    ///
497    /// Returns a const reference to the potential map (the dual
498    /// solution).
499    ///
500    /// \pre \ref run() must be called before using this function.
501    const PotentialMap& potentialMap() const {
502      return potential;
503    }
504
505    /// \brief Returns the total cost of the found flow.
506    ///
507    /// Returns the total cost of the found flow. The complexity of the
508    /// function is \f$ O(e) \f$.
509    ///
510    /// \pre \ref run() must be called before using this function.
511    Cost totalCost() const {
512      Cost c = 0;
513      for (EdgeIt e(graph); e != INVALID; ++e)
514        c += flow[e] * cost[e];
515      return c;
516    }
517
518    /// \brief Runs the algorithm.
519    ///
520    /// Runs the algorithm.
521    ///
522    /// \return \c true if a feasible flow can be found.
523    bool run() {
524      return init() && start();
525    }
526
527  protected:
528
529    /// \brief Initializes the algorithm.
530    bool init() {
531      if (!valid_supply) return false;
532      imbalance = supply;
533
534      // Initalizing Dijkstra class
535      updater.potentialMap(potential);
536      dijkstra.distMap(updater).predMap(pred);
537
538#ifdef WITH_SCALING
539      // Initilaizing delta value
540      Supply max_sup = 0, max_dem = 0;
541      for (NodeIt n(graph); n != INVALID; ++n) {
542        if (supply[n] >  max_sup) max_sup =  supply[n];
543        if (supply[n] < -max_dem) max_dem = -supply[n];
544      }
545      if (max_dem < max_sup) max_sup = max_dem;
546      for ( delta = 1; SCALING_FACTOR * delta < max_sup;
547            delta *= SCALING_FACTOR ) ;
548#endif
549      return true;
550    }
551
552#ifdef WITH_SCALING
553    /// \brief Executes the capacity scaling version of the successive
554    /// shortest path algorithm.
555    bool start() {
556      typedef typename DeltaResGraph::EdgeIt DeltaResEdgeIt;
557      typedef typename DeltaResGraph::Edge DeltaResEdge;
558#ifdef _DEBUG_ITER_
559      int dijk_num = 0;
560#endif
561
562      // Processing capacity scaling phases
563      ResNode s, t;
564      for ( ; delta >= 1; delta = delta < SCALING_FACTOR && delta > 1 ?
565                                  1 : delta / SCALING_FACTOR )
566      {
567        // Saturating edges not satisfying the optimality condition
568        Capacity r;
569        for (DeltaResEdgeIt e(dres_graph); e != INVALID; ++e) {
570          if (red_cost[e] < 0) {
571            res_graph.augment(e, r = res_graph.rescap(e));
572            imbalance[dres_graph.source(e)] -= r;
573            imbalance[dres_graph.target(e)] += r;
574          }
575        }
576
577        // Finding excess nodes
578        excess_nodes.clear();
579        deficit_nodes.clear();
580        for (ResNodeIt n(res_graph); n != INVALID; ++n) {
581          if (imbalance[n] >=  delta) excess_nodes.push_back(n);
582          if (imbalance[n] <= -delta) deficit_nodes.push_back(n);
583        }
584        next_node = 0;
585
586        // Finding shortest paths
587        while (next_node < excess_nodes.size()) {
588          // Checking deficit nodes
589          if (delta > 1) {
590            bool delta_def = false;
591            for (int i = 0; i < deficit_nodes.size(); ++i) {
592              if (imbalance[deficit_nodes[i]] <= -delta) {
593                delta_def = true;
594                break;
595              }
596            }
597            if (!delta_def) break;
598          }
599
600          // Running Dijkstra
601          s = excess_nodes[next_node];
602          updater.init();
603          dijkstra.init();
604          dijkstra.addSource(s);
605#ifdef _DEBUG_ITER_
606          ++dijk_num;
607#endif
608          if ((t = dijkstra.start(delta_deficit)) == INVALID) {
609            if (delta > 1) {
610              ++next_node;
611              continue;
612            }
613            return false;
614          }
615
616          // Updating node potentials
617          updater.update();
618
619          // Augment along a shortest path from s to t
620          Capacity d = imbalance[s] < -imbalance[t] ?
621            imbalance[s] : -imbalance[t];
622          ResNode u = t;
623          ResEdge e;
624          if (d > delta) {
625            while ((e = pred[u]) != INVALID) {
626              if (res_graph.rescap(e) < d) d = res_graph.rescap(e);
627              u = dres_graph.source(e);
628            }
629          }
630          u = t;
631          while ((e = pred[u]) != INVALID) {
632            res_graph.augment(e, d);
633            u = dres_graph.source(e);
634          }
635          imbalance[s] -= d;
636          imbalance[t] += d;
637          if (imbalance[s] < delta) ++next_node;
638        }
639      }
640#ifdef _DEBUG_ITER_
641      std::cout << "Capacity Scaling algorithm finished with running Dijkstra algorithm "
642        << dijk_num << " times." << std::endl;
643#endif
644
645      // Handling nonzero lower bounds
646      if (lower) {
647        for (EdgeIt e(graph); e != INVALID; ++e)
648          flow[e] += (*lower)[e];
649      }
650      return true;
651    }
652
653#else //WITHOUT_CAPACITY_SCALING
654    /// \brief Executes the successive shortest path algorithm without
655    /// capacity scaling.
656    bool start() {
657      // Finding excess nodes
658      for (ResNodeIt n(res_graph); n != INVALID; ++n) {
659        if (imbalance[n] > 0) excess_nodes.push_back(n);
660      }
661      if (excess_nodes.size() == 0) return true;
662      next_node = 0;
663
664      // Finding shortest paths
665      ResNode s, t;
666      while ( imbalance[excess_nodes[next_node]] > 0 ||
667              ++next_node < excess_nodes.size() )
668      {
669        // Running Dijkstra
670        s = excess_nodes[next_node];
671        updater.init();
672        dijkstra.init();
673        dijkstra.addSource(s);
674        if ((t = dijkstra.start(has_deficit)) == INVALID)
675          return false;
676
677        // Updating node potentials
678        updater.update();
679
680        // Augmenting along a shortest path from s to t
681        Capacity delta = imbalance[s] < -imbalance[t] ?
682          imbalance[s] : -imbalance[t];
683        ResNode u = t;
684        ResEdge e;
685        while ((e = pred[u]) != INVALID) {
686          if (res_graph.rescap(e) < delta) delta = res_graph.rescap(e);
687          u = res_graph.source(e);
688        }
689        u = t;
690        while ((e = pred[u]) != INVALID) {
691          res_graph.augment(e, delta);
692          u = res_graph.source(e);
693        }
694        imbalance[s] -= delta;
695        imbalance[t] += delta;
696      }
697
698      // Handling nonzero lower bounds
699      if (lower) {
700        for (EdgeIt e(graph); e != INVALID; ++e)
701          flow[e] += (*lower)[e];
702      }
703      return true;
704    }
705#endif
706
707  }; //class CapacityScaling
708
709  ///@}
710
711} //namespace lemon
712
713#endif //LEMON_CAPACITY_SCALING_H
Note: See TracBrowser for help on using the repository browser.