lemon/capacity_scaling.h
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 806 fa6f37d7a25b
parent 805 d3e32a777d0b
child 807 78071e00de00
permissions -rw-r--r--
Entirely rework CapacityScaling (#180)

- Use the new interface similarly to NetworkSimplex.
- Rework the implementation using an efficient internal structure
for handling the residual network. This improvement made the
code much faster (up to 2-5 times faster on large graphs).
- Handle GEQ supply type (LEQ is not supported).
- Handle negative costs for arcs of finite capacity.
(Note that this algorithm cannot handle arcs of negative cost
and infinite upper bound, thus it returns UNBOUNDED if such
an arc exists.)
- Extend the documentation.
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@806
    22
/// \ingroup min_cost_flow_algs
kpeter@805
    23
///
kpeter@805
    24
/// \file
kpeter@806
    25
/// \brief Capacity Scaling algorithm for finding a minimum cost flow.
kpeter@805
    26
kpeter@805
    27
#include <vector>
kpeter@806
    28
#include <limits>
kpeter@806
    29
#include <lemon/core.h>
kpeter@805
    30
#include <lemon/bin_heap.h>
kpeter@805
    31
kpeter@805
    32
namespace lemon {
kpeter@805
    33
kpeter@806
    34
  /// \addtogroup min_cost_flow_algs
kpeter@805
    35
  /// @{
kpeter@805
    36
kpeter@806
    37
  /// \brief Implementation of the Capacity Scaling algorithm for
kpeter@806
    38
  /// finding a \ref min_cost_flow "minimum cost flow".
kpeter@805
    39
  ///
kpeter@805
    40
  /// \ref CapacityScaling implements the capacity scaling version
kpeter@806
    41
  /// of the successive shortest path algorithm for finding a
kpeter@806
    42
  /// \ref min_cost_flow "minimum cost flow". It is an efficient dual
kpeter@806
    43
  /// solution method.
kpeter@805
    44
  ///
kpeter@806
    45
  /// Most of the parameters of the problem (except for the digraph)
kpeter@806
    46
  /// can be given using separate functions, and the algorithm can be
kpeter@806
    47
  /// executed using the \ref run() function. If some parameters are not
kpeter@806
    48
  /// specified, then default values will be used.
kpeter@805
    49
  ///
kpeter@806
    50
  /// \tparam GR The digraph type the algorithm runs on.
kpeter@806
    51
  /// \tparam V The value type used for flow amounts, capacity bounds
kpeter@806
    52
  /// and supply values in the algorithm. By default it is \c int.
kpeter@806
    53
  /// \tparam C The value type used for costs and potentials in the
kpeter@806
    54
  /// algorithm. By default it is the same as \c V.
kpeter@805
    55
  ///
kpeter@806
    56
  /// \warning Both value types must be signed and all input data must
kpeter@806
    57
  /// be integer.
kpeter@806
    58
  /// \warning This algorithm does not support negative costs for such
kpeter@806
    59
  /// arcs that have infinite upper bound.
kpeter@806
    60
  template <typename GR, typename V = int, typename C = V>
kpeter@805
    61
  class CapacityScaling
kpeter@805
    62
  {
kpeter@806
    63
  public:
kpeter@805
    64
kpeter@806
    65
    /// The type of the flow amounts, capacity bounds and supply values
kpeter@806
    66
    typedef V Value;
kpeter@806
    67
    /// The type of the arc costs
kpeter@806
    68
    typedef C Cost;
kpeter@805
    69
kpeter@805
    70
  public:
kpeter@805
    71
kpeter@806
    72
    /// \brief Problem type constants for the \c run() function.
kpeter@806
    73
    ///
kpeter@806
    74
    /// Enum type containing the problem type constants that can be
kpeter@806
    75
    /// returned by the \ref run() function of the algorithm.
kpeter@806
    76
    enum ProblemType {
kpeter@806
    77
      /// The problem has no feasible solution (flow).
kpeter@806
    78
      INFEASIBLE,
kpeter@806
    79
      /// The problem has optimal solution (i.e. it is feasible and
kpeter@806
    80
      /// bounded), and the algorithm has found optimal flow and node
kpeter@806
    81
      /// potentials (primal and dual solutions).
kpeter@806
    82
      OPTIMAL,
kpeter@806
    83
      /// The digraph contains an arc of negative cost and infinite
kpeter@806
    84
      /// upper bound. It means that the objective function is unbounded
kpeter@806
    85
      /// on that arc, however note that it could actually be bounded
kpeter@806
    86
      /// over the feasible flows, but this algroithm cannot handle
kpeter@806
    87
      /// these cases.
kpeter@806
    88
      UNBOUNDED
kpeter@806
    89
    };
kpeter@806
    90
  
kpeter@806
    91
  private:
kpeter@806
    92
kpeter@806
    93
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
kpeter@806
    94
kpeter@806
    95
    typedef std::vector<Arc> ArcVector;
kpeter@806
    96
    typedef std::vector<Node> NodeVector;
kpeter@806
    97
    typedef std::vector<int> IntVector;
kpeter@806
    98
    typedef std::vector<bool> BoolVector;
kpeter@806
    99
    typedef std::vector<Value> ValueVector;
kpeter@806
   100
    typedef std::vector<Cost> CostVector;
kpeter@805
   101
kpeter@805
   102
  private:
kpeter@805
   103
kpeter@806
   104
    // Data related to the underlying digraph
kpeter@806
   105
    const GR &_graph;
kpeter@806
   106
    int _node_num;
kpeter@806
   107
    int _arc_num;
kpeter@806
   108
    int _res_arc_num;
kpeter@806
   109
    int _root;
kpeter@806
   110
kpeter@806
   111
    // Parameters of the problem
kpeter@806
   112
    bool _have_lower;
kpeter@806
   113
    Value _sum_supply;
kpeter@806
   114
kpeter@806
   115
    // Data structures for storing the digraph
kpeter@806
   116
    IntNodeMap _node_id;
kpeter@806
   117
    IntArcMap _arc_idf;
kpeter@806
   118
    IntArcMap _arc_idb;
kpeter@806
   119
    IntVector _first_out;
kpeter@806
   120
    BoolVector _forward;
kpeter@806
   121
    IntVector _source;
kpeter@806
   122
    IntVector _target;
kpeter@806
   123
    IntVector _reverse;
kpeter@806
   124
kpeter@806
   125
    // Node and arc data
kpeter@806
   126
    ValueVector _lower;
kpeter@806
   127
    ValueVector _upper;
kpeter@806
   128
    CostVector _cost;
kpeter@806
   129
    ValueVector _supply;
kpeter@806
   130
kpeter@806
   131
    ValueVector _res_cap;
kpeter@806
   132
    CostVector _pi;
kpeter@806
   133
    ValueVector _excess;
kpeter@806
   134
    IntVector _excess_nodes;
kpeter@806
   135
    IntVector _deficit_nodes;
kpeter@806
   136
kpeter@806
   137
    Value _delta;
kpeter@806
   138
    int _phase_num;
kpeter@806
   139
    IntVector _pred;
kpeter@806
   140
kpeter@806
   141
  public:
kpeter@806
   142
  
kpeter@806
   143
    /// \brief Constant for infinite upper bounds (capacities).
kpeter@805
   144
    ///
kpeter@806
   145
    /// Constant for infinite upper bounds (capacities).
kpeter@806
   146
    /// It is \c std::numeric_limits<Value>::infinity() if available,
kpeter@806
   147
    /// \c std::numeric_limits<Value>::max() otherwise.
kpeter@806
   148
    const Value INF;
kpeter@806
   149
kpeter@806
   150
  private:
kpeter@806
   151
kpeter@806
   152
    // Special implementation of the Dijkstra algorithm for finding
kpeter@806
   153
    // shortest paths in the residual network of the digraph with
kpeter@806
   154
    // respect to the reduced arc costs and modifying the node
kpeter@806
   155
    // potentials according to the found distance labels.
kpeter@805
   156
    class ResidualDijkstra
kpeter@805
   157
    {
kpeter@806
   158
      typedef RangeMap<int> HeapCrossRef;
kpeter@805
   159
      typedef BinHeap<Cost, HeapCrossRef> Heap;
kpeter@805
   160
kpeter@805
   161
    private:
kpeter@805
   162
kpeter@806
   163
      int _node_num;
kpeter@806
   164
      const IntVector &_first_out;
kpeter@806
   165
      const IntVector &_target;
kpeter@806
   166
      const CostVector &_cost;
kpeter@806
   167
      const ValueVector &_res_cap;
kpeter@806
   168
      const ValueVector &_excess;
kpeter@806
   169
      CostVector &_pi;
kpeter@806
   170
      IntVector &_pred;
kpeter@806
   171
      
kpeter@806
   172
      IntVector _proc_nodes;
kpeter@806
   173
      CostVector _dist;
kpeter@806
   174
      
kpeter@805
   175
    public:
kpeter@805
   176
kpeter@806
   177
      ResidualDijkstra(CapacityScaling& cs) :
kpeter@806
   178
        _node_num(cs._node_num), _first_out(cs._first_out), 
kpeter@806
   179
        _target(cs._target), _cost(cs._cost), _res_cap(cs._res_cap),
kpeter@806
   180
        _excess(cs._excess), _pi(cs._pi), _pred(cs._pred),
kpeter@806
   181
        _dist(cs._node_num)
kpeter@805
   182
      {}
kpeter@805
   183
kpeter@806
   184
      int run(int s, Value delta = 1) {
kpeter@806
   185
        HeapCrossRef heap_cross_ref(_node_num, Heap::PRE_HEAP);
kpeter@805
   186
        Heap heap(heap_cross_ref);
kpeter@805
   187
        heap.push(s, 0);
kpeter@806
   188
        _pred[s] = -1;
kpeter@805
   189
        _proc_nodes.clear();
kpeter@805
   190
kpeter@806
   191
        // Process nodes
kpeter@805
   192
        while (!heap.empty() && _excess[heap.top()] > -delta) {
kpeter@806
   193
          int u = heap.top(), v;
kpeter@806
   194
          Cost d = heap.prio() + _pi[u], dn;
kpeter@805
   195
          _dist[u] = heap.prio();
kpeter@806
   196
          _proc_nodes.push_back(u);
kpeter@805
   197
          heap.pop();
kpeter@805
   198
kpeter@806
   199
          // Traverse outgoing residual arcs
kpeter@806
   200
          for (int a = _first_out[u]; a != _first_out[u+1]; ++a) {
kpeter@806
   201
            if (_res_cap[a] < delta) continue;
kpeter@806
   202
            v = _target[a];
kpeter@806
   203
            switch (heap.state(v)) {
kpeter@805
   204
              case Heap::PRE_HEAP:
kpeter@806
   205
                heap.push(v, d + _cost[a] - _pi[v]);
kpeter@806
   206
                _pred[v] = a;
kpeter@805
   207
                break;
kpeter@805
   208
              case Heap::IN_HEAP:
kpeter@806
   209
                dn = d + _cost[a] - _pi[v];
kpeter@806
   210
                if (dn < heap[v]) {
kpeter@806
   211
                  heap.decrease(v, dn);
kpeter@806
   212
                  _pred[v] = a;
kpeter@805
   213
                }
kpeter@805
   214
                break;
kpeter@805
   215
              case Heap::POST_HEAP:
kpeter@805
   216
                break;
kpeter@805
   217
            }
kpeter@805
   218
          }
kpeter@805
   219
        }
kpeter@806
   220
        if (heap.empty()) return -1;
kpeter@805
   221
kpeter@806
   222
        // Update potentials of processed nodes
kpeter@806
   223
        int t = heap.top();
kpeter@806
   224
        Cost dt = heap.prio();
kpeter@806
   225
        for (int i = 0; i < int(_proc_nodes.size()); ++i) {
kpeter@806
   226
          _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - dt;
kpeter@806
   227
        }
kpeter@805
   228
kpeter@805
   229
        return t;
kpeter@805
   230
      }
kpeter@805
   231
kpeter@805
   232
    }; //class ResidualDijkstra
kpeter@805
   233
kpeter@805
   234
  public:
kpeter@805
   235
kpeter@806
   236
    /// \brief Constructor.
kpeter@805
   237
    ///
kpeter@806
   238
    /// The constructor of the class.
kpeter@805
   239
    ///
kpeter@806
   240
    /// \param graph The digraph the algorithm runs on.
kpeter@806
   241
    CapacityScaling(const GR& graph) :
kpeter@806
   242
      _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
kpeter@806
   243
      INF(std::numeric_limits<Value>::has_infinity ?
kpeter@806
   244
          std::numeric_limits<Value>::infinity() :
kpeter@806
   245
          std::numeric_limits<Value>::max())
kpeter@805
   246
    {
kpeter@806
   247
      // Check the value types
kpeter@806
   248
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
kpeter@806
   249
        "The flow type of CapacityScaling must be signed");
kpeter@806
   250
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
kpeter@806
   251
        "The cost type of CapacityScaling must be signed");
kpeter@806
   252
kpeter@806
   253
      // Resize vectors
kpeter@806
   254
      _node_num = countNodes(_graph);
kpeter@806
   255
      _arc_num = countArcs(_graph);
kpeter@806
   256
      _res_arc_num = 2 * (_arc_num + _node_num);
kpeter@806
   257
      _root = _node_num;
kpeter@806
   258
      ++_node_num;
kpeter@806
   259
kpeter@806
   260
      _first_out.resize(_node_num + 1);
kpeter@806
   261
      _forward.resize(_res_arc_num);
kpeter@806
   262
      _source.resize(_res_arc_num);
kpeter@806
   263
      _target.resize(_res_arc_num);
kpeter@806
   264
      _reverse.resize(_res_arc_num);
kpeter@806
   265
kpeter@806
   266
      _lower.resize(_res_arc_num);
kpeter@806
   267
      _upper.resize(_res_arc_num);
kpeter@806
   268
      _cost.resize(_res_arc_num);
kpeter@806
   269
      _supply.resize(_node_num);
kpeter@806
   270
      
kpeter@806
   271
      _res_cap.resize(_res_arc_num);
kpeter@806
   272
      _pi.resize(_node_num);
kpeter@806
   273
      _excess.resize(_node_num);
kpeter@806
   274
      _pred.resize(_node_num);
kpeter@806
   275
kpeter@806
   276
      // Copy the graph
kpeter@806
   277
      int i = 0, j = 0, k = 2 * _arc_num + _node_num - 1;
kpeter@806
   278
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
kpeter@806
   279
        _node_id[n] = i;
kpeter@805
   280
      }
kpeter@806
   281
      i = 0;
kpeter@806
   282
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
kpeter@806
   283
        _first_out[i] = j;
kpeter@806
   284
        for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) {
kpeter@806
   285
          _arc_idf[a] = j;
kpeter@806
   286
          _forward[j] = true;
kpeter@806
   287
          _source[j] = i;
kpeter@806
   288
          _target[j] = _node_id[_graph.runningNode(a)];
kpeter@806
   289
        }
kpeter@806
   290
        for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) {
kpeter@806
   291
          _arc_idb[a] = j;
kpeter@806
   292
          _forward[j] = false;
kpeter@806
   293
          _source[j] = i;
kpeter@806
   294
          _target[j] = _node_id[_graph.runningNode(a)];
kpeter@806
   295
        }
kpeter@806
   296
        _forward[j] = false;
kpeter@806
   297
        _source[j] = i;
kpeter@806
   298
        _target[j] = _root;
kpeter@806
   299
        _reverse[j] = k;
kpeter@806
   300
        _forward[k] = true;
kpeter@806
   301
        _source[k] = _root;
kpeter@806
   302
        _target[k] = i;
kpeter@806
   303
        _reverse[k] = j;
kpeter@806
   304
        ++j; ++k;
kpeter@806
   305
      }
kpeter@806
   306
      _first_out[i] = j;
kpeter@806
   307
      _first_out[_node_num] = k;
kpeter@805
   308
      for (ArcIt a(_graph); a != INVALID; ++a) {
kpeter@806
   309
        int fi = _arc_idf[a];
kpeter@806
   310
        int bi = _arc_idb[a];
kpeter@806
   311
        _reverse[fi] = bi;
kpeter@806
   312
        _reverse[bi] = fi;
kpeter@805
   313
      }
kpeter@806
   314
      
kpeter@806
   315
      // Reset parameters
kpeter@806
   316
      reset();
kpeter@805
   317
    }
kpeter@805
   318
kpeter@806
   319
    /// \name Parameters
kpeter@806
   320
    /// The parameters of the algorithm can be specified using these
kpeter@806
   321
    /// functions.
kpeter@806
   322
kpeter@806
   323
    /// @{
kpeter@806
   324
kpeter@806
   325
    /// \brief Set the lower bounds on the arcs.
kpeter@805
   326
    ///
kpeter@806
   327
    /// This function sets the lower bounds on the arcs.
kpeter@806
   328
    /// If it is not used before calling \ref run(), the lower bounds
kpeter@806
   329
    /// will be set to zero on all arcs.
kpeter@805
   330
    ///
kpeter@806
   331
    /// \param map An arc map storing the lower bounds.
kpeter@806
   332
    /// Its \c Value type must be convertible to the \c Value type
kpeter@806
   333
    /// of the algorithm.
kpeter@806
   334
    ///
kpeter@806
   335
    /// \return <tt>(*this)</tt>
kpeter@806
   336
    template <typename LowerMap>
kpeter@806
   337
    CapacityScaling& lowerMap(const LowerMap& map) {
kpeter@806
   338
      _have_lower = true;
kpeter@806
   339
      for (ArcIt a(_graph); a != INVALID; ++a) {
kpeter@806
   340
        _lower[_arc_idf[a]] = map[a];
kpeter@806
   341
        _lower[_arc_idb[a]] = map[a];
kpeter@805
   342
      }
kpeter@805
   343
      return *this;
kpeter@805
   344
    }
kpeter@805
   345
kpeter@806
   346
    /// \brief Set the upper bounds (capacities) on the arcs.
kpeter@805
   347
    ///
kpeter@806
   348
    /// This function sets the upper bounds (capacities) on the arcs.
kpeter@806
   349
    /// If it is not used before calling \ref run(), the upper bounds
kpeter@806
   350
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
kpeter@806
   351
    /// unbounded from above on each arc).
kpeter@805
   352
    ///
kpeter@806
   353
    /// \param map An arc map storing the upper bounds.
kpeter@806
   354
    /// Its \c Value type must be convertible to the \c Value type
kpeter@806
   355
    /// of the algorithm.
kpeter@806
   356
    ///
kpeter@806
   357
    /// \return <tt>(*this)</tt>
kpeter@806
   358
    template<typename UpperMap>
kpeter@806
   359
    CapacityScaling& upperMap(const UpperMap& map) {
kpeter@806
   360
      for (ArcIt a(_graph); a != INVALID; ++a) {
kpeter@806
   361
        _upper[_arc_idf[a]] = map[a];
kpeter@805
   362
      }
kpeter@805
   363
      return *this;
kpeter@805
   364
    }
kpeter@805
   365
kpeter@806
   366
    /// \brief Set the costs of the arcs.
kpeter@806
   367
    ///
kpeter@806
   368
    /// This function sets the costs of the arcs.
kpeter@806
   369
    /// If it is not used before calling \ref run(), the costs
kpeter@806
   370
    /// will be set to \c 1 on all arcs.
kpeter@806
   371
    ///
kpeter@806
   372
    /// \param map An arc map storing the costs.
kpeter@806
   373
    /// Its \c Value type must be convertible to the \c Cost type
kpeter@806
   374
    /// of the algorithm.
kpeter@806
   375
    ///
kpeter@806
   376
    /// \return <tt>(*this)</tt>
kpeter@806
   377
    template<typename CostMap>
kpeter@806
   378
    CapacityScaling& costMap(const CostMap& map) {
kpeter@806
   379
      for (ArcIt a(_graph); a != INVALID; ++a) {
kpeter@806
   380
        _cost[_arc_idf[a]] =  map[a];
kpeter@806
   381
        _cost[_arc_idb[a]] = -map[a];
kpeter@806
   382
      }
kpeter@806
   383
      return *this;
kpeter@806
   384
    }
kpeter@806
   385
kpeter@806
   386
    /// \brief Set the supply values of the nodes.
kpeter@806
   387
    ///
kpeter@806
   388
    /// This function sets the supply values of the nodes.
kpeter@806
   389
    /// If neither this function nor \ref stSupply() is used before
kpeter@806
   390
    /// calling \ref run(), the supply of each node will be set to zero.
kpeter@806
   391
    ///
kpeter@806
   392
    /// \param map A node map storing the supply values.
kpeter@806
   393
    /// Its \c Value type must be convertible to the \c Value type
kpeter@806
   394
    /// of the algorithm.
kpeter@806
   395
    ///
kpeter@806
   396
    /// \return <tt>(*this)</tt>
kpeter@806
   397
    template<typename SupplyMap>
kpeter@806
   398
    CapacityScaling& supplyMap(const SupplyMap& map) {
kpeter@806
   399
      for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@806
   400
        _supply[_node_id[n]] = map[n];
kpeter@806
   401
      }
kpeter@806
   402
      return *this;
kpeter@806
   403
    }
kpeter@806
   404
kpeter@806
   405
    /// \brief Set single source and target nodes and a supply value.
kpeter@806
   406
    ///
kpeter@806
   407
    /// This function sets a single source node and a single target node
kpeter@806
   408
    /// and the required flow value.
kpeter@806
   409
    /// If neither this function nor \ref supplyMap() is used before
kpeter@806
   410
    /// calling \ref run(), the supply of each node will be set to zero.
kpeter@806
   411
    ///
kpeter@806
   412
    /// Using this function has the same effect as using \ref supplyMap()
kpeter@806
   413
    /// with such a map in which \c k is assigned to \c s, \c -k is
kpeter@806
   414
    /// assigned to \c t and all other nodes have zero supply value.
kpeter@806
   415
    ///
kpeter@806
   416
    /// \param s The source node.
kpeter@806
   417
    /// \param t The target node.
kpeter@806
   418
    /// \param k The required amount of flow from node \c s to node \c t
kpeter@806
   419
    /// (i.e. the supply of \c s and the demand of \c t).
kpeter@806
   420
    ///
kpeter@806
   421
    /// \return <tt>(*this)</tt>
kpeter@806
   422
    CapacityScaling& stSupply(const Node& s, const Node& t, Value k) {
kpeter@806
   423
      for (int i = 0; i != _node_num; ++i) {
kpeter@806
   424
        _supply[i] = 0;
kpeter@806
   425
      }
kpeter@806
   426
      _supply[_node_id[s]] =  k;
kpeter@806
   427
      _supply[_node_id[t]] = -k;
kpeter@806
   428
      return *this;
kpeter@806
   429
    }
kpeter@806
   430
    
kpeter@806
   431
    /// @}
kpeter@806
   432
kpeter@805
   433
    /// \name Execution control
kpeter@805
   434
kpeter@805
   435
    /// @{
kpeter@805
   436
kpeter@805
   437
    /// \brief Run the algorithm.
kpeter@805
   438
    ///
kpeter@805
   439
    /// This function runs the algorithm.
kpeter@806
   440
    /// The paramters can be specified using functions \ref lowerMap(),
kpeter@806
   441
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
kpeter@806
   442
    /// For example,
kpeter@806
   443
    /// \code
kpeter@806
   444
    ///   CapacityScaling<ListDigraph> cs(graph);
kpeter@806
   445
    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
kpeter@806
   446
    ///     .supplyMap(sup).run();
kpeter@806
   447
    /// \endcode
kpeter@806
   448
    ///
kpeter@806
   449
    /// This function can be called more than once. All the parameters
kpeter@806
   450
    /// that have been given are kept for the next call, unless
kpeter@806
   451
    /// \ref reset() is called, thus only the modified parameters
kpeter@806
   452
    /// have to be set again. See \ref reset() for examples.
kpeter@806
   453
    /// However the underlying digraph must not be modified after this
kpeter@806
   454
    /// class have been constructed, since it copies the digraph.
kpeter@805
   455
    ///
kpeter@805
   456
    /// \param scaling Enable or disable capacity scaling.
kpeter@806
   457
    /// If the maximum upper bound and/or the amount of total supply
kpeter@805
   458
    /// is rather small, the algorithm could be slightly faster without
kpeter@805
   459
    /// scaling.
kpeter@805
   460
    ///
kpeter@806
   461
    /// \return \c INFEASIBLE if no feasible flow exists,
kpeter@806
   462
    /// \n \c OPTIMAL if the problem has optimal solution
kpeter@806
   463
    /// (i.e. it is feasible and bounded), and the algorithm has found
kpeter@806
   464
    /// optimal flow and node potentials (primal and dual solutions),
kpeter@806
   465
    /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
kpeter@806
   466
    /// and infinite upper bound. It means that the objective function
kpeter@806
   467
    /// is unbounded on that arc, however note that it could actually be
kpeter@806
   468
    /// bounded over the feasible flows, but this algroithm cannot handle
kpeter@806
   469
    /// these cases.
kpeter@806
   470
    ///
kpeter@806
   471
    /// \see ProblemType
kpeter@806
   472
    ProblemType run(bool scaling = true) {
kpeter@806
   473
      ProblemType pt = init(scaling);
kpeter@806
   474
      if (pt != OPTIMAL) return pt;
kpeter@806
   475
      return start();
kpeter@806
   476
    }
kpeter@806
   477
kpeter@806
   478
    /// \brief Reset all the parameters that have been given before.
kpeter@806
   479
    ///
kpeter@806
   480
    /// This function resets all the paramaters that have been given
kpeter@806
   481
    /// before using functions \ref lowerMap(), \ref upperMap(),
kpeter@806
   482
    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
kpeter@806
   483
    ///
kpeter@806
   484
    /// It is useful for multiple run() calls. If this function is not
kpeter@806
   485
    /// used, all the parameters given before are kept for the next
kpeter@806
   486
    /// \ref run() call.
kpeter@806
   487
    /// However the underlying digraph must not be modified after this
kpeter@806
   488
    /// class have been constructed, since it copies and extends the graph.
kpeter@806
   489
    ///
kpeter@806
   490
    /// For example,
kpeter@806
   491
    /// \code
kpeter@806
   492
    ///   CapacityScaling<ListDigraph> cs(graph);
kpeter@806
   493
    ///
kpeter@806
   494
    ///   // First run
kpeter@806
   495
    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
kpeter@806
   496
    ///     .supplyMap(sup).run();
kpeter@806
   497
    ///
kpeter@806
   498
    ///   // Run again with modified cost map (reset() is not called,
kpeter@806
   499
    ///   // so only the cost map have to be set again)
kpeter@806
   500
    ///   cost[e] += 100;
kpeter@806
   501
    ///   cs.costMap(cost).run();
kpeter@806
   502
    ///
kpeter@806
   503
    ///   // Run again from scratch using reset()
kpeter@806
   504
    ///   // (the lower bounds will be set to zero on all arcs)
kpeter@806
   505
    ///   cs.reset();
kpeter@806
   506
    ///   cs.upperMap(capacity).costMap(cost)
kpeter@806
   507
    ///     .supplyMap(sup).run();
kpeter@806
   508
    /// \endcode
kpeter@806
   509
    ///
kpeter@806
   510
    /// \return <tt>(*this)</tt>
kpeter@806
   511
    CapacityScaling& reset() {
kpeter@806
   512
      for (int i = 0; i != _node_num; ++i) {
kpeter@806
   513
        _supply[i] = 0;
kpeter@806
   514
      }
kpeter@806
   515
      for (int j = 0; j != _res_arc_num; ++j) {
kpeter@806
   516
        _lower[j] = 0;
kpeter@806
   517
        _upper[j] = INF;
kpeter@806
   518
        _cost[j] = _forward[j] ? 1 : -1;
kpeter@806
   519
      }
kpeter@806
   520
      _have_lower = false;
kpeter@806
   521
      return *this;
kpeter@805
   522
    }
kpeter@805
   523
kpeter@805
   524
    /// @}
kpeter@805
   525
kpeter@805
   526
    /// \name Query Functions
kpeter@805
   527
    /// The results of the algorithm can be obtained using these
kpeter@805
   528
    /// functions.\n
kpeter@806
   529
    /// The \ref run() function must be called before using them.
kpeter@805
   530
kpeter@805
   531
    /// @{
kpeter@805
   532
kpeter@806
   533
    /// \brief Return the total cost of the found flow.
kpeter@805
   534
    ///
kpeter@806
   535
    /// This function returns the total cost of the found flow.
kpeter@806
   536
    /// Its complexity is O(e).
kpeter@806
   537
    ///
kpeter@806
   538
    /// \note The return type of the function can be specified as a
kpeter@806
   539
    /// template parameter. For example,
kpeter@806
   540
    /// \code
kpeter@806
   541
    ///   cs.totalCost<double>();
kpeter@806
   542
    /// \endcode
kpeter@806
   543
    /// It is useful if the total cost cannot be stored in the \c Cost
kpeter@806
   544
    /// type of the algorithm, which is the default return type of the
kpeter@806
   545
    /// function.
kpeter@805
   546
    ///
kpeter@805
   547
    /// \pre \ref run() must be called before using this function.
kpeter@806
   548
    template <typename Number>
kpeter@806
   549
    Number totalCost() const {
kpeter@806
   550
      Number c = 0;
kpeter@806
   551
      for (ArcIt a(_graph); a != INVALID; ++a) {
kpeter@806
   552
        int i = _arc_idb[a];
kpeter@806
   553
        c += static_cast<Number>(_res_cap[i]) *
kpeter@806
   554
             (-static_cast<Number>(_cost[i]));
kpeter@806
   555
      }
kpeter@806
   556
      return c;
kpeter@805
   557
    }
kpeter@805
   558
kpeter@806
   559
#ifndef DOXYGEN
kpeter@806
   560
    Cost totalCost() const {
kpeter@806
   561
      return totalCost<Cost>();
kpeter@805
   562
    }
kpeter@806
   563
#endif
kpeter@805
   564
kpeter@805
   565
    /// \brief Return the flow on the given arc.
kpeter@805
   566
    ///
kpeter@806
   567
    /// This function returns the flow on the given arc.
kpeter@805
   568
    ///
kpeter@805
   569
    /// \pre \ref run() must be called before using this function.
kpeter@806
   570
    Value flow(const Arc& a) const {
kpeter@806
   571
      return _res_cap[_arc_idb[a]];
kpeter@805
   572
    }
kpeter@805
   573
kpeter@806
   574
    /// \brief Return the flow map (the primal solution).
kpeter@805
   575
    ///
kpeter@806
   576
    /// This function copies the flow value on each arc into the given
kpeter@806
   577
    /// map. The \c Value type of the algorithm must be convertible to
kpeter@806
   578
    /// the \c Value type of the map.
kpeter@805
   579
    ///
kpeter@805
   580
    /// \pre \ref run() must be called before using this function.
kpeter@806
   581
    template <typename FlowMap>
kpeter@806
   582
    void flowMap(FlowMap &map) const {
kpeter@806
   583
      for (ArcIt a(_graph); a != INVALID; ++a) {
kpeter@806
   584
        map.set(a, _res_cap[_arc_idb[a]]);
kpeter@806
   585
      }
kpeter@805
   586
    }
kpeter@805
   587
kpeter@806
   588
    /// \brief Return the potential (dual value) of the given node.
kpeter@805
   589
    ///
kpeter@806
   590
    /// This function returns the potential (dual value) of the
kpeter@806
   591
    /// given node.
kpeter@805
   592
    ///
kpeter@805
   593
    /// \pre \ref run() must be called before using this function.
kpeter@806
   594
    Cost potential(const Node& n) const {
kpeter@806
   595
      return _pi[_node_id[n]];
kpeter@806
   596
    }
kpeter@806
   597
kpeter@806
   598
    /// \brief Return the potential map (the dual solution).
kpeter@806
   599
    ///
kpeter@806
   600
    /// This function copies the potential (dual value) of each node
kpeter@806
   601
    /// into the given map.
kpeter@806
   602
    /// The \c Cost type of the algorithm must be convertible to the
kpeter@806
   603
    /// \c Value type of the map.
kpeter@806
   604
    ///
kpeter@806
   605
    /// \pre \ref run() must be called before using this function.
kpeter@806
   606
    template <typename PotentialMap>
kpeter@806
   607
    void potentialMap(PotentialMap &map) const {
kpeter@806
   608
      for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@806
   609
        map.set(n, _pi[_node_id[n]]);
kpeter@806
   610
      }
kpeter@805
   611
    }
kpeter@805
   612
kpeter@805
   613
    /// @}
kpeter@805
   614
kpeter@805
   615
  private:
kpeter@805
   616
kpeter@806
   617
    // Initialize the algorithm
kpeter@806
   618
    ProblemType init(bool scaling) {
kpeter@806
   619
      if (_node_num == 0) return INFEASIBLE;
kpeter@805
   620
kpeter@806
   621
      // Check the sum of supply values
kpeter@806
   622
      _sum_supply = 0;
kpeter@806
   623
      for (int i = 0; i != _root; ++i) {
kpeter@806
   624
        _sum_supply += _supply[i];
kpeter@805
   625
      }
kpeter@806
   626
      if (_sum_supply > 0) return INFEASIBLE;
kpeter@806
   627
      
kpeter@806
   628
      // Initialize maps
kpeter@806
   629
      for (int i = 0; i != _root; ++i) {
kpeter@806
   630
        _pi[i] = 0;
kpeter@806
   631
        _excess[i] = _supply[i];
kpeter@805
   632
      }
kpeter@805
   633
kpeter@806
   634
      // Remove non-zero lower bounds
kpeter@806
   635
      if (_have_lower) {
kpeter@806
   636
        for (int i = 0; i != _root; ++i) {
kpeter@806
   637
          for (int j = _first_out[i]; j != _first_out[i+1]; ++j) {
kpeter@806
   638
            if (_forward[j]) {
kpeter@806
   639
              Value c = _lower[j];
kpeter@806
   640
              if (c >= 0) {
kpeter@806
   641
                _res_cap[j] = _upper[j] < INF ? _upper[j] - c : INF;
kpeter@806
   642
              } else {
kpeter@806
   643
                _res_cap[j] = _upper[j] < INF + c ? _upper[j] - c : INF;
kpeter@806
   644
              }
kpeter@806
   645
              _excess[i] -= c;
kpeter@806
   646
              _excess[_target[j]] += c;
kpeter@806
   647
            } else {
kpeter@806
   648
              _res_cap[j] = 0;
kpeter@806
   649
            }
kpeter@806
   650
          }
kpeter@806
   651
        }
kpeter@806
   652
      } else {
kpeter@806
   653
        for (int j = 0; j != _res_arc_num; ++j) {
kpeter@806
   654
          _res_cap[j] = _forward[j] ? _upper[j] : 0;
kpeter@806
   655
        }
kpeter@806
   656
      }
kpeter@805
   657
kpeter@806
   658
      // Handle negative costs
kpeter@806
   659
      for (int u = 0; u != _root; ++u) {
kpeter@806
   660
        for (int a = _first_out[u]; a != _first_out[u+1]; ++a) {
kpeter@806
   661
          Value rc = _res_cap[a];
kpeter@806
   662
          if (_cost[a] < 0 && rc > 0) {
kpeter@806
   663
            if (rc == INF) return UNBOUNDED;
kpeter@806
   664
            _excess[u] -= rc;
kpeter@806
   665
            _excess[_target[a]] += rc;
kpeter@806
   666
            _res_cap[a] = 0;
kpeter@806
   667
            _res_cap[_reverse[a]] += rc;
kpeter@806
   668
          }
kpeter@806
   669
        }
kpeter@806
   670
      }
kpeter@806
   671
      
kpeter@806
   672
      // Handle GEQ supply type
kpeter@806
   673
      if (_sum_supply < 0) {
kpeter@806
   674
        _pi[_root] = 0;
kpeter@806
   675
        _excess[_root] = -_sum_supply;
kpeter@806
   676
        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
kpeter@806
   677
          int u = _target[a];
kpeter@806
   678
          if (_excess[u] < 0) {
kpeter@806
   679
            _res_cap[a] = -_excess[u] + 1;
kpeter@806
   680
          } else {
kpeter@806
   681
            _res_cap[a] = 1;
kpeter@806
   682
          }
kpeter@806
   683
          _res_cap[_reverse[a]] = 0;
kpeter@806
   684
          _cost[a] = 0;
kpeter@806
   685
          _cost[_reverse[a]] = 0;
kpeter@806
   686
        }
kpeter@806
   687
      } else {
kpeter@806
   688
        _pi[_root] = 0;
kpeter@806
   689
        _excess[_root] = 0;
kpeter@806
   690
        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
kpeter@806
   691
          _res_cap[a] = 1;
kpeter@806
   692
          _res_cap[_reverse[a]] = 0;
kpeter@806
   693
          _cost[a] = 0;
kpeter@806
   694
          _cost[_reverse[a]] = 0;
kpeter@806
   695
        }
kpeter@806
   696
      }
kpeter@806
   697
kpeter@806
   698
      // Initialize delta value
kpeter@805
   699
      if (scaling) {
kpeter@805
   700
        // With scaling
kpeter@806
   701
        Value max_sup = 0, max_dem = 0;
kpeter@806
   702
        for (int i = 0; i != _node_num; ++i) {
kpeter@806
   703
          if ( _excess[i] > max_sup) max_sup =  _excess[i];
kpeter@806
   704
          if (-_excess[i] > max_dem) max_dem = -_excess[i];
kpeter@805
   705
        }
kpeter@806
   706
        Value max_cap = 0;
kpeter@806
   707
        for (int j = 0; j != _res_arc_num; ++j) {
kpeter@806
   708
          if (_res_cap[j] > max_cap) max_cap = _res_cap[j];
kpeter@805
   709
        }
kpeter@805
   710
        max_sup = std::min(std::min(max_sup, max_dem), max_cap);
kpeter@805
   711
        _phase_num = 0;
kpeter@805
   712
        for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2)
kpeter@805
   713
          ++_phase_num;
kpeter@805
   714
      } else {
kpeter@805
   715
        // Without scaling
kpeter@805
   716
        _delta = 1;
kpeter@805
   717
      }
kpeter@805
   718
kpeter@806
   719
      return OPTIMAL;
kpeter@805
   720
    }
kpeter@805
   721
kpeter@806
   722
    ProblemType start() {
kpeter@806
   723
      // Execute the algorithm
kpeter@806
   724
      ProblemType pt;
kpeter@805
   725
      if (_delta > 1)
kpeter@806
   726
        pt = startWithScaling();
kpeter@805
   727
      else
kpeter@806
   728
        pt = startWithoutScaling();
kpeter@806
   729
kpeter@806
   730
      // Handle non-zero lower bounds
kpeter@806
   731
      if (_have_lower) {
kpeter@806
   732
        for (int j = 0; j != _res_arc_num - _node_num + 1; ++j) {
kpeter@806
   733
          if (!_forward[j]) _res_cap[j] += _lower[j];
kpeter@806
   734
        }
kpeter@806
   735
      }
kpeter@806
   736
kpeter@806
   737
      // Shift potentials if necessary
kpeter@806
   738
      Cost pr = _pi[_root];
kpeter@806
   739
      if (_sum_supply < 0 || pr > 0) {
kpeter@806
   740
        for (int i = 0; i != _node_num; ++i) {
kpeter@806
   741
          _pi[i] -= pr;
kpeter@806
   742
        }        
kpeter@806
   743
      }
kpeter@806
   744
      
kpeter@806
   745
      return pt;
kpeter@805
   746
    }
kpeter@805
   747
kpeter@806
   748
    // Execute the capacity scaling algorithm
kpeter@806
   749
    ProblemType startWithScaling() {
kpeter@806
   750
      // Process capacity scaling phases
kpeter@806
   751
      int s, t;
kpeter@805
   752
      int phase_cnt = 0;
kpeter@805
   753
      int factor = 4;
kpeter@806
   754
      ResidualDijkstra _dijkstra(*this);
kpeter@805
   755
      while (true) {
kpeter@806
   756
        // Saturate all arcs not satisfying the optimality condition
kpeter@806
   757
        for (int u = 0; u != _node_num; ++u) {
kpeter@806
   758
          for (int a = _first_out[u]; a != _first_out[u+1]; ++a) {
kpeter@806
   759
            int v = _target[a];
kpeter@806
   760
            Cost c = _cost[a] + _pi[u] - _pi[v];
kpeter@806
   761
            Value rc = _res_cap[a];
kpeter@806
   762
            if (c < 0 && rc >= _delta) {
kpeter@806
   763
              _excess[u] -= rc;
kpeter@806
   764
              _excess[v] += rc;
kpeter@806
   765
              _res_cap[a] = 0;
kpeter@806
   766
              _res_cap[_reverse[a]] += rc;
kpeter@806
   767
            }
kpeter@805
   768
          }
kpeter@805
   769
        }
kpeter@805
   770
kpeter@806
   771
        // Find excess nodes and deficit nodes
kpeter@805
   772
        _excess_nodes.clear();
kpeter@805
   773
        _deficit_nodes.clear();
kpeter@806
   774
        for (int u = 0; u != _node_num; ++u) {
kpeter@806
   775
          if (_excess[u] >=  _delta) _excess_nodes.push_back(u);
kpeter@806
   776
          if (_excess[u] <= -_delta) _deficit_nodes.push_back(u);
kpeter@805
   777
        }
kpeter@805
   778
        int next_node = 0, next_def_node = 0;
kpeter@805
   779
kpeter@806
   780
        // Find augmenting shortest paths
kpeter@805
   781
        while (next_node < int(_excess_nodes.size())) {
kpeter@806
   782
          // Check deficit nodes
kpeter@805
   783
          if (_delta > 1) {
kpeter@805
   784
            bool delta_deficit = false;
kpeter@805
   785
            for ( ; next_def_node < int(_deficit_nodes.size());
kpeter@805
   786
                    ++next_def_node ) {
kpeter@805
   787
              if (_excess[_deficit_nodes[next_def_node]] <= -_delta) {
kpeter@805
   788
                delta_deficit = true;
kpeter@805
   789
                break;
kpeter@805
   790
              }
kpeter@805
   791
            }
kpeter@805
   792
            if (!delta_deficit) break;
kpeter@805
   793
          }
kpeter@805
   794
kpeter@806
   795
          // Run Dijkstra in the residual network
kpeter@805
   796
          s = _excess_nodes[next_node];
kpeter@806
   797
          if ((t = _dijkstra.run(s, _delta)) == -1) {
kpeter@805
   798
            if (_delta > 1) {
kpeter@805
   799
              ++next_node;
kpeter@805
   800
              continue;
kpeter@805
   801
            }
kpeter@806
   802
            return INFEASIBLE;
kpeter@805
   803
          }
kpeter@805
   804
kpeter@806
   805
          // Augment along a shortest path from s to t
kpeter@806
   806
          Value d = std::min(_excess[s], -_excess[t]);
kpeter@806
   807
          int u = t;
kpeter@806
   808
          int a;
kpeter@805
   809
          if (d > _delta) {
kpeter@806
   810
            while ((a = _pred[u]) != -1) {
kpeter@806
   811
              if (_res_cap[a] < d) d = _res_cap[a];
kpeter@806
   812
              u = _source[a];
kpeter@805
   813
            }
kpeter@805
   814
          }
kpeter@805
   815
          u = t;
kpeter@806
   816
          while ((a = _pred[u]) != -1) {
kpeter@806
   817
            _res_cap[a] -= d;
kpeter@806
   818
            _res_cap[_reverse[a]] += d;
kpeter@806
   819
            u = _source[a];
kpeter@805
   820
          }
kpeter@805
   821
          _excess[s] -= d;
kpeter@805
   822
          _excess[t] += d;
kpeter@805
   823
kpeter@805
   824
          if (_excess[s] < _delta) ++next_node;
kpeter@805
   825
        }
kpeter@805
   826
kpeter@805
   827
        if (_delta == 1) break;
kpeter@806
   828
        if (++phase_cnt == _phase_num / 4) factor = 2;
kpeter@805
   829
        _delta = _delta <= factor ? 1 : _delta / factor;
kpeter@805
   830
      }
kpeter@805
   831
kpeter@806
   832
      return OPTIMAL;
kpeter@805
   833
    }
kpeter@805
   834
kpeter@806
   835
    // Execute the successive shortest path algorithm
kpeter@806
   836
    ProblemType startWithoutScaling() {
kpeter@806
   837
      // Find excess nodes
kpeter@806
   838
      _excess_nodes.clear();
kpeter@806
   839
      for (int i = 0; i != _node_num; ++i) {
kpeter@806
   840
        if (_excess[i] > 0) _excess_nodes.push_back(i);
kpeter@806
   841
      }
kpeter@806
   842
      if (_excess_nodes.size() == 0) return OPTIMAL;
kpeter@805
   843
      int next_node = 0;
kpeter@805
   844
kpeter@806
   845
      // Find shortest paths
kpeter@806
   846
      int s, t;
kpeter@806
   847
      ResidualDijkstra _dijkstra(*this);
kpeter@805
   848
      while ( _excess[_excess_nodes[next_node]] > 0 ||
kpeter@805
   849
              ++next_node < int(_excess_nodes.size()) )
kpeter@805
   850
      {
kpeter@806
   851
        // Run Dijkstra in the residual network
kpeter@805
   852
        s = _excess_nodes[next_node];
kpeter@806
   853
        if ((t = _dijkstra.run(s)) == -1) return INFEASIBLE;
kpeter@805
   854
kpeter@806
   855
        // Augment along a shortest path from s to t
kpeter@806
   856
        Value d = std::min(_excess[s], -_excess[t]);
kpeter@806
   857
        int u = t;
kpeter@806
   858
        int a;
kpeter@805
   859
        if (d > 1) {
kpeter@806
   860
          while ((a = _pred[u]) != -1) {
kpeter@806
   861
            if (_res_cap[a] < d) d = _res_cap[a];
kpeter@806
   862
            u = _source[a];
kpeter@805
   863
          }
kpeter@805
   864
        }
kpeter@805
   865
        u = t;
kpeter@806
   866
        while ((a = _pred[u]) != -1) {
kpeter@806
   867
          _res_cap[a] -= d;
kpeter@806
   868
          _res_cap[_reverse[a]] += d;
kpeter@806
   869
          u = _source[a];
kpeter@805
   870
        }
kpeter@805
   871
        _excess[s] -= d;
kpeter@805
   872
        _excess[t] += d;
kpeter@805
   873
      }
kpeter@805
   874
kpeter@806
   875
      return OPTIMAL;
kpeter@805
   876
    }
kpeter@805
   877
kpeter@805
   878
  }; //class CapacityScaling
kpeter@805
   879
kpeter@805
   880
  ///@}
kpeter@805
   881
kpeter@805
   882
} //namespace lemon
kpeter@805
   883
kpeter@805
   884
#endif //LEMON_CAPACITY_SCALING_H