COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/capacity_scaling.h @ 2559:75dd6d724f26

Last change on this file since 2559:75dd6d724f26 was 2556:74c2c81055e1, checked in by Peter Kovacs, 12 years ago

Cleanup in the minimum cost flow files.
The changes only affects the documentation and the look of the source codes.

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