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