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