COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/capacity_scaling.h @ 2588:4d3bc1d04c1d

Last change on this file since 2588:4d3bc1d04c1d was 2588:4d3bc1d04c1d, checked in by Peter Kovacs, 16 years ago

Small improvements in min cost flow files.

File size: 21.9 KB
RevLine 
[2440]1/* -*- C++ -*-
2 *
3 * This file is a part of LEMON, a generic C++ optimization library
4 *
[2553]5 * Copyright (C) 2003-2008
[2440]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
[2574]25/// \brief Capacity scaling algorithm for finding a minimum cost flow.
26
27#include <vector>
[2535]28#include <lemon/bin_heap.h>
[2457]29
[2440]30namespace lemon {
31
32  /// \addtogroup min_cost_flow
33  /// @{
34
[2574]35  /// \brief Implementation of the capacity scaling algorithm for
36  /// finding a minimum cost flow.
[2440]37  ///
[2535]38  /// \ref CapacityScaling implements the capacity scaling version
39  /// of the successive shortest path algorithm for finding a minimum
40  /// cost flow.
[2440]41  ///
[2574]42  /// \tparam Graph The directed graph type the algorithm runs on.
43  /// \tparam LowerMap The type of the lower bound map.
44  /// \tparam CapacityMap The type of the capacity (upper bound) map.
45  /// \tparam CostMap The type of the cost (length) map.
46  /// \tparam SupplyMap The type of the supply map.
[2440]47  ///
48  /// \warning
[2574]49  /// - Edge capacities and costs should be \e non-negative \e integers.
50  /// - Supply values should be \e signed \e integers.
[2581]51  /// - The value types of the maps should be convertible to each other.
52  /// - \c CostMap::Value must be signed type.
[2440]53  ///
54  /// \author Peter Kovacs
55
[2533]56  template < typename Graph,
[2535]57             typename LowerMap = typename Graph::template EdgeMap<int>,
[2574]58             typename CapacityMap = typename Graph::template EdgeMap<int>,
[2535]59             typename CostMap = typename Graph::template EdgeMap<int>,
[2574]60             typename SupplyMap = typename Graph::template NodeMap<int> >
[2440]61  class CapacityScaling
62  {
[2556]63    GRAPH_TYPEDEFS(typename Graph);
[2440]64
65    typedef typename CapacityMap::Value Capacity;
66    typedef typename CostMap::Value Cost;
67    typedef typename SupplyMap::Value Supply;
[2556]68    typedef typename Graph::template EdgeMap<Capacity> CapacityEdgeMap;
69    typedef typename Graph::template NodeMap<Supply> SupplyNodeMap;
[2535]70    typedef typename Graph::template NodeMap<Edge> PredMap;
[2440]71
72  public:
73
[2556]74    /// The type of the flow map.
75    typedef typename Graph::template EdgeMap<Capacity> FlowMap;
76    /// The type of the potential map.
[2440]77    typedef typename Graph::template NodeMap<Cost> PotentialMap;
78
[2574]79  private:
[2440]80
[2535]81    /// \brief Special implementation of the \ref Dijkstra algorithm
[2574]82    /// for finding shortest paths in the residual network.
83    ///
84    /// \ref ResidualDijkstra is a special implementation of the
85    /// \ref Dijkstra algorithm for finding shortest paths in the
86    /// residual network of the graph with respect to the reduced edge
87    /// costs and modifying the node potentials according to the
88    /// distance of the nodes.
[2535]89    class ResidualDijkstra
[2440]90    {
[2535]91      typedef typename Graph::template NodeMap<int> HeapCrossRef;
92      typedef BinHeap<Cost, HeapCrossRef> Heap;
93
[2574]94    private:
[2535]95
[2574]96      // The directed graph the algorithm runs on
97      const Graph &_graph;
[2535]98
[2574]99      // The main maps
100      const FlowMap &_flow;
101      const CapacityEdgeMap &_res_cap;
102      const CostMap &_cost;
103      const SupplyNodeMap &_excess;
104      PotentialMap &_potential;
[2535]105
[2574]106      // The distance map
[2588]107      PotentialMap _dist;
[2574]108      // The pred edge map
109      PredMap &_pred;
110      // The processed (i.e. permanently labeled) nodes
111      std::vector<Node> _proc_nodes;
[2440]112
113    public:
114
[2581]115      /// Constructor.
[2574]116      ResidualDijkstra( const Graph &graph,
117                        const FlowMap &flow,
118                        const CapacityEdgeMap &res_cap,
119                        const CostMap &cost,
120                        const SupplyMap &excess,
121                        PotentialMap &potential,
122                        PredMap &pred ) :
123        _graph(graph), _flow(flow), _res_cap(res_cap), _cost(cost),
124        _excess(excess), _potential(potential), _dist(graph),
125        _pred(pred)
[2535]126      {}
[2440]127
[2556]128      /// Runs the algorithm from the given source node.
[2588]129      Node run(Node s, Capacity delta = 1) {
[2574]130        HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
[2535]131        Heap heap(heap_cross_ref);
132        heap.push(s, 0);
[2574]133        _pred[s] = INVALID;
134        _proc_nodes.clear();
[2535]135
136        // Processing nodes
[2574]137        while (!heap.empty() && _excess[heap.top()] > -delta) {
[2535]138          Node u = heap.top(), v;
[2574]139          Cost d = heap.prio() + _potential[u], nd;
140          _dist[u] = heap.prio();
[2535]141          heap.pop();
[2574]142          _proc_nodes.push_back(u);
[2535]143
144          // Traversing outgoing edges
[2574]145          for (OutEdgeIt e(_graph, u); e != INVALID; ++e) {
146            if (_res_cap[e] >= delta) {
147              v = _graph.target(e);
[2535]148              switch(heap.state(v)) {
149              case Heap::PRE_HEAP:
[2574]150                heap.push(v, d + _cost[e] - _potential[v]);
151                _pred[v] = e;
[2535]152                break;
153              case Heap::IN_HEAP:
[2574]154                nd = d + _cost[e] - _potential[v];
[2535]155                if (nd < heap[v]) {
156                  heap.decrease(v, nd);
[2574]157                  _pred[v] = e;
[2535]158                }
159                break;
160              case Heap::POST_HEAP:
161                break;
162              }
163            }
164          }
165
166          // Traversing incoming edges
[2574]167          for (InEdgeIt e(_graph, u); e != INVALID; ++e) {
168            if (_flow[e] >= delta) {
169              v = _graph.source(e);
[2535]170              switch(heap.state(v)) {
171              case Heap::PRE_HEAP:
[2574]172                heap.push(v, d - _cost[e] - _potential[v]);
173                _pred[v] = e;
[2535]174                break;
175              case Heap::IN_HEAP:
[2574]176                nd = d - _cost[e] - _potential[v];
[2535]177                if (nd < heap[v]) {
178                  heap.decrease(v, nd);
[2574]179                  _pred[v] = e;
[2535]180                }
181                break;
182              case Heap::POST_HEAP:
183                break;
184              }
185            }
186          }
187        }
188        if (heap.empty()) return INVALID;
189
190        // Updating potentials of processed nodes
191        Node t = heap.top();
[2574]192        Cost t_dist = heap.prio();
193        for (int i = 0; i < int(_proc_nodes.size()); ++i)
194          _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
[2535]195
196        return t;
[2440]197      }
198
[2535]199    }; //class ResidualDijkstra
[2440]200
[2574]201  private:
[2440]202
[2574]203    // The directed graph the algorithm runs on
204    const Graph &_graph;
205    // The original lower bound map
206    const LowerMap *_lower;
207    // The modified capacity map
208    CapacityEdgeMap _capacity;
209    // The original cost map
210    const CostMap &_cost;
211    // The modified supply map
212    SupplyNodeMap _supply;
213    bool _valid_supply;
[2440]214
[2574]215    // Edge map of the current flow
[2581]216    FlowMap *_flow;
217    bool _local_flow;
[2574]218    // Node map of the current potentials
[2581]219    PotentialMap *_potential;
220    bool _local_potential;
[2440]221
[2574]222    // The residual capacity map
223    CapacityEdgeMap _res_cap;
224    // The excess map
225    SupplyNodeMap _excess;
226    // The excess nodes (i.e. nodes with positive excess)
227    std::vector<Node> _excess_nodes;
228    // The deficit nodes (i.e. nodes with negative excess)
229    std::vector<Node> _deficit_nodes;
[2440]230
[2574]231    // The delta parameter used for capacity scaling
232    Capacity _delta;
233    // The maximum number of phases
234    int _phase_num;
[2440]235
[2574]236    // The pred edge map
237    PredMap _pred;
238    // Implementation of the Dijkstra algorithm for finding augmenting
239    // shortest paths in the residual network
[2581]240    ResidualDijkstra *_dijkstra;
[2440]241
[2581]242  public:
[2440]243
[2581]244    /// \brief General constructor (with lower bounds).
[2440]245    ///
[2581]246    /// General constructor (with lower bounds).
[2440]247    ///
[2574]248    /// \param graph The directed graph the algorithm runs on.
249    /// \param lower The lower bounds of the edges.
250    /// \param capacity The capacities (upper bounds) of the edges.
251    /// \param cost The cost (length) values of the edges.
252    /// \param supply The supply values of the nodes (signed).
253    CapacityScaling( const Graph &graph,
254                     const LowerMap &lower,
255                     const CapacityMap &capacity,
256                     const CostMap &cost,
257                     const SupplyMap &supply ) :
258      _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
[2581]259      _supply(graph), _flow(0), _local_flow(false),
260      _potential(0), _local_potential(false),
261      _res_cap(graph), _excess(graph), _pred(graph)
[2440]262    {
[2556]263      // Removing non-zero lower bounds
[2574]264      _capacity = subMap(capacity, lower);
265      _res_cap = _capacity;
[2440]266      Supply sum = 0;
[2574]267      for (NodeIt n(_graph); n != INVALID; ++n) {
268        Supply s = supply[n];
269        for (InEdgeIt e(_graph, n); e != INVALID; ++e)
270          s += lower[e];
271        for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
272          s -= lower[e];
273        _supply[n] = s;
[2535]274        sum += s;
[2440]275      }
[2574]276      _valid_supply = sum == 0;
[2440]277    }
278
[2581]279    /// \brief General constructor (without lower bounds).
[2440]280    ///
[2581]281    /// General constructor (without lower bounds).
[2440]282    ///
[2574]283    /// \param graph The directed graph the algorithm runs on.
284    /// \param capacity The capacities (upper bounds) of the edges.
285    /// \param cost The cost (length) values of the edges.
286    /// \param supply The supply values of the nodes (signed).
287    CapacityScaling( const Graph &graph,
288                     const CapacityMap &capacity,
289                     const CostMap &cost,
290                     const SupplyMap &supply ) :
291      _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
[2581]292      _supply(supply), _flow(0), _local_flow(false),
293      _potential(0), _local_potential(false),
294      _res_cap(capacity), _excess(graph), _pred(graph)
[2440]295    {
296      // Checking the sum of supply values
297      Supply sum = 0;
[2574]298      for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
299      _valid_supply = sum == 0;
[2440]300    }
301
[2581]302    /// \brief Simple constructor (with lower bounds).
[2440]303    ///
[2581]304    /// Simple constructor (with lower bounds).
[2440]305    ///
[2574]306    /// \param graph The directed graph the algorithm runs on.
307    /// \param lower The lower bounds of the edges.
308    /// \param capacity The capacities (upper bounds) of the edges.
309    /// \param cost The cost (length) values of the edges.
310    /// \param s The source node.
311    /// \param t The target node.
312    /// \param flow_value The required amount of flow from node \c s
313    /// to node \c t (i.e. the supply of \c s and the demand of \c t).
314    CapacityScaling( const Graph &graph,
315                     const LowerMap &lower,
316                     const CapacityMap &capacity,
317                     const CostMap &cost,
318                     Node s, Node t,
319                     Supply flow_value ) :
320      _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
[2581]321      _supply(graph), _flow(0), _local_flow(false),
322      _potential(0), _local_potential(false),
323      _res_cap(graph), _excess(graph), _pred(graph)
[2440]324    {
[2556]325      // Removing non-zero lower bounds
[2574]326      _capacity = subMap(capacity, lower);
327      _res_cap = _capacity;
328      for (NodeIt n(_graph); n != INVALID; ++n) {
329        Supply sum = 0;
330        if (n == s) sum =  flow_value;
331        if (n == t) sum = -flow_value;
332        for (InEdgeIt e(_graph, n); e != INVALID; ++e)
333          sum += lower[e];
334        for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
335          sum -= lower[e];
336        _supply[n] = sum;
[2440]337      }
[2574]338      _valid_supply = true;
[2440]339    }
340
[2581]341    /// \brief Simple constructor (without lower bounds).
[2440]342    ///
[2581]343    /// Simple constructor (without lower bounds).
[2440]344    ///
[2574]345    /// \param graph The directed graph the algorithm runs on.
346    /// \param capacity The capacities (upper bounds) of the edges.
347    /// \param cost The cost (length) values of the edges.
348    /// \param s The source node.
349    /// \param t The target node.
350    /// \param flow_value The required amount of flow from node \c s
351    /// to node \c t (i.e. the supply of \c s and the demand of \c t).
352    CapacityScaling( const Graph &graph,
353                     const CapacityMap &capacity,
354                     const CostMap &cost,
355                     Node s, Node t,
356                     Supply flow_value ) :
357      _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
[2581]358      _supply(graph, 0), _flow(0), _local_flow(false),
359      _potential(0), _local_potential(false),
360      _res_cap(capacity), _excess(graph), _pred(graph)
[2440]361    {
[2574]362      _supply[s] =  flow_value;
363      _supply[t] = -flow_value;
364      _valid_supply = true;
[2440]365    }
366
[2581]367    /// Destructor.
368    ~CapacityScaling() {
369      if (_local_flow) delete _flow;
370      if (_local_potential) delete _potential;
371      delete _dijkstra;
372    }
373
374    /// \brief Sets the flow map.
375    ///
376    /// Sets the flow map.
377    ///
378    /// \return \c (*this)
379    CapacityScaling& flowMap(FlowMap &map) {
380      if (_local_flow) {
381        delete _flow;
382        _local_flow = false;
383      }
384      _flow = &map;
385      return *this;
386    }
387
388    /// \brief Sets the potential map.
389    ///
390    /// Sets the potential map.
391    ///
392    /// \return \c (*this)
393    CapacityScaling& potentialMap(PotentialMap &map) {
394      if (_local_potential) {
395        delete _potential;
396        _local_potential = false;
397      }
398      _potential = &map;
399      return *this;
400    }
401
402    /// \name Execution control
403    /// The only way to execute the algorithm is to call the run()
404    /// function.
405
406    /// @{
407
[2556]408    /// \brief Runs the algorithm.
409    ///
410    /// Runs the algorithm.
411    ///
[2574]412    /// \param scaling Enable or disable capacity scaling.
[2556]413    /// If the maximum edge capacity and/or the amount of total supply
[2574]414    /// is rather small, the algorithm could be slightly faster without
[2556]415    /// scaling.
416    ///
417    /// \return \c true if a feasible flow can be found.
[2574]418    bool run(bool scaling = true) {
419      return init(scaling) && start();
[2556]420    }
421
[2581]422    /// @}
423
424    /// \name Query Functions
425    /// The result of the algorithm can be obtained using these
426    /// functions.
427    /// \n run() must be called before using them.
428
429    /// @{
430
[2574]431    /// \brief Returns a const reference to the edge map storing the
432    /// found flow.
[2440]433    ///
[2574]434    /// Returns a const reference to the edge map storing the found flow.
[2440]435    ///
436    /// \pre \ref run() must be called before using this function.
437    const FlowMap& flowMap() const {
[2581]438      return *_flow;
[2440]439    }
440
[2574]441    /// \brief Returns a const reference to the node map storing the
442    /// found potentials (the dual solution).
[2440]443    ///
[2574]444    /// Returns a const reference to the node map storing the found
445    /// potentials (the dual solution).
[2440]446    ///
447    /// \pre \ref run() must be called before using this function.
448    const PotentialMap& potentialMap() const {
[2581]449      return *_potential;
450    }
451
[2588]452    /// \brief Returns the flow on the given edge.
[2581]453    ///
[2588]454    /// Returns the flow on the given edge.
[2581]455    ///
456    /// \pre \ref run() must be called before using this function.
457    Capacity flow(const Edge& edge) const {
458      return (*_flow)[edge];
459    }
460
[2588]461    /// \brief Returns the potential of the given node.
[2581]462    ///
[2588]463    /// Returns the potential of the given node.
[2581]464    ///
465    /// \pre \ref run() must be called before using this function.
466    Cost potential(const Node& node) const {
467      return (*_potential)[node];
[2440]468    }
469
470    /// \brief Returns the total cost of the found flow.
471    ///
472    /// Returns the total cost of the found flow. The complexity of the
473    /// function is \f$ O(e) \f$.
474    ///
475    /// \pre \ref run() must be called before using this function.
476    Cost totalCost() const {
477      Cost c = 0;
[2574]478      for (EdgeIt e(_graph); e != INVALID; ++e)
[2581]479        c += (*_flow)[e] * _cost[e];
[2440]480      return c;
481    }
482
[2581]483    /// @}
484
[2574]485  private:
[2440]486
[2556]487    /// Initializes the algorithm.
[2574]488    bool init(bool scaling) {
489      if (!_valid_supply) return false;
[2581]490
491      // Initializing maps
492      if (!_flow) {
493        _flow = new FlowMap(_graph);
494        _local_flow = true;
495      }
496      if (!_potential) {
497        _potential = new PotentialMap(_graph);
498        _local_potential = true;
499      }
500      for (EdgeIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
501      for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
[2574]502      _excess = _supply;
[2440]503
[2581]504      _dijkstra = new ResidualDijkstra( _graph, *_flow, _res_cap, _cost,
505                                        _excess, *_potential, _pred );
506
507      // Initializing delta value
[2574]508      if (scaling) {
[2535]509        // With scaling
510        Supply max_sup = 0, max_dem = 0;
[2574]511        for (NodeIt n(_graph); n != INVALID; ++n) {
512          if ( _supply[n] > max_sup) max_sup =  _supply[n];
513          if (-_supply[n] > max_dem) max_dem = -_supply[n];
[2535]514        }
[2588]515        Capacity max_cap = 0;
516        for (EdgeIt e(_graph); e != INVALID; ++e) {
517          if (_capacity[e] > max_cap) max_cap = _capacity[e];
518        }
519        max_sup = std::min(std::min(max_sup, max_dem), max_cap);
[2574]520        _phase_num = 0;
521        for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2)
522          ++_phase_num;
[2535]523      } else {
524        // Without scaling
[2574]525        _delta = 1;
[2440]526      }
[2581]527
[2440]528      return true;
529    }
530
[2535]531    bool start() {
[2574]532      if (_delta > 1)
[2535]533        return startWithScaling();
534      else
535        return startWithoutScaling();
536    }
537
[2574]538    /// Executes the capacity scaling algorithm.
[2535]539    bool startWithScaling() {
540      // Processing capacity scaling phases
541      Node s, t;
542      int phase_cnt = 0;
543      int factor = 4;
544      while (true) {
545        // Saturating all edges not satisfying the optimality condition
[2574]546        for (EdgeIt e(_graph); e != INVALID; ++e) {
547          Node u = _graph.source(e), v = _graph.target(e);
[2581]548          Cost c = _cost[e] + (*_potential)[u] - (*_potential)[v];
[2574]549          if (c < 0 && _res_cap[e] >= _delta) {
550            _excess[u] -= _res_cap[e];
551            _excess[v] += _res_cap[e];
[2581]552            (*_flow)[e] = _capacity[e];
[2574]553            _res_cap[e] = 0;
[2535]554          }
[2581]555          else if (c > 0 && (*_flow)[e] >= _delta) {
556            _excess[u] += (*_flow)[e];
557            _excess[v] -= (*_flow)[e];
558            (*_flow)[e] = 0;
[2574]559            _res_cap[e] = _capacity[e];
[2535]560          }
561        }
562
563        // Finding excess nodes and deficit nodes
[2574]564        _excess_nodes.clear();
565        _deficit_nodes.clear();
566        for (NodeIt n(_graph); n != INVALID; ++n) {
567          if (_excess[n] >=  _delta) _excess_nodes.push_back(n);
568          if (_excess[n] <= -_delta) _deficit_nodes.push_back(n);
[2535]569        }
[2556]570        int next_node = 0;
[2535]571
572        // Finding augmenting shortest paths
[2574]573        while (next_node < int(_excess_nodes.size())) {
[2535]574          // Checking deficit nodes
[2574]575          if (_delta > 1) {
[2535]576            bool delta_deficit = false;
[2574]577            for (int i = 0; i < int(_deficit_nodes.size()); ++i) {
578              if (_excess[_deficit_nodes[i]] <= -_delta) {
[2535]579                delta_deficit = true;
580                break;
581              }
582            }
583            if (!delta_deficit) break;
584          }
585
586          // Running Dijkstra
[2574]587          s = _excess_nodes[next_node];
[2581]588          if ((t = _dijkstra->run(s, _delta)) == INVALID) {
[2574]589            if (_delta > 1) {
[2535]590              ++next_node;
591              continue;
592            }
593            return false;
594          }
595
596          // Augmenting along a shortest path from s to t.
[2588]597          Capacity d = std::min(_excess[s], -_excess[t]);
[2535]598          Node u = t;
599          Edge e;
[2574]600          if (d > _delta) {
601            while ((e = _pred[u]) != INVALID) {
[2535]602              Capacity rc;
[2574]603              if (u == _graph.target(e)) {
604                rc = _res_cap[e];
605                u = _graph.source(e);
[2535]606              } else {
[2581]607                rc = (*_flow)[e];
[2574]608                u = _graph.target(e);
[2535]609              }
610              if (rc < d) d = rc;
611            }
612          }
613          u = t;
[2574]614          while ((e = _pred[u]) != INVALID) {
615            if (u == _graph.target(e)) {
[2581]616              (*_flow)[e] += d;
[2574]617              _res_cap[e] -= d;
618              u = _graph.source(e);
[2535]619            } else {
[2581]620              (*_flow)[e] -= d;
[2574]621              _res_cap[e] += d;
622              u = _graph.target(e);
[2535]623            }
624          }
[2574]625          _excess[s] -= d;
626          _excess[t] += d;
[2535]627
[2574]628          if (_excess[s] < _delta) ++next_node;
[2535]629        }
630
[2574]631        if (_delta == 1) break;
632        if (++phase_cnt > _phase_num / 4) factor = 2;
633        _delta = _delta <= factor ? 1 : _delta / factor;
[2535]634      }
635
[2556]636      // Handling non-zero lower bounds
[2574]637      if (_lower) {
638        for (EdgeIt e(_graph); e != INVALID; ++e)
[2581]639          (*_flow)[e] += (*_lower)[e];
[2535]640      }
641      return true;
642    }
643
[2574]644    /// Executes the successive shortest path algorithm.
[2535]645    bool startWithoutScaling() {
[2440]646      // Finding excess nodes
[2574]647      for (NodeIt n(_graph); n != INVALID; ++n)
648        if (_excess[n] > 0) _excess_nodes.push_back(n);
649      if (_excess_nodes.size() == 0) return true;
[2556]650      int next_node = 0;
[2440]651
[2457]652      // Finding shortest paths
[2535]653      Node s, t;
[2574]654      while ( _excess[_excess_nodes[next_node]] > 0 ||
655              ++next_node < int(_excess_nodes.size()) )
[2440]656      {
[2535]657        // Running Dijkstra
[2574]658        s = _excess_nodes[next_node];
[2588]659        if ((t = _dijkstra->run(s)) == INVALID) break;
[2440]660
[2535]661        // Augmenting along a shortest path from s to t
[2588]662        Capacity d = std::min(_excess[s], -_excess[t]);
[2535]663        Node u = t;
664        Edge e;
[2588]665        if (d > 1) {
666          while ((e = _pred[u]) != INVALID) {
667            Capacity rc;
668            if (u == _graph.target(e)) {
669              rc = _res_cap[e];
670              u = _graph.source(e);
671            } else {
672              rc = (*_flow)[e];
673              u = _graph.target(e);
674            }
675            if (rc < d) d = rc;
[2535]676          }
677        }
678        u = t;
[2574]679        while ((e = _pred[u]) != INVALID) {
680          if (u == _graph.target(e)) {
[2581]681            (*_flow)[e] += d;
[2574]682            _res_cap[e] -= d;
683            u = _graph.source(e);
[2535]684          } else {
[2581]685            (*_flow)[e] -= d;
[2574]686            _res_cap[e] += d;
687            u = _graph.target(e);
[2535]688          }
689        }
[2574]690        _excess[s] -= d;
691        _excess[t] += d;
[2440]692      }
693
[2556]694      // Handling non-zero lower bounds
[2574]695      if (_lower) {
696        for (EdgeIt e(_graph); e != INVALID; ++e)
[2581]697          (*_flow)[e] += (*_lower)[e];
[2440]698      }
699      return true;
700    }
701
702  }; //class CapacityScaling
703
704  ///@}
705
706} //namespace lemon
707
708#endif //LEMON_CAPACITY_SCALING_H
Note: See TracBrowser for help on using the repository browser.