lemon/cost_scaling.h
author kpeter
Thu, 28 Feb 2008 02:54:27 +0000
changeset 2581 054566ac0934
parent 2577 2c6204d4b0f6
child 2588 4d3bc1d04c1d
permissions -rw-r--r--
Query improvements in the min cost flow algorithms.

- External flow and potential maps can be used.
- New query functions: flow() and potential().
- CycleCanceling also provides dual solution (node potentials).
- Doc improvements.
kpeter@2577
     1
/* -*- C++ -*-
kpeter@2577
     2
 *
kpeter@2577
     3
 * This file is a part of LEMON, a generic C++ optimization library
kpeter@2577
     4
 *
kpeter@2577
     5
 * Copyright (C) 2003-2008
kpeter@2577
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
kpeter@2577
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
kpeter@2577
     8
 *
kpeter@2577
     9
 * Permission to use, modify and distribute this software is granted
kpeter@2577
    10
 * provided that this copyright notice appears in all copies. For
kpeter@2577
    11
 * precise terms see the accompanying LICENSE file.
kpeter@2577
    12
 *
kpeter@2577
    13
 * This software is provided "AS IS" with no warranty of any kind,
kpeter@2577
    14
 * express or implied, and with no claim as to its suitability for any
kpeter@2577
    15
 * purpose.
kpeter@2577
    16
 *
kpeter@2577
    17
 */
kpeter@2577
    18
kpeter@2577
    19
#ifndef LEMON_COST_SCALING_H
kpeter@2577
    20
#define LEMON_COST_SCALING_H
kpeter@2577
    21
kpeter@2577
    22
/// \ingroup min_cost_flow
kpeter@2577
    23
///
kpeter@2577
    24
/// \file
kpeter@2577
    25
/// \brief Cost scaling algorithm for finding a minimum cost flow.
kpeter@2577
    26
kpeter@2577
    27
#include <deque>
kpeter@2577
    28
#include <lemon/graph_adaptor.h>
kpeter@2577
    29
#include <lemon/graph_utils.h>
kpeter@2577
    30
#include <lemon/maps.h>
kpeter@2577
    31
#include <lemon/math.h>
kpeter@2577
    32
kpeter@2577
    33
#include <lemon/circulation.h>
kpeter@2577
    34
#include <lemon/bellman_ford.h>
kpeter@2577
    35
kpeter@2577
    36
namespace lemon {
kpeter@2577
    37
kpeter@2577
    38
  /// \addtogroup min_cost_flow
kpeter@2577
    39
  /// @{
kpeter@2577
    40
kpeter@2577
    41
  /// \brief Implementation of the cost scaling algorithm for finding a
kpeter@2577
    42
  /// minimum cost flow.
kpeter@2577
    43
  ///
kpeter@2577
    44
  /// \ref CostScaling implements the cost scaling algorithm performing
kpeter@2577
    45
  /// generalized push-relabel operations for finding a minimum cost
kpeter@2577
    46
  /// flow.
kpeter@2577
    47
  ///
kpeter@2577
    48
  /// \tparam Graph The directed graph type the algorithm runs on.
kpeter@2577
    49
  /// \tparam LowerMap The type of the lower bound map.
kpeter@2577
    50
  /// \tparam CapacityMap The type of the capacity (upper bound) map.
kpeter@2577
    51
  /// \tparam CostMap The type of the cost (length) map.
kpeter@2577
    52
  /// \tparam SupplyMap The type of the supply map.
kpeter@2577
    53
  ///
kpeter@2577
    54
  /// \warning
kpeter@2577
    55
  /// - Edge capacities and costs should be \e non-negative \e integers.
kpeter@2577
    56
  /// - Supply values should be \e signed \e integers.
kpeter@2581
    57
  /// - The value types of the maps should be convertible to each other.
kpeter@2581
    58
  /// - \c CostMap::Value must be signed type.
kpeter@2577
    59
  ///
kpeter@2577
    60
  /// \note Edge costs are multiplied with the number of nodes during
kpeter@2577
    61
  /// the algorithm so overflow problems may arise more easily than with
kpeter@2577
    62
  /// other minimum cost flow algorithms.
kpeter@2577
    63
  /// If it is available, <tt>long long int</tt> type is used instead of
kpeter@2577
    64
  /// <tt>long int</tt> in the inside computations.
kpeter@2577
    65
  ///
kpeter@2577
    66
  /// \author Peter Kovacs
kpeter@2577
    67
kpeter@2577
    68
  template < typename Graph,
kpeter@2577
    69
             typename LowerMap = typename Graph::template EdgeMap<int>,
kpeter@2577
    70
             typename CapacityMap = typename Graph::template EdgeMap<int>,
kpeter@2577
    71
             typename CostMap = typename Graph::template EdgeMap<int>,
kpeter@2577
    72
             typename SupplyMap = typename Graph::template NodeMap<int> >
kpeter@2577
    73
  class CostScaling
kpeter@2577
    74
  {
kpeter@2577
    75
    GRAPH_TYPEDEFS(typename Graph);
kpeter@2577
    76
kpeter@2577
    77
    typedef typename CapacityMap::Value Capacity;
kpeter@2577
    78
    typedef typename CostMap::Value Cost;
kpeter@2577
    79
    typedef typename SupplyMap::Value Supply;
kpeter@2577
    80
    typedef typename Graph::template EdgeMap<Capacity> CapacityEdgeMap;
kpeter@2577
    81
    typedef typename Graph::template NodeMap<Supply> SupplyNodeMap;
kpeter@2577
    82
kpeter@2577
    83
    typedef ResGraphAdaptor< const Graph, Capacity,
kpeter@2577
    84
                             CapacityEdgeMap, CapacityEdgeMap > ResGraph;
kpeter@2577
    85
    typedef typename ResGraph::Edge ResEdge;
kpeter@2577
    86
kpeter@2577
    87
#if defined __GNUC__ && !defined __STRICT_ANSI__
kpeter@2577
    88
    typedef long long int LCost;
kpeter@2577
    89
#else
kpeter@2577
    90
    typedef long int LCost;
kpeter@2577
    91
#endif
kpeter@2577
    92
    typedef typename Graph::template EdgeMap<LCost> LargeCostMap;
kpeter@2577
    93
kpeter@2577
    94
  public:
kpeter@2577
    95
kpeter@2577
    96
    /// The type of the flow map.
kpeter@2581
    97
    typedef typename Graph::template EdgeMap<Capacity> FlowMap;
kpeter@2577
    98
    /// The type of the potential map.
kpeter@2577
    99
    typedef typename Graph::template NodeMap<LCost> PotentialMap;
kpeter@2577
   100
kpeter@2577
   101
  private:
kpeter@2577
   102
kpeter@2577
   103
    /// \brief Map adaptor class for handling residual edge costs.
kpeter@2577
   104
    ///
kpeter@2577
   105
    /// \ref ResidualCostMap is a map adaptor class for handling
kpeter@2577
   106
    /// residual edge costs.
kpeter@2581
   107
    template <typename Map>
kpeter@2581
   108
    class ResidualCostMap : public MapBase<ResEdge, typename Map::Value>
kpeter@2577
   109
    {
kpeter@2577
   110
    private:
kpeter@2577
   111
kpeter@2581
   112
      const Map &_cost_map;
kpeter@2577
   113
kpeter@2577
   114
    public:
kpeter@2577
   115
kpeter@2577
   116
      ///\e
kpeter@2581
   117
      ResidualCostMap(const Map &cost_map) :
kpeter@2577
   118
        _cost_map(cost_map) {}
kpeter@2577
   119
kpeter@2577
   120
      ///\e
kpeter@2581
   121
      typename Map::Value operator[](const ResEdge &e) const {
kpeter@2577
   122
        return ResGraph::forward(e) ?  _cost_map[e] : -_cost_map[e];
kpeter@2577
   123
      }
kpeter@2577
   124
kpeter@2577
   125
    }; //class ResidualCostMap
kpeter@2577
   126
kpeter@2577
   127
    /// \brief Map adaptor class for handling reduced edge costs.
kpeter@2577
   128
    ///
kpeter@2577
   129
    /// \ref ReducedCostMap is a map adaptor class for handling reduced
kpeter@2577
   130
    /// edge costs.
kpeter@2577
   131
    class ReducedCostMap : public MapBase<Edge, LCost>
kpeter@2577
   132
    {
kpeter@2577
   133
    private:
kpeter@2577
   134
kpeter@2577
   135
      const Graph &_gr;
kpeter@2577
   136
      const LargeCostMap &_cost_map;
kpeter@2577
   137
      const PotentialMap &_pot_map;
kpeter@2577
   138
kpeter@2577
   139
    public:
kpeter@2577
   140
kpeter@2577
   141
      ///\e
kpeter@2577
   142
      ReducedCostMap( const Graph &gr,
kpeter@2577
   143
                      const LargeCostMap &cost_map,
kpeter@2577
   144
                      const PotentialMap &pot_map ) :
kpeter@2577
   145
        _gr(gr), _cost_map(cost_map), _pot_map(pot_map) {}
kpeter@2577
   146
kpeter@2577
   147
      ///\e
kpeter@2577
   148
      LCost operator[](const Edge &e) const {
kpeter@2577
   149
        return _cost_map[e] + _pot_map[_gr.source(e)]
kpeter@2577
   150
                            - _pot_map[_gr.target(e)];
kpeter@2577
   151
      }
kpeter@2577
   152
kpeter@2577
   153
    }; //class ReducedCostMap
kpeter@2577
   154
kpeter@2577
   155
  private:
kpeter@2577
   156
kpeter@2577
   157
    // Scaling factor
kpeter@2577
   158
    static const int ALPHA = 4;
kpeter@2577
   159
kpeter@2577
   160
    // Paramters for heuristics
kpeter@2581
   161
    static const int BF_HEURISTIC_EPSILON_BOUND = 5000;
kpeter@2581
   162
    static const int BF_HEURISTIC_BOUND_FACTOR  = 3;
kpeter@2577
   163
kpeter@2577
   164
  private:
kpeter@2577
   165
kpeter@2577
   166
    // The directed graph the algorithm runs on
kpeter@2577
   167
    const Graph &_graph;
kpeter@2577
   168
    // The original lower bound map
kpeter@2577
   169
    const LowerMap *_lower;
kpeter@2577
   170
    // The modified capacity map
kpeter@2577
   171
    CapacityEdgeMap _capacity;
kpeter@2577
   172
    // The original cost map
kpeter@2577
   173
    const CostMap &_orig_cost;
kpeter@2577
   174
    // The scaled cost map
kpeter@2577
   175
    LargeCostMap _cost;
kpeter@2577
   176
    // The modified supply map
kpeter@2577
   177
    SupplyNodeMap _supply;
kpeter@2577
   178
    bool _valid_supply;
kpeter@2577
   179
kpeter@2577
   180
    // Edge map of the current flow
kpeter@2581
   181
    FlowMap *_flow;
kpeter@2581
   182
    bool _local_flow;
kpeter@2577
   183
    // Node map of the current potentials
kpeter@2581
   184
    PotentialMap *_potential;
kpeter@2581
   185
    bool _local_potential;
kpeter@2577
   186
kpeter@2577
   187
    // The residual graph
kpeter@2581
   188
    ResGraph *_res_graph;
kpeter@2577
   189
    // The residual cost map
kpeter@2581
   190
    ResidualCostMap<LargeCostMap> _res_cost;
kpeter@2577
   191
    // The reduced cost map
kpeter@2581
   192
    ReducedCostMap *_red_cost;
kpeter@2577
   193
    // The excess map
kpeter@2577
   194
    SupplyNodeMap _excess;
kpeter@2577
   195
    // The epsilon parameter used for cost scaling
kpeter@2577
   196
    LCost _epsilon;
kpeter@2577
   197
kpeter@2577
   198
  public:
kpeter@2577
   199
kpeter@2581
   200
    /// \brief General constructor (with lower bounds).
kpeter@2577
   201
    ///
kpeter@2581
   202
    /// General constructor (with lower bounds).
kpeter@2577
   203
    ///
kpeter@2577
   204
    /// \param graph The directed graph the algorithm runs on.
kpeter@2577
   205
    /// \param lower The lower bounds of the edges.
kpeter@2577
   206
    /// \param capacity The capacities (upper bounds) of the edges.
kpeter@2577
   207
    /// \param cost The cost (length) values of the edges.
kpeter@2577
   208
    /// \param supply The supply values of the nodes (signed).
kpeter@2577
   209
    CostScaling( const Graph &graph,
kpeter@2577
   210
                 const LowerMap &lower,
kpeter@2577
   211
                 const CapacityMap &capacity,
kpeter@2577
   212
                 const CostMap &cost,
kpeter@2577
   213
                 const SupplyMap &supply ) :
kpeter@2577
   214
      _graph(graph), _lower(&lower), _capacity(graph), _orig_cost(cost),
kpeter@2581
   215
      _cost(graph), _supply(graph), _flow(0), _local_flow(false),
kpeter@2581
   216
      _potential(0), _local_potential(false), _res_cost(_cost),
kpeter@2581
   217
      _excess(graph, 0)
kpeter@2577
   218
    {
kpeter@2577
   219
      // Removing non-zero lower bounds
kpeter@2577
   220
      _capacity = subMap(capacity, lower);
kpeter@2577
   221
      Supply sum = 0;
kpeter@2577
   222
      for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@2577
   223
        Supply s = supply[n];
kpeter@2577
   224
        for (InEdgeIt e(_graph, n); e != INVALID; ++e)
kpeter@2577
   225
          s += lower[e];
kpeter@2577
   226
        for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
kpeter@2577
   227
          s -= lower[e];
kpeter@2577
   228
        _supply[n] = s;
kpeter@2577
   229
        sum += s;
kpeter@2577
   230
      }
kpeter@2577
   231
      _valid_supply = sum == 0;
kpeter@2577
   232
    }
kpeter@2577
   233
kpeter@2581
   234
    /// \brief General constructor (without lower bounds).
kpeter@2577
   235
    ///
kpeter@2581
   236
    /// General constructor (without lower bounds).
kpeter@2577
   237
    ///
kpeter@2577
   238
    /// \param graph The directed graph the algorithm runs on.
kpeter@2577
   239
    /// \param capacity The capacities (upper bounds) of the edges.
kpeter@2577
   240
    /// \param cost The cost (length) values of the edges.
kpeter@2577
   241
    /// \param supply The supply values of the nodes (signed).
kpeter@2577
   242
    CostScaling( const Graph &graph,
kpeter@2577
   243
                 const CapacityMap &capacity,
kpeter@2577
   244
                 const CostMap &cost,
kpeter@2577
   245
                 const SupplyMap &supply ) :
kpeter@2577
   246
      _graph(graph), _lower(NULL), _capacity(capacity), _orig_cost(cost),
kpeter@2581
   247
      _cost(graph), _supply(supply), _flow(0), _local_flow(false),
kpeter@2581
   248
      _potential(0), _local_potential(false), _res_cost(_cost),
kpeter@2581
   249
      _excess(graph, 0)
kpeter@2577
   250
    {
kpeter@2577
   251
      // Checking the sum of supply values
kpeter@2577
   252
      Supply sum = 0;
kpeter@2577
   253
      for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
kpeter@2577
   254
      _valid_supply = sum == 0;
kpeter@2577
   255
    }
kpeter@2577
   256
kpeter@2581
   257
    /// \brief Simple constructor (with lower bounds).
kpeter@2577
   258
    ///
kpeter@2581
   259
    /// Simple constructor (with lower bounds).
kpeter@2577
   260
    ///
kpeter@2577
   261
    /// \param graph The directed graph the algorithm runs on.
kpeter@2577
   262
    /// \param lower The lower bounds of the edges.
kpeter@2577
   263
    /// \param capacity The capacities (upper bounds) of the edges.
kpeter@2577
   264
    /// \param cost The cost (length) values of the edges.
kpeter@2577
   265
    /// \param s The source node.
kpeter@2577
   266
    /// \param t The target node.
kpeter@2577
   267
    /// \param flow_value The required amount of flow from node \c s
kpeter@2577
   268
    /// to node \c t (i.e. the supply of \c s and the demand of \c t).
kpeter@2577
   269
    CostScaling( const Graph &graph,
kpeter@2577
   270
                 const LowerMap &lower,
kpeter@2577
   271
                 const CapacityMap &capacity,
kpeter@2577
   272
                 const CostMap &cost,
kpeter@2577
   273
                 Node s, Node t,
kpeter@2577
   274
                 Supply flow_value ) :
kpeter@2577
   275
      _graph(graph), _lower(&lower), _capacity(graph), _orig_cost(cost),
kpeter@2581
   276
      _cost(graph), _supply(graph), _flow(0), _local_flow(false),
kpeter@2581
   277
      _potential(0), _local_potential(false), _res_cost(_cost),
kpeter@2581
   278
      _excess(graph, 0)
kpeter@2577
   279
    {
kpeter@2577
   280
      // Removing nonzero lower bounds
kpeter@2577
   281
      _capacity = subMap(capacity, lower);
kpeter@2577
   282
      for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@2577
   283
        Supply sum = 0;
kpeter@2577
   284
        if (n == s) sum =  flow_value;
kpeter@2577
   285
        if (n == t) sum = -flow_value;
kpeter@2577
   286
        for (InEdgeIt e(_graph, n); e != INVALID; ++e)
kpeter@2577
   287
          sum += lower[e];
kpeter@2577
   288
        for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
kpeter@2577
   289
          sum -= lower[e];
kpeter@2577
   290
        _supply[n] = sum;
kpeter@2577
   291
      }
kpeter@2577
   292
      _valid_supply = true;
kpeter@2577
   293
    }
kpeter@2577
   294
kpeter@2581
   295
    /// \brief Simple constructor (without lower bounds).
kpeter@2577
   296
    ///
kpeter@2581
   297
    /// Simple constructor (without lower bounds).
kpeter@2577
   298
    ///
kpeter@2577
   299
    /// \param graph The directed graph the algorithm runs on.
kpeter@2577
   300
    /// \param capacity The capacities (upper bounds) of the edges.
kpeter@2577
   301
    /// \param cost The cost (length) values of the edges.
kpeter@2577
   302
    /// \param s The source node.
kpeter@2577
   303
    /// \param t The target node.
kpeter@2577
   304
    /// \param flow_value The required amount of flow from node \c s
kpeter@2577
   305
    /// to node \c t (i.e. the supply of \c s and the demand of \c t).
kpeter@2577
   306
    CostScaling( const Graph &graph,
kpeter@2577
   307
                 const CapacityMap &capacity,
kpeter@2577
   308
                 const CostMap &cost,
kpeter@2577
   309
                 Node s, Node t,
kpeter@2577
   310
                 Supply flow_value ) :
kpeter@2577
   311
      _graph(graph), _lower(NULL), _capacity(capacity), _orig_cost(cost),
kpeter@2581
   312
      _cost(graph), _supply(graph, 0), _flow(0), _local_flow(false),
kpeter@2581
   313
      _potential(0), _local_potential(false), _res_cost(_cost),
kpeter@2581
   314
      _excess(graph, 0)
kpeter@2577
   315
    {
kpeter@2577
   316
      _supply[s] =  flow_value;
kpeter@2577
   317
      _supply[t] = -flow_value;
kpeter@2577
   318
      _valid_supply = true;
kpeter@2577
   319
    }
kpeter@2577
   320
kpeter@2581
   321
    /// Destructor.
kpeter@2581
   322
    ~CostScaling() {
kpeter@2581
   323
      if (_local_flow) delete _flow;
kpeter@2581
   324
      if (_local_potential) delete _potential;
kpeter@2581
   325
      delete _res_graph;
kpeter@2581
   326
      delete _red_cost;
kpeter@2581
   327
    }
kpeter@2581
   328
kpeter@2581
   329
    /// \brief Sets the flow map.
kpeter@2581
   330
    ///
kpeter@2581
   331
    /// Sets the flow map.
kpeter@2581
   332
    ///
kpeter@2581
   333
    /// \return \c (*this)
kpeter@2581
   334
    CostScaling& flowMap(FlowMap &map) {
kpeter@2581
   335
      if (_local_flow) {
kpeter@2581
   336
        delete _flow;
kpeter@2581
   337
        _local_flow = false;
kpeter@2581
   338
      }
kpeter@2581
   339
      _flow = &map;
kpeter@2581
   340
      return *this;
kpeter@2581
   341
    }
kpeter@2581
   342
kpeter@2581
   343
    /// \brief Sets the potential map.
kpeter@2581
   344
    ///
kpeter@2581
   345
    /// Sets the potential map.
kpeter@2581
   346
    ///
kpeter@2581
   347
    /// \return \c (*this)
kpeter@2581
   348
    CostScaling& potentialMap(PotentialMap &map) {
kpeter@2581
   349
      if (_local_potential) {
kpeter@2581
   350
        delete _potential;
kpeter@2581
   351
        _local_potential = false;
kpeter@2581
   352
      }
kpeter@2581
   353
      _potential = &map;
kpeter@2581
   354
      return *this;
kpeter@2581
   355
    }
kpeter@2581
   356
kpeter@2581
   357
    /// \name Execution control
kpeter@2581
   358
    /// The only way to execute the algorithm is to call the run()
kpeter@2581
   359
    /// function.
kpeter@2581
   360
kpeter@2581
   361
    /// @{
kpeter@2581
   362
kpeter@2577
   363
    /// \brief Runs the algorithm.
kpeter@2577
   364
    ///
kpeter@2577
   365
    /// Runs the algorithm.
kpeter@2577
   366
    ///
kpeter@2577
   367
    /// \return \c true if a feasible flow can be found.
kpeter@2577
   368
    bool run() {
kpeter@2581
   369
      return init() && start();
kpeter@2577
   370
    }
kpeter@2577
   371
kpeter@2581
   372
    /// @}
kpeter@2581
   373
kpeter@2581
   374
    /// \name Query Functions
kpeter@2581
   375
    /// The result of the algorithm can be obtained using these
kpeter@2581
   376
    /// functions.
kpeter@2581
   377
    /// \n run() must be called before using them.
kpeter@2581
   378
kpeter@2581
   379
    /// @{
kpeter@2581
   380
kpeter@2577
   381
    /// \brief Returns a const reference to the edge map storing the
kpeter@2577
   382
    /// found flow.
kpeter@2577
   383
    ///
kpeter@2577
   384
    /// Returns a const reference to the edge map storing the found flow.
kpeter@2577
   385
    ///
kpeter@2577
   386
    /// \pre \ref run() must be called before using this function.
kpeter@2577
   387
    const FlowMap& flowMap() const {
kpeter@2581
   388
      return *_flow;
kpeter@2577
   389
    }
kpeter@2577
   390
kpeter@2577
   391
    /// \brief Returns a const reference to the node map storing the
kpeter@2577
   392
    /// found potentials (the dual solution).
kpeter@2577
   393
    ///
kpeter@2577
   394
    /// Returns a const reference to the node map storing the found
kpeter@2577
   395
    /// potentials (the dual solution).
kpeter@2577
   396
    ///
kpeter@2577
   397
    /// \pre \ref run() must be called before using this function.
kpeter@2577
   398
    const PotentialMap& potentialMap() const {
kpeter@2581
   399
      return *_potential;
kpeter@2581
   400
    }
kpeter@2581
   401
kpeter@2581
   402
    /// \brief Returns the flow on the edge.
kpeter@2581
   403
    ///
kpeter@2581
   404
    /// Returns the flow on the edge.
kpeter@2581
   405
    ///
kpeter@2581
   406
    /// \pre \ref run() must be called before using this function.
kpeter@2581
   407
    Capacity flow(const Edge& edge) const {
kpeter@2581
   408
      return (*_flow)[edge];
kpeter@2581
   409
    }
kpeter@2581
   410
kpeter@2581
   411
    /// \brief Returns the potential of the node.
kpeter@2581
   412
    ///
kpeter@2581
   413
    /// Returns the potential of the node.
kpeter@2581
   414
    ///
kpeter@2581
   415
    /// \pre \ref run() must be called before using this function.
kpeter@2581
   416
    Cost potential(const Node& node) const {
kpeter@2581
   417
      return (*_potential)[node];
kpeter@2577
   418
    }
kpeter@2577
   419
kpeter@2577
   420
    /// \brief Returns the total cost of the found flow.
kpeter@2577
   421
    ///
kpeter@2577
   422
    /// Returns the total cost of the found flow. The complexity of the
kpeter@2577
   423
    /// function is \f$ O(e) \f$.
kpeter@2577
   424
    ///
kpeter@2577
   425
    /// \pre \ref run() must be called before using this function.
kpeter@2577
   426
    Cost totalCost() const {
kpeter@2577
   427
      Cost c = 0;
kpeter@2577
   428
      for (EdgeIt e(_graph); e != INVALID; ++e)
kpeter@2581
   429
        c += (*_flow)[e] * _orig_cost[e];
kpeter@2577
   430
      return c;
kpeter@2577
   431
    }
kpeter@2577
   432
kpeter@2581
   433
    /// @}
kpeter@2581
   434
kpeter@2577
   435
  private:
kpeter@2577
   436
kpeter@2577
   437
    /// Initializes the algorithm.
kpeter@2577
   438
    bool init() {
kpeter@2577
   439
      if (!_valid_supply) return false;
kpeter@2577
   440
kpeter@2581
   441
      // Initializing flow and potential maps
kpeter@2581
   442
      if (!_flow) {
kpeter@2581
   443
        _flow = new FlowMap(_graph);
kpeter@2581
   444
        _local_flow = true;
kpeter@2581
   445
      }
kpeter@2581
   446
      if (!_potential) {
kpeter@2581
   447
        _potential = new PotentialMap(_graph);
kpeter@2581
   448
        _local_potential = true;
kpeter@2581
   449
      }
kpeter@2581
   450
kpeter@2581
   451
      _red_cost = new ReducedCostMap(_graph, _cost, *_potential);
kpeter@2581
   452
      _res_graph = new ResGraph(_graph, _capacity, *_flow);
kpeter@2581
   453
kpeter@2577
   454
      // Initializing the scaled cost map and the epsilon parameter
kpeter@2577
   455
      Cost max_cost = 0;
kpeter@2577
   456
      int node_num = countNodes(_graph);
kpeter@2577
   457
      for (EdgeIt e(_graph); e != INVALID; ++e) {
kpeter@2577
   458
        _cost[e] = LCost(_orig_cost[e]) * node_num * ALPHA;
kpeter@2577
   459
        if (_orig_cost[e] > max_cost) max_cost = _orig_cost[e];
kpeter@2577
   460
      }
kpeter@2577
   461
      _epsilon = max_cost * node_num;
kpeter@2577
   462
kpeter@2577
   463
      // Finding a feasible flow using Circulation
kpeter@2577
   464
      Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap,
kpeter@2577
   465
                   SupplyMap >
kpeter@2581
   466
        circulation( _graph, constMap<Edge>(Capacity(0)), _capacity,
kpeter@2577
   467
                     _supply );
kpeter@2581
   468
      return circulation.flowMap(*_flow).run();
kpeter@2577
   469
    }
kpeter@2577
   470
kpeter@2577
   471
kpeter@2577
   472
    /// Executes the algorithm.
kpeter@2577
   473
    bool start() {
kpeter@2577
   474
      std::deque<Node> active_nodes;
kpeter@2577
   475
      typename Graph::template NodeMap<bool> hyper(_graph, false);
kpeter@2577
   476
kpeter@2577
   477
      int node_num = countNodes(_graph);
kpeter@2577
   478
      for ( ; _epsilon >= 1; _epsilon = _epsilon < ALPHA && _epsilon > 1 ?
kpeter@2577
   479
                                        1 : _epsilon / ALPHA )
kpeter@2577
   480
      {
kpeter@2577
   481
        // Performing price refinement heuristic using Bellman-Ford
kpeter@2577
   482
        // algorithm
kpeter@2577
   483
        if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
kpeter@2581
   484
          typedef ShiftMap< ResidualCostMap<LargeCostMap> > ShiftCostMap;
kpeter@2577
   485
          ShiftCostMap shift_cost(_res_cost, _epsilon);
kpeter@2581
   486
          BellmanFord<ResGraph, ShiftCostMap> bf(*_res_graph, shift_cost);
kpeter@2577
   487
          bf.init(0);
kpeter@2577
   488
          bool done = false;
kpeter@2577
   489
          int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(node_num));
kpeter@2577
   490
          for (int i = 0; i < K && !done; ++i)
kpeter@2577
   491
            done = bf.processNextWeakRound();
kpeter@2577
   492
          if (done) {
kpeter@2577
   493
            for (NodeIt n(_graph); n != INVALID; ++n)
kpeter@2581
   494
              (*_potential)[n] = bf.dist(n);
kpeter@2577
   495
            continue;
kpeter@2577
   496
          }
kpeter@2577
   497
        }
kpeter@2577
   498
kpeter@2577
   499
        // Saturating edges not satisfying the optimality condition
kpeter@2577
   500
        Capacity delta;
kpeter@2577
   501
        for (EdgeIt e(_graph); e != INVALID; ++e) {
kpeter@2581
   502
          if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
kpeter@2581
   503
            delta = _capacity[e] - (*_flow)[e];
kpeter@2577
   504
            _excess[_graph.source(e)] -= delta;
kpeter@2577
   505
            _excess[_graph.target(e)] += delta;
kpeter@2581
   506
            (*_flow)[e] = _capacity[e];
kpeter@2577
   507
          }
kpeter@2581
   508
          if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
kpeter@2581
   509
            _excess[_graph.target(e)] -= (*_flow)[e];
kpeter@2581
   510
            _excess[_graph.source(e)] += (*_flow)[e];
kpeter@2581
   511
            (*_flow)[e] = 0;
kpeter@2577
   512
          }
kpeter@2577
   513
        }
kpeter@2577
   514
kpeter@2577
   515
        // Finding active nodes (i.e. nodes with positive excess)
kpeter@2577
   516
        for (NodeIt n(_graph); n != INVALID; ++n)
kpeter@2577
   517
          if (_excess[n] > 0) active_nodes.push_back(n);
kpeter@2577
   518
kpeter@2577
   519
        // Performing push and relabel operations
kpeter@2577
   520
        while (active_nodes.size() > 0) {
kpeter@2577
   521
          Node n = active_nodes[0], t;
kpeter@2577
   522
          bool relabel_enabled = true;
kpeter@2577
   523
kpeter@2577
   524
          // Performing push operations if there are admissible edges
kpeter@2577
   525
          if (_excess[n] > 0) {
kpeter@2577
   526
            for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
kpeter@2581
   527
              if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
kpeter@2581
   528
                delta = _capacity[e] - (*_flow)[e] <= _excess[n] ?
kpeter@2581
   529
                        _capacity[e] - (*_flow)[e] : _excess[n];
kpeter@2577
   530
                t = _graph.target(e);
kpeter@2577
   531
kpeter@2577
   532
                // Push-look-ahead heuristic
kpeter@2577
   533
                Capacity ahead = -_excess[t];
kpeter@2577
   534
                for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) {
kpeter@2581
   535
                  if (_capacity[oe] - (*_flow)[oe] > 0 && (*_red_cost)[oe] < 0)
kpeter@2581
   536
                    ahead += _capacity[oe] - (*_flow)[oe];
kpeter@2577
   537
                }
kpeter@2577
   538
                for (InEdgeIt ie(_graph, t); ie != INVALID; ++ie) {
kpeter@2581
   539
                  if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
kpeter@2581
   540
                    ahead += (*_flow)[ie];
kpeter@2577
   541
                }
kpeter@2577
   542
                if (ahead < 0) ahead = 0;
kpeter@2577
   543
kpeter@2577
   544
                // Pushing flow along the edge
kpeter@2577
   545
                if (ahead < delta) {
kpeter@2581
   546
                  (*_flow)[e] += ahead;
kpeter@2577
   547
                  _excess[n] -= ahead;
kpeter@2577
   548
                  _excess[t] += ahead;
kpeter@2577
   549
                  active_nodes.push_front(t);
kpeter@2577
   550
                  hyper[t] = true;
kpeter@2577
   551
                  relabel_enabled = false;
kpeter@2577
   552
                  break;
kpeter@2577
   553
                } else {
kpeter@2581
   554
                  (*_flow)[e] += delta;
kpeter@2577
   555
                  _excess[n] -= delta;
kpeter@2577
   556
                  _excess[t] += delta;
kpeter@2577
   557
                  if (_excess[t] > 0 && _excess[t] <= delta)
kpeter@2577
   558
                    active_nodes.push_back(t);
kpeter@2577
   559
                }
kpeter@2577
   560
kpeter@2577
   561
                if (_excess[n] == 0) break;
kpeter@2577
   562
              }
kpeter@2577
   563
            }
kpeter@2577
   564
          }
kpeter@2577
   565
kpeter@2577
   566
          if (_excess[n] > 0) {
kpeter@2577
   567
            for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
kpeter@2581
   568
              if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
kpeter@2581
   569
                delta = (*_flow)[e] <= _excess[n] ? (*_flow)[e] : _excess[n];
kpeter@2577
   570
                t = _graph.source(e);
kpeter@2577
   571
kpeter@2577
   572
                // Push-look-ahead heuristic
kpeter@2577
   573
                Capacity ahead = -_excess[t];
kpeter@2577
   574
                for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) {
kpeter@2581
   575
                  if (_capacity[oe] - (*_flow)[oe] > 0 && (*_red_cost)[oe] < 0)
kpeter@2581
   576
                    ahead += _capacity[oe] - (*_flow)[oe];
kpeter@2577
   577
                }
kpeter@2577
   578
                for (InEdgeIt ie(_graph, t); ie != INVALID; ++ie) {
kpeter@2581
   579
                  if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
kpeter@2581
   580
                    ahead += (*_flow)[ie];
kpeter@2577
   581
                }
kpeter@2577
   582
                if (ahead < 0) ahead = 0;
kpeter@2577
   583
kpeter@2577
   584
                // Pushing flow along the edge
kpeter@2577
   585
                if (ahead < delta) {
kpeter@2581
   586
                  (*_flow)[e] -= ahead;
kpeter@2577
   587
                  _excess[n] -= ahead;
kpeter@2577
   588
                  _excess[t] += ahead;
kpeter@2577
   589
                  active_nodes.push_front(t);
kpeter@2577
   590
                  hyper[t] = true;
kpeter@2577
   591
                  relabel_enabled = false;
kpeter@2577
   592
                  break;
kpeter@2577
   593
                } else {
kpeter@2581
   594
                  (*_flow)[e] -= delta;
kpeter@2577
   595
                  _excess[n] -= delta;
kpeter@2577
   596
                  _excess[t] += delta;
kpeter@2577
   597
                  if (_excess[t] > 0 && _excess[t] <= delta)
kpeter@2577
   598
                    active_nodes.push_back(t);
kpeter@2577
   599
                }
kpeter@2577
   600
kpeter@2577
   601
                if (_excess[n] == 0) break;
kpeter@2577
   602
              }
kpeter@2577
   603
            }
kpeter@2577
   604
          }
kpeter@2577
   605
kpeter@2577
   606
          if (relabel_enabled && (_excess[n] > 0 || hyper[n])) {
kpeter@2577
   607
            // Performing relabel operation if the node is still active
kpeter@2577
   608
            LCost min_red_cost = std::numeric_limits<LCost>::max();
kpeter@2577
   609
            for (OutEdgeIt oe(_graph, n); oe != INVALID; ++oe) {
kpeter@2581
   610
              if ( _capacity[oe] - (*_flow)[oe] > 0 &&
kpeter@2581
   611
                   (*_red_cost)[oe] < min_red_cost )
kpeter@2581
   612
                min_red_cost = (*_red_cost)[oe];
kpeter@2577
   613
            }
kpeter@2577
   614
            for (InEdgeIt ie(_graph, n); ie != INVALID; ++ie) {
kpeter@2581
   615
              if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < min_red_cost)
kpeter@2581
   616
                min_red_cost = -(*_red_cost)[ie];
kpeter@2577
   617
            }
kpeter@2581
   618
            (*_potential)[n] -= min_red_cost + _epsilon;
kpeter@2577
   619
            hyper[n] = false;
kpeter@2577
   620
          }
kpeter@2577
   621
kpeter@2577
   622
          // Removing active nodes with non-positive excess
kpeter@2577
   623
          while ( active_nodes.size() > 0 &&
kpeter@2577
   624
                  _excess[active_nodes[0]] <= 0 &&
kpeter@2577
   625
                  !hyper[active_nodes[0]] ) {
kpeter@2577
   626
            active_nodes.pop_front();
kpeter@2577
   627
          }
kpeter@2577
   628
        }
kpeter@2577
   629
      }
kpeter@2577
   630
kpeter@2581
   631
      // Computing node potentials for the original costs
kpeter@2581
   632
      ResidualCostMap<CostMap> res_cost(_orig_cost);
kpeter@2581
   633
      BellmanFord< ResGraph, ResidualCostMap<CostMap> >
kpeter@2581
   634
        bf(*_res_graph, res_cost);
kpeter@2581
   635
      bf.init(0); bf.start();
kpeter@2581
   636
      for (NodeIt n(_graph); n != INVALID; ++n)
kpeter@2581
   637
        (*_potential)[n] = bf.dist(n);
kpeter@2581
   638
kpeter@2577
   639
      // Handling non-zero lower bounds
kpeter@2577
   640
      if (_lower) {
kpeter@2577
   641
        for (EdgeIt e(_graph); e != INVALID; ++e)
kpeter@2581
   642
          (*_flow)[e] += (*_lower)[e];
kpeter@2577
   643
      }
kpeter@2577
   644
      return true;
kpeter@2577
   645
    }
kpeter@2577
   646
kpeter@2577
   647
  }; //class CostScaling
kpeter@2577
   648
kpeter@2577
   649
  ///@}
kpeter@2577
   650
kpeter@2577
   651
} //namespace lemon
kpeter@2577
   652
kpeter@2577
   653
#endif //LEMON_COST_SCALING_H