Redesigned CapacityScaling algorithm with almost the same interface.
authorkpeter
Wed, 05 Dec 2007 13:03:19 +0000
changeset 2535716024e7c080
parent 2534 edad4c3e926d
child 2536 0a1a6872855c
Redesigned CapacityScaling algorithm with almost the same interface.
The new version does not use the ResidualGraphAdaptor for performance reasons.
Scaling can be enabled and disabled with a parameter of the run() function.
lemon/capacity_scaling.h
     1.1 --- a/lemon/capacity_scaling.h	Wed Dec 05 12:57:24 2007 +0000
     1.2 +++ b/lemon/capacity_scaling.h	Wed Dec 05 13:03:19 2007 +0000
     1.3 @@ -25,17 +25,9 @@
     1.4  /// \brief The capacity scaling algorithm for finding a minimum cost
     1.5  /// flow.
     1.6  
     1.7 +#include <lemon/graph_adaptor.h>
     1.8 +#include <lemon/bin_heap.h>
     1.9  #include <vector>
    1.10 -#include <lemon/graph_adaptor.h>
    1.11 -#include <lemon/dijkstra.h>
    1.12 -
    1.13 -#define WITH_SCALING
    1.14 -
    1.15 -#ifdef WITH_SCALING
    1.16 -#define SCALING_FACTOR	  2
    1.17 -#endif
    1.18 -
    1.19 -//#define _DEBUG_ITER_
    1.20  
    1.21  namespace lemon {
    1.22  
    1.23 @@ -46,9 +38,9 @@
    1.24    /// successive shortest path algorithm for finding a minimum cost
    1.25    /// flow.
    1.26    ///
    1.27 -  /// \ref lemon::CapacityScaling "CapacityScaling" implements the
    1.28 -  /// capacity scaling version of the successive shortest path
    1.29 -  /// algorithm for finding a minimum cost flow.
    1.30 +  /// \ref CapacityScaling implements the capacity scaling version
    1.31 +  /// of the successive shortest path algorithm for finding a minimum
    1.32 +  /// cost flow.
    1.33    ///
    1.34    /// \param Graph The directed graph type the algorithm runs on.
    1.35    /// \param LowerMap The type of the lower bound map.
    1.36 @@ -58,20 +50,20 @@
    1.37    ///
    1.38    /// \warning
    1.39    /// - Edge capacities and costs should be nonnegative integers.
    1.40 -  ///	However \c CostMap::Value should be signed type.
    1.41 +  ///   However \c CostMap::Value should be signed type.
    1.42    /// - Supply values should be signed integers.
    1.43    /// - \c LowerMap::Value must be convertible to
    1.44 -  ///	\c CapacityMap::Value and \c CapacityMap::Value must be
    1.45 -  ///	convertible to \c SupplyMap::Value.
    1.46 +  ///   \c CapacityMap::Value and \c CapacityMap::Value must be
    1.47 +  ///   convertible to \c SupplyMap::Value.
    1.48    ///
    1.49    /// \author Peter Kovacs
    1.50  
    1.51    template < typename Graph,
    1.52 -	     typename LowerMap = typename Graph::template EdgeMap<int>,
    1.53 -	     typename CapacityMap = LowerMap,
    1.54 -	     typename CostMap = typename Graph::template EdgeMap<int>,
    1.55 -	     typename SupplyMap = typename Graph::template NodeMap
    1.56 -				  <typename CapacityMap::Value> >
    1.57 +             typename LowerMap = typename Graph::template EdgeMap<int>,
    1.58 +             typename CapacityMap = LowerMap,
    1.59 +             typename CostMap = typename Graph::template EdgeMap<int>,
    1.60 +             typename SupplyMap = typename Graph::template NodeMap
    1.61 +                                  <typename CapacityMap::Value> >
    1.62    class CapacityScaling
    1.63    {
    1.64      typedef typename Graph::Node Node;
    1.65 @@ -87,16 +79,16 @@
    1.66      typedef typename SupplyMap::Value Supply;
    1.67      typedef typename Graph::template EdgeMap<Capacity> CapacityRefMap;
    1.68      typedef typename Graph::template NodeMap<Supply> SupplyRefMap;
    1.69 -
    1.70 -    typedef ResGraphAdaptor< const Graph, Capacity,
    1.71 -			     CapacityRefMap, CapacityRefMap > ResGraph;
    1.72 -    typedef typename ResGraph::Node ResNode;
    1.73 -    typedef typename ResGraph::NodeIt ResNodeIt;
    1.74 -    typedef typename ResGraph::Edge ResEdge;
    1.75 -    typedef typename ResGraph::EdgeIt ResEdgeIt;
    1.76 +    typedef typename Graph::template NodeMap<Edge> PredMap;
    1.77  
    1.78    public:
    1.79  
    1.80 +    /// \brief Type to enable or disable capacity scaling.
    1.81 +    enum ScalingEnum {
    1.82 +      WITH_SCALING = 0,
    1.83 +      WITHOUT_SCALING = -1
    1.84 +    };
    1.85 +
    1.86      /// \brief The type of the flow map.
    1.87      typedef CapacityRefMap FlowMap;
    1.88      /// \brief The type of the potential map.
    1.89 @@ -104,151 +96,129 @@
    1.90  
    1.91    protected:
    1.92  
    1.93 -    /// \brief Map adaptor class for handling reduced edge costs.
    1.94 -    class ReducedCostMap : public MapBase<ResEdge, Cost>
    1.95 +    /// \brief Special implementation of the \ref Dijkstra algorithm
    1.96 +    /// for finding shortest paths in the residual network of the graph
    1.97 +    /// with respect to the reduced edge costs and modifying the
    1.98 +    /// node potentials according to the distance of the nodes.
    1.99 +    class ResidualDijkstra
   1.100      {
   1.101 -    private:
   1.102 +      typedef typename Graph::template NodeMap<Cost> CostNodeMap;
   1.103 +      typedef typename Graph::template NodeMap<Edge> PredMap;
   1.104  
   1.105 -      const ResGraph &gr;
   1.106 -      const CostMap &cost_map;
   1.107 -      const PotentialMap &pot_map;
   1.108 +      typedef typename Graph::template NodeMap<int> HeapCrossRef;
   1.109 +      typedef BinHeap<Cost, HeapCrossRef> Heap;
   1.110 +
   1.111 +    protected:
   1.112 +
   1.113 +      /// \brief The directed graph the algorithm runs on.
   1.114 +      const Graph &graph;
   1.115 +
   1.116 +      /// \brief The flow map.
   1.117 +      const FlowMap &flow;
   1.118 +      /// \brief The residual capacity map.
   1.119 +      const CapacityRefMap &res_cap;
   1.120 +      /// \brief The cost map.
   1.121 +      const CostMap &cost;
   1.122 +      /// \brief The excess map.
   1.123 +      const SupplyRefMap &excess;
   1.124 +
   1.125 +      /// \brief The potential map.
   1.126 +      PotentialMap &potential;
   1.127 +
   1.128 +      /// \brief The distance map.
   1.129 +      CostNodeMap dist;
   1.130 +      /// \brief The map of predecessors edges.
   1.131 +      PredMap &pred;
   1.132 +      /// \brief The processed (i.e. permanently labeled) nodes.
   1.133 +      std::vector<Node> proc_nodes;
   1.134  
   1.135      public:
   1.136  
   1.137 -      ReducedCostMap( const ResGraph &_gr,
   1.138 -		      const CostMap &_cost,
   1.139 -		      const PotentialMap &_pot ) :
   1.140 -	gr(_gr), cost_map(_cost), pot_map(_pot) {}
   1.141 +      /// \brief The constructor of the class.
   1.142 +      ResidualDijkstra( const Graph &_graph,
   1.143 +                        const FlowMap &_flow,
   1.144 +                        const CapacityRefMap &_res_cap,
   1.145 +                        const CostMap &_cost,
   1.146 +                        const SupplyMap &_excess,
   1.147 +                        PotentialMap &_potential,
   1.148 +                        PredMap &_pred ) :
   1.149 +        graph(_graph), flow(_flow), res_cap(_res_cap), cost(_cost),
   1.150 +        excess(_excess), potential(_potential), dist(_graph),
   1.151 +        pred(_pred)
   1.152 +      {}
   1.153  
   1.154 -      Cost operator[](const ResEdge &e) const {
   1.155 -	return ResGraph::forward(e) ?
   1.156 -	   cost_map[e] - pot_map[gr.source(e)] + pot_map[gr.target(e)] :
   1.157 -	  -cost_map[e] - pot_map[gr.source(e)] + pot_map[gr.target(e)];
   1.158 +      /// \brief Runs the algorithm from the given source node.
   1.159 +      Node run(Node s, Capacity delta) {
   1.160 +        HeapCrossRef heap_cross_ref(graph, Heap::PRE_HEAP);
   1.161 +        Heap heap(heap_cross_ref);
   1.162 +        heap.push(s, 0);
   1.163 +        pred[s] = INVALID;
   1.164 +        proc_nodes.clear();
   1.165 +
   1.166 +        // Processing nodes
   1.167 +        while (!heap.empty() && excess[heap.top()] > -delta) {
   1.168 +          Node u = heap.top(), v;
   1.169 +          Cost d = heap.prio() - potential[u], nd;
   1.170 +          dist[u] = heap.prio();
   1.171 +          heap.pop();
   1.172 +          proc_nodes.push_back(u);
   1.173 +
   1.174 +          // Traversing outgoing edges
   1.175 +          for (OutEdgeIt e(graph, u); e != INVALID; ++e) {
   1.176 +            if (res_cap[e] >= delta) {
   1.177 +              v = graph.target(e);
   1.178 +              switch(heap.state(v)) {
   1.179 +              case Heap::PRE_HEAP:
   1.180 +                heap.push(v, d + cost[e] + potential[v]);
   1.181 +                pred[v] = e;
   1.182 +                break;
   1.183 +              case Heap::IN_HEAP:
   1.184 +                nd = d + cost[e] + potential[v];
   1.185 +                if (nd < heap[v]) {
   1.186 +                  heap.decrease(v, nd);
   1.187 +                  pred[v] = e;
   1.188 +                }
   1.189 +                break;
   1.190 +              case Heap::POST_HEAP:
   1.191 +                break;
   1.192 +              }
   1.193 +            }
   1.194 +          }
   1.195 +
   1.196 +          // Traversing incoming edges
   1.197 +          for (InEdgeIt e(graph, u); e != INVALID; ++e) {
   1.198 +            if (flow[e] >= delta) {
   1.199 +              v = graph.source(e);
   1.200 +              switch(heap.state(v)) {
   1.201 +              case Heap::PRE_HEAP:
   1.202 +                heap.push(v, d - cost[e] + potential[v]);
   1.203 +                pred[v] = e;
   1.204 +                break;
   1.205 +              case Heap::IN_HEAP:
   1.206 +                nd = d - cost[e] + potential[v];
   1.207 +                if (nd < heap[v]) {
   1.208 +                  heap.decrease(v, nd);
   1.209 +                  pred[v] = e;
   1.210 +                }
   1.211 +                break;
   1.212 +              case Heap::POST_HEAP:
   1.213 +                break;
   1.214 +              }
   1.215 +            }
   1.216 +          }
   1.217 +        }
   1.218 +        if (heap.empty()) return INVALID;
   1.219 +
   1.220 +        // Updating potentials of processed nodes
   1.221 +        Node t = heap.top();
   1.222 +        Cost dt = heap.prio();
   1.223 +        for (int i = 0; i < proc_nodes.size(); ++i)
   1.224 +          potential[proc_nodes[i]] -= dist[proc_nodes[i]] - dt;
   1.225 +
   1.226 +        return t;
   1.227        }
   1.228  
   1.229 -    }; //class ReducedCostMap
   1.230 -
   1.231 -    /// \brief Map class for the \ref lemon::Dijkstra "Dijkstra"
   1.232 -    /// algorithm to update node potentials.
   1.233 -    class PotentialUpdateMap : public MapBase<ResNode, Cost>
   1.234 -    {
   1.235 -    private:
   1.236 -
   1.237 -      PotentialMap *pot;
   1.238 -      typedef std::pair<ResNode, Cost> Pair;
   1.239 -      std::vector<Pair> data;
   1.240 -
   1.241 -    public:
   1.242 -
   1.243 -      void potentialMap(PotentialMap &_pot) {
   1.244 -	pot = &_pot;
   1.245 -      }
   1.246 -
   1.247 -      void init() {
   1.248 -	data.clear();
   1.249 -      }
   1.250 -
   1.251 -      void set(const ResNode &n, const Cost &v) {
   1.252 -	data.push_back(Pair(n, v));
   1.253 -      }
   1.254 -
   1.255 -      void update() {
   1.256 -	Cost val = data[data.size()-1].second;
   1.257 -	for (int i = 0; i < data.size()-1; ++i)
   1.258 -	  (*pot)[data[i].first] += val - data[i].second;
   1.259 -      }
   1.260 -
   1.261 -    }; //class PotentialUpdateMap
   1.262 -
   1.263 -#ifdef WITH_SCALING
   1.264 -    /// \brief Map adaptor class for identifing deficit nodes.
   1.265 -    class DeficitBoolMap : public MapBase<ResNode, bool>
   1.266 -    {
   1.267 -    private:
   1.268 -
   1.269 -      const SupplyRefMap &imb;
   1.270 -      const Capacity &delta;
   1.271 -
   1.272 -    public:
   1.273 -
   1.274 -      DeficitBoolMap(const SupplyRefMap &_imb, const Capacity &_delta) :
   1.275 -	imb(_imb), delta(_delta) {}
   1.276 -
   1.277 -      bool operator[](const ResNode &n) const {
   1.278 -	return imb[n] <= -delta;
   1.279 -      }
   1.280 -
   1.281 -    }; //class DeficitBoolMap
   1.282 -
   1.283 -    /// \brief Map adaptor class for filtering edges with at least
   1.284 -    /// \c delta residual capacity.
   1.285 -    class DeltaFilterMap : public MapBase<ResEdge, bool>
   1.286 -    {
   1.287 -    private:
   1.288 -
   1.289 -      const ResGraph &gr;
   1.290 -      const Capacity &delta;
   1.291 -
   1.292 -    public:
   1.293 -
   1.294 -      DeltaFilterMap(const ResGraph &_gr, const Capacity &_delta) :
   1.295 -	gr(_gr), delta(_delta) {}
   1.296 -
   1.297 -      bool operator[](const ResEdge &e) const {
   1.298 -	return gr.rescap(e) >= delta;
   1.299 -      }
   1.300 -
   1.301 -    }; //class DeltaFilterMap
   1.302 -
   1.303 -    typedef EdgeSubGraphAdaptor<const ResGraph, const DeltaFilterMap>
   1.304 -      DeltaResGraph;
   1.305 -
   1.306 -    /// \brief Traits class for \ref lemon::Dijkstra "Dijkstra" class.
   1.307 -    class ResDijkstraTraits :
   1.308 -      public DijkstraDefaultTraits<DeltaResGraph, ReducedCostMap>
   1.309 -    {
   1.310 -    public:
   1.311 -
   1.312 -      typedef PotentialUpdateMap DistMap;
   1.313 -
   1.314 -      static DistMap *createDistMap(const DeltaResGraph&) {
   1.315 -	return new DistMap();
   1.316 -      }
   1.317 -
   1.318 -    }; //class ResDijkstraTraits
   1.319 -
   1.320 -#else //WITHOUT_CAPACITY_SCALING
   1.321 -    /// \brief Map adaptor class for identifing deficit nodes.
   1.322 -    class DeficitBoolMap : public MapBase<ResNode, bool>
   1.323 -    {
   1.324 -    private:
   1.325 -
   1.326 -      const SupplyRefMap &imb;
   1.327 -
   1.328 -    public:
   1.329 -
   1.330 -      DeficitBoolMap(const SupplyRefMap &_imb) : imb(_imb) {}
   1.331 -
   1.332 -      bool operator[](const ResNode &n) const {
   1.333 -	return imb[n] < 0;
   1.334 -      }
   1.335 -
   1.336 -    }; //class DeficitBoolMap
   1.337 -
   1.338 -    /// \brief Traits class for \ref lemon::Dijkstra "Dijkstra" class.
   1.339 -    class ResDijkstraTraits :
   1.340 -      public DijkstraDefaultTraits<ResGraph, ReducedCostMap>
   1.341 -    {
   1.342 -    public:
   1.343 -
   1.344 -      typedef PotentialUpdateMap DistMap;
   1.345 -
   1.346 -      static DistMap *createDistMap(const ResGraph&) {
   1.347 -	return new DistMap();
   1.348 -      }
   1.349 -
   1.350 -    }; //class ResDijkstraTraits
   1.351 -#endif
   1.352 +    }; //class ResidualDijkstra
   1.353  
   1.354    protected:
   1.355  
   1.356 @@ -269,57 +239,30 @@
   1.357      FlowMap flow;
   1.358      /// \brief The potential node map.
   1.359      PotentialMap potential;
   1.360 -    /// \brief The residual graph.
   1.361 -    ResGraph res_graph;
   1.362 -    /// \brief The reduced cost map.
   1.363 -    ReducedCostMap red_cost;
   1.364  
   1.365 -    /// \brief The imbalance map.
   1.366 -    SupplyRefMap imbalance;
   1.367 -    /// \brief The excess nodes.
   1.368 -    std::vector<ResNode> excess_nodes;
   1.369 +    /// \brief The residual capacity map.
   1.370 +    CapacityRefMap res_cap;
   1.371 +    /// \brief The excess map.
   1.372 +    SupplyRefMap excess;
   1.373 +    /// \brief The excess nodes (i.e. nodes with positive excess).
   1.374 +    std::vector<Node> excess_nodes;
   1.375      /// \brief The index of the next excess node.
   1.376      int next_node;
   1.377  
   1.378 -#ifdef WITH_SCALING
   1.379 -    typedef Dijkstra<DeltaResGraph, ReducedCostMap, ResDijkstraTraits>
   1.380 -      ResDijkstra;
   1.381 -    /// \brief \ref lemon::Dijkstra "Dijkstra" class for finding
   1.382 -    /// shortest paths in the residual graph with respect to the
   1.383 -    /// reduced edge costs.
   1.384 -    ResDijkstra dijkstra;
   1.385 -
   1.386 +    /// \brief The scaling status (enabled or disabled).
   1.387 +    ScalingEnum scaling;
   1.388      /// \brief The delta parameter used for capacity scaling.
   1.389      Capacity delta;
   1.390 -    /// \brief Edge filter map for filtering edges with at least
   1.391 -    /// \c delta residual capacity.
   1.392 -    DeltaFilterMap delta_filter;
   1.393 -    /// \brief The delta residual graph (i.e. the subgraph of the
   1.394 -    /// residual graph consisting of edges with at least \c delta
   1.395 -    /// residual capacity).
   1.396 -    DeltaResGraph dres_graph;
   1.397 -    /// \brief Map for identifing deficit nodes.
   1.398 -    DeficitBoolMap delta_deficit;
   1.399 +    /// \brief The maximum number of phases.
   1.400 +    Capacity phase_num;
   1.401 +    /// \brief The deficit nodes.
   1.402 +    std::vector<Node> deficit_nodes;
   1.403  
   1.404 -    /// \brief The deficit nodes.
   1.405 -    std::vector<ResNode> deficit_nodes;
   1.406 -
   1.407 -#else //WITHOUT_CAPACITY_SCALING
   1.408 -    typedef Dijkstra<ResGraph, ReducedCostMap, ResDijkstraTraits>
   1.409 -      ResDijkstra;
   1.410 -    /// \brief \ref lemon::Dijkstra "Dijkstra" class for finding
   1.411 -    /// shortest paths in the residual graph with respect to the
   1.412 -    /// reduced edge costs.
   1.413 -    ResDijkstra dijkstra;
   1.414 -    /// \brief Map for identifing deficit nodes.
   1.415 -    DeficitBoolMap has_deficit;
   1.416 -#endif
   1.417 -
   1.418 -    /// \brief Pred map for the \ref lemon::Dijkstra "Dijkstra" class.
   1.419 -    typename ResDijkstra::PredMap pred;
   1.420 -    /// \brief Dist map for the \ref lemon::Dijkstra "Dijkstra" class to
   1.421 -    /// update node potentials.
   1.422 -    PotentialUpdateMap updater;
   1.423 +    /// \brief Implementation of the \ref Dijkstra algorithm for
   1.424 +    /// finding augmenting shortest paths in the residual network.
   1.425 +    ResidualDijkstra dijkstra;
   1.426 +    /// \brief The map of predecessors edges.
   1.427 +    PredMap pred;
   1.428  
   1.429    public :
   1.430  
   1.431 @@ -333,35 +276,27 @@
   1.432      /// \param _cost The cost (length) values of the edges.
   1.433      /// \param _supply The supply values of the nodes (signed).
   1.434      CapacityScaling( const Graph &_graph,
   1.435 -		     const LowerMap &_lower,
   1.436 -		     const CapacityMap &_capacity,
   1.437 -		     const CostMap &_cost,
   1.438 -		     const SupplyMap &_supply ) :
   1.439 +                     const LowerMap &_lower,
   1.440 +                     const CapacityMap &_capacity,
   1.441 +                     const CostMap &_cost,
   1.442 +                     const SupplyMap &_supply ) :
   1.443        graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
   1.444        supply(_graph), flow(_graph, 0), potential(_graph, 0),
   1.445 -      res_graph(_graph, capacity, flow),
   1.446 -      red_cost(res_graph, cost, potential), imbalance(_graph),
   1.447 -#ifdef WITH_SCALING
   1.448 -      delta(0), delta_filter(res_graph, delta),
   1.449 -      dres_graph(res_graph, delta_filter),
   1.450 -      dijkstra(dres_graph, red_cost), pred(dres_graph),
   1.451 -      delta_deficit(imbalance, delta)
   1.452 -#else //WITHOUT_CAPACITY_SCALING
   1.453 -      dijkstra(res_graph, red_cost), pred(res_graph),
   1.454 -      has_deficit(imbalance)
   1.455 -#endif
   1.456 +      res_cap(_graph), excess(_graph), pred(_graph),
   1.457 +      dijkstra(graph, flow, res_cap, cost, excess, potential, pred)
   1.458      {
   1.459        // Removing nonzero lower bounds
   1.460        capacity = subMap(_capacity, _lower);
   1.461 +      res_cap = capacity;
   1.462        Supply sum = 0;
   1.463        for (NodeIt n(graph); n != INVALID; ++n) {
   1.464 -	Supply s = _supply[n];
   1.465 -	for (InEdgeIt e(graph, n); e != INVALID; ++e)
   1.466 -	  s += _lower[e];
   1.467 -	for (OutEdgeIt e(graph, n); e != INVALID; ++e)
   1.468 -	  s -= _lower[e];
   1.469 -	supply[n] = s;
   1.470 -	sum += s;
   1.471 +        Supply s = _supply[n];
   1.472 +        for (InEdgeIt e(graph, n); e != INVALID; ++e)
   1.473 +          s += _lower[e];
   1.474 +        for (OutEdgeIt e(graph, n); e != INVALID; ++e)
   1.475 +          s -= _lower[e];
   1.476 +        supply[n] = s;
   1.477 +        sum += s;
   1.478        }
   1.479        valid_supply = sum == 0;
   1.480      }
   1.481 @@ -375,22 +310,13 @@
   1.482      /// \param _cost The cost (length) values of the edges.
   1.483      /// \param _supply The supply values of the nodes (signed).
   1.484      CapacityScaling( const Graph &_graph,
   1.485 -		     const CapacityMap &_capacity,
   1.486 -		     const CostMap &_cost,
   1.487 -		     const SupplyMap &_supply ) :
   1.488 +                     const CapacityMap &_capacity,
   1.489 +                     const CostMap &_cost,
   1.490 +                     const SupplyMap &_supply ) :
   1.491        graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
   1.492        supply(_supply), flow(_graph, 0), potential(_graph, 0),
   1.493 -      res_graph(_graph, capacity, flow),
   1.494 -      red_cost(res_graph, cost, potential), imbalance(_graph),
   1.495 -#ifdef WITH_SCALING
   1.496 -      delta(0), delta_filter(res_graph, delta),
   1.497 -      dres_graph(res_graph, delta_filter),
   1.498 -      dijkstra(dres_graph, red_cost), pred(dres_graph),
   1.499 -      delta_deficit(imbalance, delta)
   1.500 -#else //WITHOUT_CAPACITY_SCALING
   1.501 -      dijkstra(res_graph, red_cost), pred(res_graph),
   1.502 -      has_deficit(imbalance)
   1.503 -#endif
   1.504 +      res_cap(_capacity), excess(_graph), pred(_graph),
   1.505 +      dijkstra(graph, flow, res_cap, cost, excess, potential)
   1.506      {
   1.507        // Checking the sum of supply values
   1.508        Supply sum = 0;
   1.509 @@ -412,36 +338,28 @@
   1.510      /// to node \c _t (i.e. the supply of \c _s and the demand of
   1.511      /// \c _t).
   1.512      CapacityScaling( const Graph &_graph,
   1.513 -		     const LowerMap &_lower,
   1.514 -		     const CapacityMap &_capacity,
   1.515 -		     const CostMap &_cost,
   1.516 -		     Node _s, Node _t,
   1.517 -		     Supply _flow_value ) :
   1.518 +                     const LowerMap &_lower,
   1.519 +                     const CapacityMap &_capacity,
   1.520 +                     const CostMap &_cost,
   1.521 +                     Node _s, Node _t,
   1.522 +                     Supply _flow_value ) :
   1.523        graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
   1.524        supply(_graph), flow(_graph, 0), potential(_graph, 0),
   1.525 -      res_graph(_graph, capacity, flow),
   1.526 -      red_cost(res_graph, cost, potential), imbalance(_graph),
   1.527 -#ifdef WITH_SCALING
   1.528 -      delta(0), delta_filter(res_graph, delta),
   1.529 -      dres_graph(res_graph, delta_filter),
   1.530 -      dijkstra(dres_graph, red_cost), pred(dres_graph),
   1.531 -      delta_deficit(imbalance, delta)
   1.532 -#else //WITHOUT_CAPACITY_SCALING
   1.533 -      dijkstra(res_graph, red_cost), pred(res_graph),
   1.534 -      has_deficit(imbalance)
   1.535 -#endif
   1.536 +      res_cap(_graph), excess(_graph), pred(_graph),
   1.537 +      dijkstra(graph, flow, res_cap, cost, excess, potential)
   1.538      {
   1.539        // Removing nonzero lower bounds
   1.540        capacity = subMap(_capacity, _lower);
   1.541 +      res_cap = capacity;
   1.542        for (NodeIt n(graph); n != INVALID; ++n) {
   1.543 -	Supply s = 0;
   1.544 -	if (n == _s) s =  _flow_value;
   1.545 -	if (n == _t) s = -_flow_value;
   1.546 -	for (InEdgeIt e(graph, n); e != INVALID; ++e)
   1.547 -	  s += _lower[e];
   1.548 -	for (OutEdgeIt e(graph, n); e != INVALID; ++e)
   1.549 -	  s -= _lower[e];
   1.550 -	supply[n] = s;
   1.551 +        Supply s = 0;
   1.552 +        if (n == _s) s =  _flow_value;
   1.553 +        if (n == _t) s = -_flow_value;
   1.554 +        for (InEdgeIt e(graph, n); e != INVALID; ++e)
   1.555 +          s += _lower[e];
   1.556 +        for (OutEdgeIt e(graph, n); e != INVALID; ++e)
   1.557 +          s -= _lower[e];
   1.558 +        supply[n] = s;
   1.559        }
   1.560        valid_supply = true;
   1.561      }
   1.562 @@ -459,23 +377,14 @@
   1.563      /// to node \c _t (i.e. the supply of \c _s and the demand of
   1.564      /// \c _t).
   1.565      CapacityScaling( const Graph &_graph,
   1.566 -		     const CapacityMap &_capacity,
   1.567 -		     const CostMap &_cost,
   1.568 -		     Node _s, Node _t,
   1.569 -		     Supply _flow_value ) :
   1.570 +                     const CapacityMap &_capacity,
   1.571 +                     const CostMap &_cost,
   1.572 +                     Node _s, Node _t,
   1.573 +                     Supply _flow_value ) :
   1.574        graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
   1.575        supply(_graph, 0), flow(_graph, 0), potential(_graph, 0),
   1.576 -      res_graph(_graph, capacity, flow),
   1.577 -      red_cost(res_graph, cost, potential), imbalance(_graph),
   1.578 -#ifdef WITH_SCALING
   1.579 -      delta(0), delta_filter(res_graph, delta),
   1.580 -      dres_graph(res_graph, delta_filter),
   1.581 -      dijkstra(dres_graph, red_cost), pred(dres_graph),
   1.582 -      delta_deficit(imbalance, delta)
   1.583 -#else //WITHOUT_CAPACITY_SCALING
   1.584 -      dijkstra(res_graph, red_cost), pred(res_graph),
   1.585 -      has_deficit(imbalance)
   1.586 -#endif
   1.587 +      res_cap(_capacity), excess(_graph), pred(_graph),
   1.588 +      dijkstra(graph, flow, res_cap, cost, excess, potential)
   1.589      {
   1.590        supply[_s] =  _flow_value;
   1.591        supply[_t] = -_flow_value;
   1.592 @@ -511,7 +420,7 @@
   1.593      Cost totalCost() const {
   1.594        Cost c = 0;
   1.595        for (EdgeIt e(graph); e != INVALID; ++e)
   1.596 -	c += flow[e] * cost[e];
   1.597 +        c += flow[e] * cost[e];
   1.598        return c;
   1.599      }
   1.600  
   1.601 @@ -519,190 +428,216 @@
   1.602      ///
   1.603      /// Runs the algorithm.
   1.604      ///
   1.605 +    /// \param scaling_mode The scaling mode. In case of WITH_SCALING
   1.606 +    /// capacity scaling is enabled in the algorithm (this is the
   1.607 +    /// default value) otherwise it is disabled.
   1.608 +    /// If the maximum edge capacity and/or the amount of total supply
   1.609 +    /// is small, the algorithm could be faster without scaling.
   1.610 +    ///
   1.611      /// \return \c true if a feasible flow can be found.
   1.612 -    bool run() {
   1.613 -      return init() && start();
   1.614 +    bool run(int scaling_mode = WITH_SCALING) {
   1.615 +      return init(scaling_mode) && start();
   1.616      }
   1.617  
   1.618    protected:
   1.619  
   1.620      /// \brief Initializes the algorithm.
   1.621 -    bool init() {
   1.622 +    bool init(int scaling_mode) {
   1.623        if (!valid_supply) return false;
   1.624 -      imbalance = supply;
   1.625 +      excess = supply;
   1.626  
   1.627 -      // Initalizing Dijkstra class
   1.628 -      updater.potentialMap(potential);
   1.629 -      dijkstra.distMap(updater).predMap(pred);
   1.630 -
   1.631 -#ifdef WITH_SCALING
   1.632        // Initilaizing delta value
   1.633 -      Supply max_sup = 0, max_dem = 0;
   1.634 -      for (NodeIt n(graph); n != INVALID; ++n) {
   1.635 -	if (supply[n] >  max_sup) max_sup =  supply[n];
   1.636 -	if (supply[n] < -max_dem) max_dem = -supply[n];
   1.637 -      }
   1.638 -      if (max_dem < max_sup) max_sup = max_dem;
   1.639 -      for ( delta = 1; SCALING_FACTOR * delta < max_sup;
   1.640 -	    delta *= SCALING_FACTOR ) ;
   1.641 -#endif
   1.642 -      return true;
   1.643 -    }
   1.644 -
   1.645 -#ifdef WITH_SCALING
   1.646 -    /// \brief Executes the capacity scaling version of the successive
   1.647 -    /// shortest path algorithm.
   1.648 -    bool start() {
   1.649 -      typedef typename DeltaResGraph::EdgeIt DeltaResEdgeIt;
   1.650 -      typedef typename DeltaResGraph::Edge DeltaResEdge;
   1.651 -#ifdef _DEBUG_ITER_
   1.652 -      int dijk_num = 0;
   1.653 -#endif
   1.654 -
   1.655 -      // Processing capacity scaling phases
   1.656 -      ResNode s, t;
   1.657 -      for ( ; delta >= 1; delta = delta < SCALING_FACTOR && delta > 1 ?
   1.658 -				  1 : delta / SCALING_FACTOR )
   1.659 -      {
   1.660 -	// Saturating edges not satisfying the optimality condition
   1.661 -	Capacity r;
   1.662 -	for (DeltaResEdgeIt e(dres_graph); e != INVALID; ++e) {
   1.663 -	  if (red_cost[e] < 0) {
   1.664 -	    res_graph.augment(e, r = res_graph.rescap(e));
   1.665 -	    imbalance[dres_graph.source(e)] -= r;
   1.666 -	    imbalance[dres_graph.target(e)] += r;
   1.667 -	  }
   1.668 -	}
   1.669 -
   1.670 -	// Finding excess nodes
   1.671 -	excess_nodes.clear();
   1.672 -	deficit_nodes.clear();
   1.673 -	for (ResNodeIt n(res_graph); n != INVALID; ++n) {
   1.674 -	  if (imbalance[n] >=  delta) excess_nodes.push_back(n);
   1.675 -	  if (imbalance[n] <= -delta) deficit_nodes.push_back(n);
   1.676 -	}
   1.677 -	next_node = 0;
   1.678 -
   1.679 -	// Finding shortest paths
   1.680 -	while (next_node < excess_nodes.size()) {
   1.681 -	  // Checking deficit nodes
   1.682 -	  if (delta > 1) {
   1.683 -	    bool delta_def = false;
   1.684 -	    for (int i = 0; i < deficit_nodes.size(); ++i) {
   1.685 -	      if (imbalance[deficit_nodes[i]] <= -delta) {
   1.686 -		delta_def = true;
   1.687 -		break;
   1.688 -	      }
   1.689 -	    }
   1.690 -	    if (!delta_def) break;
   1.691 -	  }
   1.692 -
   1.693 -	  // Running Dijkstra
   1.694 -	  s = excess_nodes[next_node];
   1.695 -	  updater.init();
   1.696 -	  dijkstra.init();
   1.697 -	  dijkstra.addSource(s);
   1.698 -#ifdef _DEBUG_ITER_
   1.699 -	  ++dijk_num;
   1.700 -#endif
   1.701 -	  if ((t = dijkstra.start(delta_deficit)) == INVALID) {
   1.702 -	    if (delta > 1) {
   1.703 -	      ++next_node;
   1.704 -	      continue;
   1.705 -	    }
   1.706 -	    return false;
   1.707 -	  }
   1.708 -
   1.709 -	  // Updating node potentials
   1.710 -	  updater.update();
   1.711 -
   1.712 -	  // Augment along a shortest path from s to t
   1.713 -	  Capacity d = imbalance[s] < -imbalance[t] ?
   1.714 -	    imbalance[s] : -imbalance[t];
   1.715 -	  ResNode u = t;
   1.716 -	  ResEdge e;
   1.717 -	  if (d > delta) {
   1.718 -	    while ((e = pred[u]) != INVALID) {
   1.719 -	      if (res_graph.rescap(e) < d) d = res_graph.rescap(e);
   1.720 -	      u = dres_graph.source(e);
   1.721 -	    }
   1.722 -	  }
   1.723 -	  u = t;
   1.724 -	  while ((e = pred[u]) != INVALID) {
   1.725 -	    res_graph.augment(e, d);
   1.726 -	    u = dres_graph.source(e);
   1.727 -	  }
   1.728 -	  imbalance[s] -= d;
   1.729 -	  imbalance[t] += d;
   1.730 -	  if (imbalance[s] < delta) ++next_node;
   1.731 -	}
   1.732 -      }
   1.733 -#ifdef _DEBUG_ITER_
   1.734 -      std::cout << "Capacity Scaling algorithm finished with running Dijkstra algorithm "
   1.735 -	<< dijk_num << " times." << std::endl;
   1.736 -#endif
   1.737 -
   1.738 -      // Handling nonzero lower bounds
   1.739 -      if (lower) {
   1.740 -	for (EdgeIt e(graph); e != INVALID; ++e)
   1.741 -	  flow[e] += (*lower)[e];
   1.742 +      if (scaling_mode == WITH_SCALING) {
   1.743 +        // With scaling
   1.744 +        Supply max_sup = 0, max_dem = 0;
   1.745 +        for (NodeIt n(graph); n != INVALID; ++n) {
   1.746 +          if ( supply[n] > max_sup) max_sup =  supply[n];
   1.747 +          if (-supply[n] > max_dem) max_dem = -supply[n];
   1.748 +        }
   1.749 +        if (max_dem < max_sup) max_sup = max_dem;
   1.750 +        phase_num = 0;
   1.751 +        for (delta = 1; 2 * delta <= max_sup; delta *= 2)
   1.752 +          ++phase_num;
   1.753 +      } else {
   1.754 +        // Without scaling
   1.755 +        delta = 1;
   1.756        }
   1.757        return true;
   1.758      }
   1.759  
   1.760 -#else //WITHOUT_CAPACITY_SCALING
   1.761 +    /// \brief Executes the algorithm.
   1.762 +    bool start() {
   1.763 +      if (delta > 1)
   1.764 +        return startWithScaling();
   1.765 +      else
   1.766 +        return startWithoutScaling();
   1.767 +    }
   1.768 +
   1.769 +    /// \brief Executes the capacity scaling version of the successive
   1.770 +    /// shortest path algorithm.
   1.771 +    bool startWithScaling() {
   1.772 +      // Processing capacity scaling phases
   1.773 +      Node s, t;
   1.774 +      int phase_cnt = 0;
   1.775 +      int factor = 4;
   1.776 +      while (true) {
   1.777 +        // Saturating all edges not satisfying the optimality condition
   1.778 +        for (EdgeIt e(graph); e != INVALID; ++e) {
   1.779 +          Node u = graph.source(e), v = graph.target(e);
   1.780 +          Cost c = cost[e] - potential[u] + potential[v];
   1.781 +          if (c < 0 && res_cap[e] >= delta) {
   1.782 +            excess[u] -= res_cap[e];
   1.783 +            excess[v] += res_cap[e];
   1.784 +            flow[e] = capacity[e];
   1.785 +            res_cap[e] = 0;
   1.786 +          }
   1.787 +          else if (c > 0 && flow[e] >= delta) {
   1.788 +            excess[u] += flow[e];
   1.789 +            excess[v] -= flow[e];
   1.790 +            flow[e] = 0;
   1.791 +            res_cap[e] = capacity[e];
   1.792 +          }
   1.793 +        }
   1.794 +
   1.795 +        // Finding excess nodes and deficit nodes
   1.796 +        excess_nodes.clear();
   1.797 +        deficit_nodes.clear();
   1.798 +        for (NodeIt n(graph); n != INVALID; ++n) {
   1.799 +          if (excess[n] >=  delta) excess_nodes.push_back(n);
   1.800 +          if (excess[n] <= -delta) deficit_nodes.push_back(n);
   1.801 +        }
   1.802 +        next_node = 0;
   1.803 +
   1.804 +        // Finding augmenting shortest paths
   1.805 +        while (next_node < excess_nodes.size()) {
   1.806 +          // Checking deficit nodes
   1.807 +          if (delta > 1) {
   1.808 +            bool delta_deficit = false;
   1.809 +            for (int i = 0; i < deficit_nodes.size(); ++i) {
   1.810 +              if (excess[deficit_nodes[i]] <= -delta) {
   1.811 +                delta_deficit = true;
   1.812 +                break;
   1.813 +              }
   1.814 +            }
   1.815 +            if (!delta_deficit) break;
   1.816 +          }
   1.817 +
   1.818 +          // Running Dijkstra
   1.819 +          s = excess_nodes[next_node];
   1.820 +          if ((t = dijkstra.run(s, delta)) == INVALID) {
   1.821 +            if (delta > 1) {
   1.822 +              ++next_node;
   1.823 +              continue;
   1.824 +            }
   1.825 +            return false;
   1.826 +          }
   1.827 +
   1.828 +          // Augmenting along a shortest path from s to t.
   1.829 +          Capacity d = excess[s] < -excess[t] ? excess[s] : -excess[t];
   1.830 +          Node u = t;
   1.831 +          Edge e;
   1.832 +          if (d > delta) {
   1.833 +            while ((e = pred[u]) != INVALID) {
   1.834 +              Capacity rc;
   1.835 +              if (u == graph.target(e)) {
   1.836 +                rc = res_cap[e];
   1.837 +                u = graph.source(e);
   1.838 +              } else {
   1.839 +                rc = flow[e];
   1.840 +                u = graph.target(e);
   1.841 +              }
   1.842 +              if (rc < d) d = rc;
   1.843 +            }
   1.844 +          }
   1.845 +          u = t;
   1.846 +          while ((e = pred[u]) != INVALID) {
   1.847 +            if (u == graph.target(e)) {
   1.848 +              flow[e] += d;
   1.849 +              res_cap[e] -= d;
   1.850 +              u = graph.source(e);
   1.851 +            } else {
   1.852 +              flow[e] -= d;
   1.853 +              res_cap[e] += d;
   1.854 +              u = graph.target(e);
   1.855 +            }
   1.856 +          }
   1.857 +          excess[s] -= d;
   1.858 +          excess[t] += d;
   1.859 +
   1.860 +          if (excess[s] < delta) ++next_node;
   1.861 +        }
   1.862 +
   1.863 +        if (delta == 1) break;
   1.864 +        if (++phase_cnt > phase_num / 4) factor = 2;
   1.865 +        delta = delta <= factor ? 1 : delta / factor;
   1.866 +      }
   1.867 +
   1.868 +      // Handling nonzero lower bounds
   1.869 +      if (lower) {
   1.870 +        for (EdgeIt e(graph); e != INVALID; ++e)
   1.871 +          flow[e] += (*lower)[e];
   1.872 +      }
   1.873 +      return true;
   1.874 +    }
   1.875 +
   1.876      /// \brief Executes the successive shortest path algorithm without
   1.877      /// capacity scaling.
   1.878 -    bool start() {
   1.879 +    bool startWithoutScaling() {
   1.880        // Finding excess nodes
   1.881 -      for (ResNodeIt n(res_graph); n != INVALID; ++n) {
   1.882 -	if (imbalance[n] > 0) excess_nodes.push_back(n);
   1.883 +      for (NodeIt n(graph); n != INVALID; ++n) {
   1.884 +        if (excess[n] > 0) excess_nodes.push_back(n);
   1.885        }
   1.886        if (excess_nodes.size() == 0) return true;
   1.887        next_node = 0;
   1.888  
   1.889        // Finding shortest paths
   1.890 -      ResNode s, t;
   1.891 -      while ( imbalance[excess_nodes[next_node]] > 0 ||
   1.892 -	      ++next_node < excess_nodes.size() )
   1.893 +      Node s, t;
   1.894 +      while ( excess[excess_nodes[next_node]] > 0 ||
   1.895 +              ++next_node < excess_nodes.size() )
   1.896        {
   1.897 -	// Running Dijkstra
   1.898 -	s = excess_nodes[next_node];
   1.899 -	updater.init();
   1.900 -	dijkstra.init();
   1.901 -	dijkstra.addSource(s);
   1.902 -	if ((t = dijkstra.start(has_deficit)) == INVALID)
   1.903 -	  return false;
   1.904 +        // Running Dijkstra
   1.905 +        s = excess_nodes[next_node];
   1.906 +        if ((t = dijkstra.run(s, 1)) == INVALID)
   1.907 +          return false;
   1.908  
   1.909 -	// Updating node potentials
   1.910 -	updater.update();
   1.911 -
   1.912 -	// Augmenting along a shortest path from s to t
   1.913 -	Capacity delta = imbalance[s] < -imbalance[t] ?
   1.914 -	  imbalance[s] : -imbalance[t];
   1.915 -	ResNode u = t;
   1.916 -	ResEdge e;
   1.917 -	while ((e = pred[u]) != INVALID) {
   1.918 -	  if (res_graph.rescap(e) < delta) delta = res_graph.rescap(e);
   1.919 -	  u = res_graph.source(e);
   1.920 -	}
   1.921 -	u = t;
   1.922 -	while ((e = pred[u]) != INVALID) {
   1.923 -	  res_graph.augment(e, delta);
   1.924 -	  u = res_graph.source(e);
   1.925 -	}
   1.926 -	imbalance[s] -= delta;
   1.927 -	imbalance[t] += delta;
   1.928 +        // Augmenting along a shortest path from s to t
   1.929 +        Capacity d = excess[s] < -excess[t] ? excess[s] : -excess[t];
   1.930 +        Node u = t;
   1.931 +        Edge e;
   1.932 +        while ((e = pred[u]) != INVALID) {
   1.933 +          Capacity rc;
   1.934 +          if (u == graph.target(e)) {
   1.935 +            rc = res_cap[e];
   1.936 +            u = graph.source(e);
   1.937 +          } else {
   1.938 +            rc = flow[e];
   1.939 +            u = graph.target(e);
   1.940 +          }
   1.941 +          if (rc < d) d = rc;
   1.942 +        }
   1.943 +        u = t;
   1.944 +        while ((e = pred[u]) != INVALID) {
   1.945 +          if (u == graph.target(e)) {
   1.946 +            flow[e] += d;
   1.947 +            res_cap[e] -= d;
   1.948 +            u = graph.source(e);
   1.949 +          } else {
   1.950 +            flow[e] -= d;
   1.951 +            res_cap[e] += d;
   1.952 +            u = graph.target(e);
   1.953 +          }
   1.954 +        }
   1.955 +        excess[s] -= d;
   1.956 +        excess[t] += d;
   1.957        }
   1.958  
   1.959        // Handling nonzero lower bounds
   1.960        if (lower) {
   1.961 -	for (EdgeIt e(graph); e != INVALID; ++e)
   1.962 -	  flow[e] += (*lower)[e];
   1.963 +        for (EdgeIt e(graph); e != INVALID; ++e)
   1.964 +          flow[e] += (*lower)[e];
   1.965        }
   1.966        return true;
   1.967      }
   1.968 -#endif
   1.969  
   1.970    }; //class CapacityScaling
   1.971