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