lemon/capacity_scaling.h
author kpeter
Fri, 29 Feb 2008 15:55:13 +0000
changeset 2586 37fb2c384c78
parent 2574 7058c9690e7d
child 2588 4d3bc1d04c1d
permissions -rw-r--r--
Reimplemented Suurballe class.

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