lemon/capacity_scaling.h
author kpeter
Sun, 13 Jan 2008 10:32:14 +0000
changeset 2556 74c2c81055e1
parent 2553 bfced05fa852
child 2574 7058c9690e7d
permissions -rw-r--r--
Cleanup in the minimum cost flow files.
The changes only affects the documentation and the look of the source codes.
     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 
    31 namespace 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