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