lemon/cost_scaling.h
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:29:42 +0100
changeset 874 9c428bb2b105
child 875 22bb98ca0101
permissions -rw-r--r--
Port CostScaling from SVN -r3524 (#180)
kpeter@874
     1
/* -*- C++ -*-
kpeter@874
     2
 *
kpeter@874
     3
 * This file is a part of LEMON, a generic C++ optimization library
kpeter@874
     4
 *
kpeter@874
     5
 * Copyright (C) 2003-2008
kpeter@874
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
kpeter@874
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
kpeter@874
     8
 *
kpeter@874
     9
 * Permission to use, modify and distribute this software is granted
kpeter@874
    10
 * provided that this copyright notice appears in all copies. For
kpeter@874
    11
 * precise terms see the accompanying LICENSE file.
kpeter@874
    12
 *
kpeter@874
    13
 * This software is provided "AS IS" with no warranty of any kind,
kpeter@874
    14
 * express or implied, and with no claim as to its suitability for any
kpeter@874
    15
 * purpose.
kpeter@874
    16
 *
kpeter@874
    17
 */
kpeter@874
    18
kpeter@874
    19
#ifndef LEMON_COST_SCALING_H
kpeter@874
    20
#define LEMON_COST_SCALING_H
kpeter@874
    21
kpeter@874
    22
/// \ingroup min_cost_flow_algs
kpeter@874
    23
/// \file
kpeter@874
    24
/// \brief Cost scaling algorithm for finding a minimum cost flow.
kpeter@874
    25
kpeter@874
    26
#include <vector>
kpeter@874
    27
#include <deque>
kpeter@874
    28
#include <limits>
kpeter@874
    29
kpeter@874
    30
#include <lemon/core.h>
kpeter@874
    31
#include <lemon/maps.h>
kpeter@874
    32
#include <lemon/math.h>
kpeter@874
    33
#include <lemon/adaptors.h>
kpeter@874
    34
#include <lemon/circulation.h>
kpeter@874
    35
#include <lemon/bellman_ford.h>
kpeter@874
    36
kpeter@874
    37
namespace lemon {
kpeter@874
    38
kpeter@874
    39
  /// \addtogroup min_cost_flow_algs
kpeter@874
    40
  /// @{
kpeter@874
    41
kpeter@874
    42
  /// \brief Implementation of the cost scaling algorithm for finding a
kpeter@874
    43
  /// minimum cost flow.
kpeter@874
    44
  ///
kpeter@874
    45
  /// \ref CostScaling implements the cost scaling algorithm performing
kpeter@874
    46
  /// augment/push and relabel operations for finding a minimum cost
kpeter@874
    47
  /// flow.
kpeter@874
    48
  ///
kpeter@874
    49
  /// \tparam Digraph The digraph type the algorithm runs on.
kpeter@874
    50
  /// \tparam LowerMap The type of the lower bound map.
kpeter@874
    51
  /// \tparam CapacityMap The type of the capacity (upper bound) map.
kpeter@874
    52
  /// \tparam CostMap The type of the cost (length) map.
kpeter@874
    53
  /// \tparam SupplyMap The type of the supply map.
kpeter@874
    54
  ///
kpeter@874
    55
  /// \warning
kpeter@874
    56
  /// - Arc capacities and costs should be \e non-negative \e integers.
kpeter@874
    57
  /// - Supply values should be \e signed \e integers.
kpeter@874
    58
  /// - The value types of the maps should be convertible to each other.
kpeter@874
    59
  /// - \c CostMap::Value must be signed type.
kpeter@874
    60
  ///
kpeter@874
    61
  /// \note Arc costs are multiplied with the number of nodes during
kpeter@874
    62
  /// the algorithm so overflow problems may arise more easily than with
kpeter@874
    63
  /// other minimum cost flow algorithms.
kpeter@874
    64
  /// If it is available, <tt>long long int</tt> type is used instead of
kpeter@874
    65
  /// <tt>long int</tt> in the inside computations.
kpeter@874
    66
  ///
kpeter@874
    67
  /// \author Peter Kovacs
kpeter@874
    68
  template < typename Digraph,
kpeter@874
    69
             typename LowerMap = typename Digraph::template ArcMap<int>,
kpeter@874
    70
             typename CapacityMap = typename Digraph::template ArcMap<int>,
kpeter@874
    71
             typename CostMap = typename Digraph::template ArcMap<int>,
kpeter@874
    72
             typename SupplyMap = typename Digraph::template NodeMap<int> >
kpeter@874
    73
  class CostScaling
kpeter@874
    74
  {
kpeter@874
    75
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
kpeter@874
    76
kpeter@874
    77
    typedef typename CapacityMap::Value Capacity;
kpeter@874
    78
    typedef typename CostMap::Value Cost;
kpeter@874
    79
    typedef typename SupplyMap::Value Supply;
kpeter@874
    80
    typedef typename Digraph::template ArcMap<Capacity> CapacityArcMap;
kpeter@874
    81
    typedef typename Digraph::template NodeMap<Supply> SupplyNodeMap;
kpeter@874
    82
kpeter@874
    83
    typedef ResidualDigraph< const Digraph,
kpeter@874
    84
                             CapacityArcMap, CapacityArcMap > ResDigraph;
kpeter@874
    85
    typedef typename ResDigraph::Arc ResArc;
kpeter@874
    86
kpeter@874
    87
#if defined __GNUC__ && !defined __STRICT_ANSI__
kpeter@874
    88
    typedef long long int LCost;
kpeter@874
    89
#else
kpeter@874
    90
    typedef long int LCost;
kpeter@874
    91
#endif
kpeter@874
    92
    typedef typename Digraph::template ArcMap<LCost> LargeCostMap;
kpeter@874
    93
kpeter@874
    94
  public:
kpeter@874
    95
kpeter@874
    96
    /// The type of the flow map.
kpeter@874
    97
    typedef typename Digraph::template ArcMap<Capacity> FlowMap;
kpeter@874
    98
    /// The type of the potential map.
kpeter@874
    99
    typedef typename Digraph::template NodeMap<LCost> PotentialMap;
kpeter@874
   100
kpeter@874
   101
  private:
kpeter@874
   102
kpeter@874
   103
    /// \brief Map adaptor class for handling residual arc costs.
kpeter@874
   104
    ///
kpeter@874
   105
    /// Map adaptor class for handling residual arc costs.
kpeter@874
   106
    template <typename Map>
kpeter@874
   107
    class ResidualCostMap : public MapBase<ResArc, typename Map::Value>
kpeter@874
   108
    {
kpeter@874
   109
    private:
kpeter@874
   110
kpeter@874
   111
      const Map &_cost_map;
kpeter@874
   112
kpeter@874
   113
    public:
kpeter@874
   114
kpeter@874
   115
      ///\e
kpeter@874
   116
      ResidualCostMap(const Map &cost_map) :
kpeter@874
   117
        _cost_map(cost_map) {}
kpeter@874
   118
kpeter@874
   119
      ///\e
kpeter@874
   120
      inline typename Map::Value operator[](const ResArc &e) const {
kpeter@874
   121
        return ResDigraph::forward(e) ? _cost_map[e] : -_cost_map[e];
kpeter@874
   122
      }
kpeter@874
   123
kpeter@874
   124
    }; //class ResidualCostMap
kpeter@874
   125
kpeter@874
   126
    /// \brief Map adaptor class for handling reduced arc costs.
kpeter@874
   127
    ///
kpeter@874
   128
    /// Map adaptor class for handling reduced arc costs.
kpeter@874
   129
    class ReducedCostMap : public MapBase<Arc, LCost>
kpeter@874
   130
    {
kpeter@874
   131
    private:
kpeter@874
   132
kpeter@874
   133
      const Digraph &_gr;
kpeter@874
   134
      const LargeCostMap &_cost_map;
kpeter@874
   135
      const PotentialMap &_pot_map;
kpeter@874
   136
kpeter@874
   137
    public:
kpeter@874
   138
kpeter@874
   139
      ///\e
kpeter@874
   140
      ReducedCostMap( const Digraph &gr,
kpeter@874
   141
                      const LargeCostMap &cost_map,
kpeter@874
   142
                      const PotentialMap &pot_map ) :
kpeter@874
   143
        _gr(gr), _cost_map(cost_map), _pot_map(pot_map) {}
kpeter@874
   144
kpeter@874
   145
      ///\e
kpeter@874
   146
      inline LCost operator[](const Arc &e) const {
kpeter@874
   147
        return _cost_map[e] + _pot_map[_gr.source(e)]
kpeter@874
   148
                            - _pot_map[_gr.target(e)];
kpeter@874
   149
      }
kpeter@874
   150
kpeter@874
   151
    }; //class ReducedCostMap
kpeter@874
   152
kpeter@874
   153
  private:
kpeter@874
   154
kpeter@874
   155
    // The digraph the algorithm runs on
kpeter@874
   156
    const Digraph &_graph;
kpeter@874
   157
    // The original lower bound map
kpeter@874
   158
    const LowerMap *_lower;
kpeter@874
   159
    // The modified capacity map
kpeter@874
   160
    CapacityArcMap _capacity;
kpeter@874
   161
    // The original cost map
kpeter@874
   162
    const CostMap &_orig_cost;
kpeter@874
   163
    // The scaled cost map
kpeter@874
   164
    LargeCostMap _cost;
kpeter@874
   165
    // The modified supply map
kpeter@874
   166
    SupplyNodeMap _supply;
kpeter@874
   167
    bool _valid_supply;
kpeter@874
   168
kpeter@874
   169
    // Arc map of the current flow
kpeter@874
   170
    FlowMap *_flow;
kpeter@874
   171
    bool _local_flow;
kpeter@874
   172
    // Node map of the current potentials
kpeter@874
   173
    PotentialMap *_potential;
kpeter@874
   174
    bool _local_potential;
kpeter@874
   175
kpeter@874
   176
    // The residual cost map
kpeter@874
   177
    ResidualCostMap<LargeCostMap> _res_cost;
kpeter@874
   178
    // The residual digraph
kpeter@874
   179
    ResDigraph *_res_graph;
kpeter@874
   180
    // The reduced cost map
kpeter@874
   181
    ReducedCostMap *_red_cost;
kpeter@874
   182
    // The excess map
kpeter@874
   183
    SupplyNodeMap _excess;
kpeter@874
   184
    // The epsilon parameter used for cost scaling
kpeter@874
   185
    LCost _epsilon;
kpeter@874
   186
    // The scaling factor
kpeter@874
   187
    int _alpha;
kpeter@874
   188
kpeter@874
   189
  public:
kpeter@874
   190
kpeter@874
   191
    /// \brief General constructor (with lower bounds).
kpeter@874
   192
    ///
kpeter@874
   193
    /// General constructor (with lower bounds).
kpeter@874
   194
    ///
kpeter@874
   195
    /// \param digraph The digraph the algorithm runs on.
kpeter@874
   196
    /// \param lower The lower bounds of the arcs.
kpeter@874
   197
    /// \param capacity The capacities (upper bounds) of the arcs.
kpeter@874
   198
    /// \param cost The cost (length) values of the arcs.
kpeter@874
   199
    /// \param supply The supply values of the nodes (signed).
kpeter@874
   200
    CostScaling( const Digraph &digraph,
kpeter@874
   201
                 const LowerMap &lower,
kpeter@874
   202
                 const CapacityMap &capacity,
kpeter@874
   203
                 const CostMap &cost,
kpeter@874
   204
                 const SupplyMap &supply ) :
kpeter@874
   205
      _graph(digraph), _lower(&lower), _capacity(digraph), _orig_cost(cost),
kpeter@874
   206
      _cost(digraph), _supply(digraph), _flow(NULL), _local_flow(false),
kpeter@874
   207
      _potential(NULL), _local_potential(false), _res_cost(_cost),
kpeter@874
   208
      _res_graph(NULL), _red_cost(NULL), _excess(digraph, 0)
kpeter@874
   209
    {
kpeter@874
   210
      // Check the sum of supply values
kpeter@874
   211
      Supply sum = 0;
kpeter@874
   212
      for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
kpeter@874
   213
      _valid_supply = sum == 0;
kpeter@874
   214
      
kpeter@874
   215
      for (ArcIt e(_graph); e != INVALID; ++e) _capacity[e] = capacity[e];
kpeter@874
   216
      for (NodeIt n(_graph); n != INVALID; ++n) _supply[n] = supply[n];
kpeter@874
   217
kpeter@874
   218
      // Remove non-zero lower bounds
kpeter@874
   219
      for (ArcIt e(_graph); e != INVALID; ++e) {
kpeter@874
   220
        if (lower[e] != 0) {
kpeter@874
   221
          _capacity[e] -= lower[e];
kpeter@874
   222
          _supply[_graph.source(e)] -= lower[e];
kpeter@874
   223
          _supply[_graph.target(e)] += lower[e];
kpeter@874
   224
        }
kpeter@874
   225
      }
kpeter@874
   226
    }
kpeter@874
   227
/*
kpeter@874
   228
    /// \brief General constructor (without lower bounds).
kpeter@874
   229
    ///
kpeter@874
   230
    /// General constructor (without lower bounds).
kpeter@874
   231
    ///
kpeter@874
   232
    /// \param digraph The digraph the algorithm runs on.
kpeter@874
   233
    /// \param capacity The capacities (upper bounds) of the arcs.
kpeter@874
   234
    /// \param cost The cost (length) values of the arcs.
kpeter@874
   235
    /// \param supply The supply values of the nodes (signed).
kpeter@874
   236
    CostScaling( const Digraph &digraph,
kpeter@874
   237
                 const CapacityMap &capacity,
kpeter@874
   238
                 const CostMap &cost,
kpeter@874
   239
                 const SupplyMap &supply ) :
kpeter@874
   240
      _graph(digraph), _lower(NULL), _capacity(capacity), _orig_cost(cost),
kpeter@874
   241
      _cost(digraph), _supply(supply), _flow(NULL), _local_flow(false),
kpeter@874
   242
      _potential(NULL), _local_potential(false), _res_cost(_cost),
kpeter@874
   243
      _res_graph(NULL), _red_cost(NULL), _excess(digraph, 0)
kpeter@874
   244
    {
kpeter@874
   245
      // Check the sum of supply values
kpeter@874
   246
      Supply sum = 0;
kpeter@874
   247
      for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
kpeter@874
   248
      _valid_supply = sum == 0;
kpeter@874
   249
    }
kpeter@874
   250
kpeter@874
   251
    /// \brief Simple constructor (with lower bounds).
kpeter@874
   252
    ///
kpeter@874
   253
    /// Simple constructor (with lower bounds).
kpeter@874
   254
    ///
kpeter@874
   255
    /// \param digraph The digraph the algorithm runs on.
kpeter@874
   256
    /// \param lower The lower bounds of the arcs.
kpeter@874
   257
    /// \param capacity The capacities (upper bounds) of the arcs.
kpeter@874
   258
    /// \param cost The cost (length) values of the arcs.
kpeter@874
   259
    /// \param s The source node.
kpeter@874
   260
    /// \param t The target node.
kpeter@874
   261
    /// \param flow_value The required amount of flow from node \c s
kpeter@874
   262
    /// to node \c t (i.e. the supply of \c s and the demand of \c t).
kpeter@874
   263
    CostScaling( const Digraph &digraph,
kpeter@874
   264
                 const LowerMap &lower,
kpeter@874
   265
                 const CapacityMap &capacity,
kpeter@874
   266
                 const CostMap &cost,
kpeter@874
   267
                 Node s, Node t,
kpeter@874
   268
                 Supply flow_value ) :
kpeter@874
   269
      _graph(digraph), _lower(&lower), _capacity(capacity), _orig_cost(cost),
kpeter@874
   270
      _cost(digraph), _supply(digraph, 0), _flow(NULL), _local_flow(false),
kpeter@874
   271
      _potential(NULL), _local_potential(false), _res_cost(_cost),
kpeter@874
   272
      _res_graph(NULL), _red_cost(NULL), _excess(digraph, 0)
kpeter@874
   273
    {
kpeter@874
   274
      // Remove non-zero lower bounds
kpeter@874
   275
      _supply[s] =  flow_value;
kpeter@874
   276
      _supply[t] = -flow_value;
kpeter@874
   277
      for (ArcIt e(_graph); e != INVALID; ++e) {
kpeter@874
   278
        if (lower[e] != 0) {
kpeter@874
   279
          _capacity[e] -= lower[e];
kpeter@874
   280
          _supply[_graph.source(e)] -= lower[e];
kpeter@874
   281
          _supply[_graph.target(e)] += lower[e];
kpeter@874
   282
        }
kpeter@874
   283
      }
kpeter@874
   284
      _valid_supply = true;
kpeter@874
   285
    }
kpeter@874
   286
kpeter@874
   287
    /// \brief Simple constructor (without lower bounds).
kpeter@874
   288
    ///
kpeter@874
   289
    /// Simple constructor (without lower bounds).
kpeter@874
   290
    ///
kpeter@874
   291
    /// \param digraph The digraph the algorithm runs on.
kpeter@874
   292
    /// \param capacity The capacities (upper bounds) of the arcs.
kpeter@874
   293
    /// \param cost The cost (length) values of the arcs.
kpeter@874
   294
    /// \param s The source node.
kpeter@874
   295
    /// \param t The target node.
kpeter@874
   296
    /// \param flow_value The required amount of flow from node \c s
kpeter@874
   297
    /// to node \c t (i.e. the supply of \c s and the demand of \c t).
kpeter@874
   298
    CostScaling( const Digraph &digraph,
kpeter@874
   299
                 const CapacityMap &capacity,
kpeter@874
   300
                 const CostMap &cost,
kpeter@874
   301
                 Node s, Node t,
kpeter@874
   302
                 Supply flow_value ) :
kpeter@874
   303
      _graph(digraph), _lower(NULL), _capacity(capacity), _orig_cost(cost),
kpeter@874
   304
      _cost(digraph), _supply(digraph, 0), _flow(NULL), _local_flow(false),
kpeter@874
   305
      _potential(NULL), _local_potential(false), _res_cost(_cost),
kpeter@874
   306
      _res_graph(NULL), _red_cost(NULL), _excess(digraph, 0)
kpeter@874
   307
    {
kpeter@874
   308
      _supply[s] =  flow_value;
kpeter@874
   309
      _supply[t] = -flow_value;
kpeter@874
   310
      _valid_supply = true;
kpeter@874
   311
    }
kpeter@874
   312
*/
kpeter@874
   313
    /// Destructor.
kpeter@874
   314
    ~CostScaling() {
kpeter@874
   315
      if (_local_flow) delete _flow;
kpeter@874
   316
      if (_local_potential) delete _potential;
kpeter@874
   317
      delete _res_graph;
kpeter@874
   318
      delete _red_cost;
kpeter@874
   319
    }
kpeter@874
   320
kpeter@874
   321
    /// \brief Set the flow map.
kpeter@874
   322
    ///
kpeter@874
   323
    /// Set the flow map.
kpeter@874
   324
    ///
kpeter@874
   325
    /// \return \c (*this)
kpeter@874
   326
    CostScaling& flowMap(FlowMap &map) {
kpeter@874
   327
      if (_local_flow) {
kpeter@874
   328
        delete _flow;
kpeter@874
   329
        _local_flow = false;
kpeter@874
   330
      }
kpeter@874
   331
      _flow = &map;
kpeter@874
   332
      return *this;
kpeter@874
   333
    }
kpeter@874
   334
kpeter@874
   335
    /// \brief Set the potential map.
kpeter@874
   336
    ///
kpeter@874
   337
    /// Set the potential map.
kpeter@874
   338
    ///
kpeter@874
   339
    /// \return \c (*this)
kpeter@874
   340
    CostScaling& potentialMap(PotentialMap &map) {
kpeter@874
   341
      if (_local_potential) {
kpeter@874
   342
        delete _potential;
kpeter@874
   343
        _local_potential = false;
kpeter@874
   344
      }
kpeter@874
   345
      _potential = &map;
kpeter@874
   346
      return *this;
kpeter@874
   347
    }
kpeter@874
   348
kpeter@874
   349
    /// \name Execution control
kpeter@874
   350
kpeter@874
   351
    /// @{
kpeter@874
   352
kpeter@874
   353
    /// \brief Run the algorithm.
kpeter@874
   354
    ///
kpeter@874
   355
    /// Run the algorithm.
kpeter@874
   356
    ///
kpeter@874
   357
    /// \param partial_augment By default the algorithm performs
kpeter@874
   358
    /// partial augment and relabel operations in the cost scaling
kpeter@874
   359
    /// phases. Set this parameter to \c false for using local push and
kpeter@874
   360
    /// relabel operations instead.
kpeter@874
   361
    ///
kpeter@874
   362
    /// \return \c true if a feasible flow can be found.
kpeter@874
   363
    bool run(bool partial_augment = true) {
kpeter@874
   364
      if (partial_augment) {
kpeter@874
   365
        return init() && startPartialAugment();
kpeter@874
   366
      } else {
kpeter@874
   367
        return init() && startPushRelabel();
kpeter@874
   368
      }
kpeter@874
   369
    }
kpeter@874
   370
kpeter@874
   371
    /// @}
kpeter@874
   372
kpeter@874
   373
    /// \name Query Functions
kpeter@874
   374
    /// The result of the algorithm can be obtained using these
kpeter@874
   375
    /// functions.\n
kpeter@874
   376
    /// \ref lemon::CostScaling::run() "run()" must be called before
kpeter@874
   377
    /// using them.
kpeter@874
   378
kpeter@874
   379
    /// @{
kpeter@874
   380
kpeter@874
   381
    /// \brief Return a const reference to the arc map storing the
kpeter@874
   382
    /// found flow.
kpeter@874
   383
    ///
kpeter@874
   384
    /// Return a const reference to the arc map storing the found flow.
kpeter@874
   385
    ///
kpeter@874
   386
    /// \pre \ref run() must be called before using this function.
kpeter@874
   387
    const FlowMap& flowMap() const {
kpeter@874
   388
      return *_flow;
kpeter@874
   389
    }
kpeter@874
   390
kpeter@874
   391
    /// \brief Return a const reference to the node map storing the
kpeter@874
   392
    /// found potentials (the dual solution).
kpeter@874
   393
    ///
kpeter@874
   394
    /// Return a const reference to the node map storing the found
kpeter@874
   395
    /// potentials (the dual solution).
kpeter@874
   396
    ///
kpeter@874
   397
    /// \pre \ref run() must be called before using this function.
kpeter@874
   398
    const PotentialMap& potentialMap() const {
kpeter@874
   399
      return *_potential;
kpeter@874
   400
    }
kpeter@874
   401
kpeter@874
   402
    /// \brief Return the flow on the given arc.
kpeter@874
   403
    ///
kpeter@874
   404
    /// Return the flow on the given arc.
kpeter@874
   405
    ///
kpeter@874
   406
    /// \pre \ref run() must be called before using this function.
kpeter@874
   407
    Capacity flow(const Arc& arc) const {
kpeter@874
   408
      return (*_flow)[arc];
kpeter@874
   409
    }
kpeter@874
   410
kpeter@874
   411
    /// \brief Return the potential of the given node.
kpeter@874
   412
    ///
kpeter@874
   413
    /// Return the potential of the given node.
kpeter@874
   414
    ///
kpeter@874
   415
    /// \pre \ref run() must be called before using this function.
kpeter@874
   416
    Cost potential(const Node& node) const {
kpeter@874
   417
      return (*_potential)[node];
kpeter@874
   418
    }
kpeter@874
   419
kpeter@874
   420
    /// \brief Return the total cost of the found flow.
kpeter@874
   421
    ///
kpeter@874
   422
    /// Return the total cost of the found flow. The complexity of the
kpeter@874
   423
    /// function is \f$ O(e) \f$.
kpeter@874
   424
    ///
kpeter@874
   425
    /// \pre \ref run() must be called before using this function.
kpeter@874
   426
    Cost totalCost() const {
kpeter@874
   427
      Cost c = 0;
kpeter@874
   428
      for (ArcIt e(_graph); e != INVALID; ++e)
kpeter@874
   429
        c += (*_flow)[e] * _orig_cost[e];
kpeter@874
   430
      return c;
kpeter@874
   431
    }
kpeter@874
   432
kpeter@874
   433
    /// @}
kpeter@874
   434
kpeter@874
   435
  private:
kpeter@874
   436
kpeter@874
   437
    /// Initialize the algorithm.
kpeter@874
   438
    bool init() {
kpeter@874
   439
      if (!_valid_supply) return false;
kpeter@874
   440
      // The scaling factor
kpeter@874
   441
      _alpha = 8;
kpeter@874
   442
kpeter@874
   443
      // Initialize flow and potential maps
kpeter@874
   444
      if (!_flow) {
kpeter@874
   445
        _flow = new FlowMap(_graph);
kpeter@874
   446
        _local_flow = true;
kpeter@874
   447
      }
kpeter@874
   448
      if (!_potential) {
kpeter@874
   449
        _potential = new PotentialMap(_graph);
kpeter@874
   450
        _local_potential = true;
kpeter@874
   451
      }
kpeter@874
   452
kpeter@874
   453
      _red_cost = new ReducedCostMap(_graph, _cost, *_potential);
kpeter@874
   454
      _res_graph = new ResDigraph(_graph, _capacity, *_flow);
kpeter@874
   455
kpeter@874
   456
      // Initialize the scaled cost map and the epsilon parameter
kpeter@874
   457
      Cost max_cost = 0;
kpeter@874
   458
      int node_num = countNodes(_graph);
kpeter@874
   459
      for (ArcIt e(_graph); e != INVALID; ++e) {
kpeter@874
   460
        _cost[e] = LCost(_orig_cost[e]) * node_num * _alpha;
kpeter@874
   461
        if (_orig_cost[e] > max_cost) max_cost = _orig_cost[e];
kpeter@874
   462
      }
kpeter@874
   463
      _epsilon = max_cost * node_num;
kpeter@874
   464
kpeter@874
   465
      // Find a feasible flow using Circulation
kpeter@874
   466
      Circulation< Digraph, ConstMap<Arc, Capacity>, CapacityArcMap,
kpeter@874
   467
                   SupplyMap >
kpeter@874
   468
        circulation( _graph, constMap<Arc>(Capacity(0)), _capacity,
kpeter@874
   469
                     _supply );
kpeter@874
   470
      return circulation.flowMap(*_flow).run();
kpeter@874
   471
    }
kpeter@874
   472
kpeter@874
   473
    /// Execute the algorithm performing partial augmentation and
kpeter@874
   474
    /// relabel operations.
kpeter@874
   475
    bool startPartialAugment() {
kpeter@874
   476
      // Paramters for heuristics
kpeter@874
   477
//      const int BF_HEURISTIC_EPSILON_BOUND = 1000;
kpeter@874
   478
//      const int BF_HEURISTIC_BOUND_FACTOR  = 3;
kpeter@874
   479
      // Maximum augment path length
kpeter@874
   480
      const int MAX_PATH_LENGTH = 4;
kpeter@874
   481
kpeter@874
   482
      // Variables
kpeter@874
   483
      typename Digraph::template NodeMap<Arc> pred_arc(_graph);
kpeter@874
   484
      typename Digraph::template NodeMap<bool> forward(_graph);
kpeter@874
   485
      typename Digraph::template NodeMap<OutArcIt> next_out(_graph);
kpeter@874
   486
      typename Digraph::template NodeMap<InArcIt> next_in(_graph);
kpeter@874
   487
      typename Digraph::template NodeMap<bool> next_dir(_graph);
kpeter@874
   488
      std::deque<Node> active_nodes;
kpeter@874
   489
      std::vector<Node> path_nodes;
kpeter@874
   490
kpeter@874
   491
//      int node_num = countNodes(_graph);
kpeter@874
   492
      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
kpeter@874
   493
                                        1 : _epsilon / _alpha )
kpeter@874
   494
      {
kpeter@874
   495
/*
kpeter@874
   496
        // "Early Termination" heuristic: use Bellman-Ford algorithm
kpeter@874
   497
        // to check if the current flow is optimal
kpeter@874
   498
        if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
kpeter@874
   499
          typedef ShiftMap< ResidualCostMap<LargeCostMap> > ShiftCostMap;
kpeter@874
   500
          ShiftCostMap shift_cost(_res_cost, 1);
kpeter@874
   501
          BellmanFord<ResDigraph, ShiftCostMap> bf(*_res_graph, shift_cost);
kpeter@874
   502
          bf.init(0);
kpeter@874
   503
          bool done = false;
kpeter@874
   504
          int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(node_num));
kpeter@874
   505
          for (int i = 0; i < K && !done; ++i)
kpeter@874
   506
            done = bf.processNextWeakRound();
kpeter@874
   507
          if (done) break;
kpeter@874
   508
        }
kpeter@874
   509
*/
kpeter@874
   510
        // Saturate arcs not satisfying the optimality condition
kpeter@874
   511
        Capacity delta;
kpeter@874
   512
        for (ArcIt e(_graph); e != INVALID; ++e) {
kpeter@874
   513
          if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
kpeter@874
   514
            delta = _capacity[e] - (*_flow)[e];
kpeter@874
   515
            _excess[_graph.source(e)] -= delta;
kpeter@874
   516
            _excess[_graph.target(e)] += delta;
kpeter@874
   517
            (*_flow)[e] = _capacity[e];
kpeter@874
   518
          }
kpeter@874
   519
          if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
kpeter@874
   520
            _excess[_graph.target(e)] -= (*_flow)[e];
kpeter@874
   521
            _excess[_graph.source(e)] += (*_flow)[e];
kpeter@874
   522
            (*_flow)[e] = 0;
kpeter@874
   523
          }
kpeter@874
   524
        }
kpeter@874
   525
kpeter@874
   526
        // Find active nodes (i.e. nodes with positive excess)
kpeter@874
   527
        for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@874
   528
          if (_excess[n] > 0) active_nodes.push_back(n);
kpeter@874
   529
        }
kpeter@874
   530
kpeter@874
   531
        // Initialize the next arc maps
kpeter@874
   532
        for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@874
   533
          next_out[n] = OutArcIt(_graph, n);
kpeter@874
   534
          next_in[n] = InArcIt(_graph, n);
kpeter@874
   535
          next_dir[n] = true;
kpeter@874
   536
        }
kpeter@874
   537
kpeter@874
   538
        // Perform partial augment and relabel operations
kpeter@874
   539
        while (active_nodes.size() > 0) {
kpeter@874
   540
          // Select an active node (FIFO selection)
kpeter@874
   541
          if (_excess[active_nodes[0]] <= 0) {
kpeter@874
   542
            active_nodes.pop_front();
kpeter@874
   543
            continue;
kpeter@874
   544
          }
kpeter@874
   545
          Node start = active_nodes[0];
kpeter@874
   546
          path_nodes.clear();
kpeter@874
   547
          path_nodes.push_back(start);
kpeter@874
   548
kpeter@874
   549
          // Find an augmenting path from the start node
kpeter@874
   550
          Node u, tip = start;
kpeter@874
   551
          LCost min_red_cost;
kpeter@874
   552
          while ( _excess[tip] >= 0 &&
kpeter@874
   553
                  int(path_nodes.size()) <= MAX_PATH_LENGTH )
kpeter@874
   554
          {
kpeter@874
   555
            if (next_dir[tip]) {
kpeter@874
   556
              for (OutArcIt e = next_out[tip]; e != INVALID; ++e) {
kpeter@874
   557
                if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
kpeter@874
   558
                  u = _graph.target(e);
kpeter@874
   559
                  pred_arc[u] = e;
kpeter@874
   560
                  forward[u] = true;
kpeter@874
   561
                  next_out[tip] = e;
kpeter@874
   562
                  tip = u;
kpeter@874
   563
                  path_nodes.push_back(tip);
kpeter@874
   564
                  goto next_step;
kpeter@874
   565
                }
kpeter@874
   566
              }
kpeter@874
   567
              next_dir[tip] = false;
kpeter@874
   568
            }
kpeter@874
   569
            for (InArcIt e = next_in[tip]; e != INVALID; ++e) {
kpeter@874
   570
              if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
kpeter@874
   571
                u = _graph.source(e);
kpeter@874
   572
                pred_arc[u] = e;
kpeter@874
   573
                forward[u] = false;
kpeter@874
   574
                next_in[tip] = e;
kpeter@874
   575
                tip = u;
kpeter@874
   576
                path_nodes.push_back(tip);
kpeter@874
   577
                goto next_step;
kpeter@874
   578
              }
kpeter@874
   579
            }
kpeter@874
   580
kpeter@874
   581
            // Relabel tip node
kpeter@874
   582
            min_red_cost = std::numeric_limits<LCost>::max() / 2;
kpeter@874
   583
            for (OutArcIt oe(_graph, tip); oe != INVALID; ++oe) {
kpeter@874
   584
              if ( _capacity[oe] - (*_flow)[oe] > 0 &&
kpeter@874
   585
                   (*_red_cost)[oe] < min_red_cost )
kpeter@874
   586
                min_red_cost = (*_red_cost)[oe];
kpeter@874
   587
            }
kpeter@874
   588
            for (InArcIt ie(_graph, tip); ie != INVALID; ++ie) {
kpeter@874
   589
              if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < min_red_cost)
kpeter@874
   590
                min_red_cost = -(*_red_cost)[ie];
kpeter@874
   591
            }
kpeter@874
   592
            (*_potential)[tip] -= min_red_cost + _epsilon;
kpeter@874
   593
kpeter@874
   594
            // Reset the next arc maps
kpeter@874
   595
            next_out[tip] = OutArcIt(_graph, tip);
kpeter@874
   596
            next_in[tip] = InArcIt(_graph, tip);
kpeter@874
   597
            next_dir[tip] = true;
kpeter@874
   598
kpeter@874
   599
            // Step back
kpeter@874
   600
            if (tip != start) {
kpeter@874
   601
              path_nodes.pop_back();
kpeter@874
   602
              tip = path_nodes[path_nodes.size()-1];
kpeter@874
   603
            }
kpeter@874
   604
kpeter@874
   605
          next_step:
kpeter@874
   606
            continue;
kpeter@874
   607
          }
kpeter@874
   608
kpeter@874
   609
          // Augment along the found path (as much flow as possible)
kpeter@874
   610
          Capacity delta;
kpeter@874
   611
          for (int i = 1; i < int(path_nodes.size()); ++i) {
kpeter@874
   612
            u = path_nodes[i];
kpeter@874
   613
            delta = forward[u] ?
kpeter@874
   614
              _capacity[pred_arc[u]] - (*_flow)[pred_arc[u]] :
kpeter@874
   615
              (*_flow)[pred_arc[u]];
kpeter@874
   616
            delta = std::min(delta, _excess[path_nodes[i-1]]);
kpeter@874
   617
            (*_flow)[pred_arc[u]] += forward[u] ? delta : -delta;
kpeter@874
   618
            _excess[path_nodes[i-1]] -= delta;
kpeter@874
   619
            _excess[u] += delta;
kpeter@874
   620
            if (_excess[u] > 0 && _excess[u] <= delta) active_nodes.push_back(u);
kpeter@874
   621
          }
kpeter@874
   622
        }
kpeter@874
   623
      }
kpeter@874
   624
kpeter@874
   625
      // Compute node potentials for the original costs
kpeter@874
   626
      ResidualCostMap<CostMap> res_cost(_orig_cost);
kpeter@874
   627
      BellmanFord< ResDigraph, ResidualCostMap<CostMap> >
kpeter@874
   628
        bf(*_res_graph, res_cost);
kpeter@874
   629
      bf.init(0); bf.start();
kpeter@874
   630
      for (NodeIt n(_graph); n != INVALID; ++n)
kpeter@874
   631
        (*_potential)[n] = bf.dist(n);
kpeter@874
   632
kpeter@874
   633
      // Handle non-zero lower bounds
kpeter@874
   634
      if (_lower) {
kpeter@874
   635
        for (ArcIt e(_graph); e != INVALID; ++e)
kpeter@874
   636
          (*_flow)[e] += (*_lower)[e];
kpeter@874
   637
      }
kpeter@874
   638
      return true;
kpeter@874
   639
    }
kpeter@874
   640
kpeter@874
   641
    /// Execute the algorithm performing push and relabel operations.
kpeter@874
   642
    bool startPushRelabel() {
kpeter@874
   643
      // Paramters for heuristics
kpeter@874
   644
//      const int BF_HEURISTIC_EPSILON_BOUND = 1000;
kpeter@874
   645
//      const int BF_HEURISTIC_BOUND_FACTOR  = 3;
kpeter@874
   646
kpeter@874
   647
      typename Digraph::template NodeMap<bool> hyper(_graph, false);
kpeter@874
   648
      typename Digraph::template NodeMap<Arc> pred_arc(_graph);
kpeter@874
   649
      typename Digraph::template NodeMap<bool> forward(_graph);
kpeter@874
   650
      typename Digraph::template NodeMap<OutArcIt> next_out(_graph);
kpeter@874
   651
      typename Digraph::template NodeMap<InArcIt> next_in(_graph);
kpeter@874
   652
      typename Digraph::template NodeMap<bool> next_dir(_graph);
kpeter@874
   653
      std::deque<Node> active_nodes;
kpeter@874
   654
kpeter@874
   655
//      int node_num = countNodes(_graph);
kpeter@874
   656
      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
kpeter@874
   657
                                        1 : _epsilon / _alpha )
kpeter@874
   658
      {
kpeter@874
   659
/*
kpeter@874
   660
        // "Early Termination" heuristic: use Bellman-Ford algorithm
kpeter@874
   661
        // to check if the current flow is optimal
kpeter@874
   662
        if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
kpeter@874
   663
          typedef ShiftMap< ResidualCostMap<LargeCostMap> > ShiftCostMap;
kpeter@874
   664
          ShiftCostMap shift_cost(_res_cost, 1);
kpeter@874
   665
          BellmanFord<ResDigraph, ShiftCostMap> bf(*_res_graph, shift_cost);
kpeter@874
   666
          bf.init(0);
kpeter@874
   667
          bool done = false;
kpeter@874
   668
          int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(node_num));
kpeter@874
   669
          for (int i = 0; i < K && !done; ++i)
kpeter@874
   670
            done = bf.processNextWeakRound();
kpeter@874
   671
          if (done) break;
kpeter@874
   672
        }
kpeter@874
   673
*/
kpeter@874
   674
kpeter@874
   675
        // Saturate arcs not satisfying the optimality condition
kpeter@874
   676
        Capacity delta;
kpeter@874
   677
        for (ArcIt e(_graph); e != INVALID; ++e) {
kpeter@874
   678
          if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
kpeter@874
   679
            delta = _capacity[e] - (*_flow)[e];
kpeter@874
   680
            _excess[_graph.source(e)] -= delta;
kpeter@874
   681
            _excess[_graph.target(e)] += delta;
kpeter@874
   682
            (*_flow)[e] = _capacity[e];
kpeter@874
   683
          }
kpeter@874
   684
          if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
kpeter@874
   685
            _excess[_graph.target(e)] -= (*_flow)[e];
kpeter@874
   686
            _excess[_graph.source(e)] += (*_flow)[e];
kpeter@874
   687
            (*_flow)[e] = 0;
kpeter@874
   688
          }
kpeter@874
   689
        }
kpeter@874
   690
kpeter@874
   691
        // Find active nodes (i.e. nodes with positive excess)
kpeter@874
   692
        for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@874
   693
          if (_excess[n] > 0) active_nodes.push_back(n);
kpeter@874
   694
        }
kpeter@874
   695
kpeter@874
   696
        // Initialize the next arc maps
kpeter@874
   697
        for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@874
   698
          next_out[n] = OutArcIt(_graph, n);
kpeter@874
   699
          next_in[n] = InArcIt(_graph, n);
kpeter@874
   700
          next_dir[n] = true;
kpeter@874
   701
        }
kpeter@874
   702
kpeter@874
   703
        // Perform push and relabel operations
kpeter@874
   704
        while (active_nodes.size() > 0) {
kpeter@874
   705
          // Select an active node (FIFO selection)
kpeter@874
   706
          Node n = active_nodes[0], t;
kpeter@874
   707
          bool relabel_enabled = true;
kpeter@874
   708
kpeter@874
   709
          // Perform push operations if there are admissible arcs
kpeter@874
   710
          if (_excess[n] > 0 && next_dir[n]) {
kpeter@874
   711
            OutArcIt e = next_out[n];
kpeter@874
   712
            for ( ; e != INVALID; ++e) {
kpeter@874
   713
              if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
kpeter@874
   714
                delta = std::min(_capacity[e] - (*_flow)[e], _excess[n]);
kpeter@874
   715
                t = _graph.target(e);
kpeter@874
   716
kpeter@874
   717
                // Push-look-ahead heuristic
kpeter@874
   718
                Capacity ahead = -_excess[t];
kpeter@874
   719
                for (OutArcIt oe(_graph, t); oe != INVALID; ++oe) {
kpeter@874
   720
                  if (_capacity[oe] - (*_flow)[oe] > 0 && (*_red_cost)[oe] < 0)
kpeter@874
   721
                    ahead += _capacity[oe] - (*_flow)[oe];
kpeter@874
   722
                }
kpeter@874
   723
                for (InArcIt ie(_graph, t); ie != INVALID; ++ie) {
kpeter@874
   724
                  if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
kpeter@874
   725
                    ahead += (*_flow)[ie];
kpeter@874
   726
                }
kpeter@874
   727
                if (ahead < 0) ahead = 0;
kpeter@874
   728
kpeter@874
   729
                // Push flow along the arc
kpeter@874
   730
                if (ahead < delta) {
kpeter@874
   731
                  (*_flow)[e] += ahead;
kpeter@874
   732
                  _excess[n] -= ahead;
kpeter@874
   733
                  _excess[t] += ahead;
kpeter@874
   734
                  active_nodes.push_front(t);
kpeter@874
   735
                  hyper[t] = true;
kpeter@874
   736
                  relabel_enabled = false;
kpeter@874
   737
                  break;
kpeter@874
   738
                } else {
kpeter@874
   739
                  (*_flow)[e] += delta;
kpeter@874
   740
                  _excess[n] -= delta;
kpeter@874
   741
                  _excess[t] += delta;
kpeter@874
   742
                  if (_excess[t] > 0 && _excess[t] <= delta)
kpeter@874
   743
                    active_nodes.push_back(t);
kpeter@874
   744
                }
kpeter@874
   745
kpeter@874
   746
                if (_excess[n] == 0) break;
kpeter@874
   747
              }
kpeter@874
   748
            }
kpeter@874
   749
            if (e != INVALID) {
kpeter@874
   750
              next_out[n] = e;
kpeter@874
   751
            } else {
kpeter@874
   752
              next_dir[n] = false;
kpeter@874
   753
            }
kpeter@874
   754
          }
kpeter@874
   755
kpeter@874
   756
          if (_excess[n] > 0 && !next_dir[n]) {
kpeter@874
   757
            InArcIt e = next_in[n];
kpeter@874
   758
            for ( ; e != INVALID; ++e) {
kpeter@874
   759
              if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
kpeter@874
   760
                delta = std::min((*_flow)[e], _excess[n]);
kpeter@874
   761
                t = _graph.source(e);
kpeter@874
   762
kpeter@874
   763
                // Push-look-ahead heuristic
kpeter@874
   764
                Capacity ahead = -_excess[t];
kpeter@874
   765
                for (OutArcIt oe(_graph, t); oe != INVALID; ++oe) {
kpeter@874
   766
                  if (_capacity[oe] - (*_flow)[oe] > 0 && (*_red_cost)[oe] < 0)
kpeter@874
   767
                    ahead += _capacity[oe] - (*_flow)[oe];
kpeter@874
   768
                }
kpeter@874
   769
                for (InArcIt ie(_graph, t); ie != INVALID; ++ie) {
kpeter@874
   770
                  if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
kpeter@874
   771
                    ahead += (*_flow)[ie];
kpeter@874
   772
                }
kpeter@874
   773
                if (ahead < 0) ahead = 0;
kpeter@874
   774
kpeter@874
   775
                // Push flow along the arc
kpeter@874
   776
                if (ahead < delta) {
kpeter@874
   777
                  (*_flow)[e] -= ahead;
kpeter@874
   778
                  _excess[n] -= ahead;
kpeter@874
   779
                  _excess[t] += ahead;
kpeter@874
   780
                  active_nodes.push_front(t);
kpeter@874
   781
                  hyper[t] = true;
kpeter@874
   782
                  relabel_enabled = false;
kpeter@874
   783
                  break;
kpeter@874
   784
                } else {
kpeter@874
   785
                  (*_flow)[e] -= delta;
kpeter@874
   786
                  _excess[n] -= delta;
kpeter@874
   787
                  _excess[t] += delta;
kpeter@874
   788
                  if (_excess[t] > 0 && _excess[t] <= delta)
kpeter@874
   789
                    active_nodes.push_back(t);
kpeter@874
   790
                }
kpeter@874
   791
kpeter@874
   792
                if (_excess[n] == 0) break;
kpeter@874
   793
              }
kpeter@874
   794
            }
kpeter@874
   795
            next_in[n] = e;
kpeter@874
   796
          }
kpeter@874
   797
kpeter@874
   798
          // Relabel the node if it is still active (or hyper)
kpeter@874
   799
          if (relabel_enabled && (_excess[n] > 0 || hyper[n])) {
kpeter@874
   800
            LCost min_red_cost = std::numeric_limits<LCost>::max() / 2;
kpeter@874
   801
            for (OutArcIt oe(_graph, n); oe != INVALID; ++oe) {
kpeter@874
   802
              if ( _capacity[oe] - (*_flow)[oe] > 0 &&
kpeter@874
   803
                   (*_red_cost)[oe] < min_red_cost )
kpeter@874
   804
                min_red_cost = (*_red_cost)[oe];
kpeter@874
   805
            }
kpeter@874
   806
            for (InArcIt ie(_graph, n); ie != INVALID; ++ie) {
kpeter@874
   807
              if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < min_red_cost)
kpeter@874
   808
                min_red_cost = -(*_red_cost)[ie];
kpeter@874
   809
            }
kpeter@874
   810
            (*_potential)[n] -= min_red_cost + _epsilon;
kpeter@874
   811
            hyper[n] = false;
kpeter@874
   812
kpeter@874
   813
            // Reset the next arc maps
kpeter@874
   814
            next_out[n] = OutArcIt(_graph, n);
kpeter@874
   815
            next_in[n] = InArcIt(_graph, n);
kpeter@874
   816
            next_dir[n] = true;
kpeter@874
   817
          }
kpeter@874
   818
kpeter@874
   819
          // Remove nodes that are not active nor hyper
kpeter@874
   820
          while ( active_nodes.size() > 0 &&
kpeter@874
   821
                  _excess[active_nodes[0]] <= 0 &&
kpeter@874
   822
                  !hyper[active_nodes[0]] ) {
kpeter@874
   823
            active_nodes.pop_front();
kpeter@874
   824
          }
kpeter@874
   825
        }
kpeter@874
   826
      }
kpeter@874
   827
kpeter@874
   828
      // Compute node potentials for the original costs
kpeter@874
   829
      ResidualCostMap<CostMap> res_cost(_orig_cost);
kpeter@874
   830
      BellmanFord< ResDigraph, ResidualCostMap<CostMap> >
kpeter@874
   831
        bf(*_res_graph, res_cost);
kpeter@874
   832
      bf.init(0); bf.start();
kpeter@874
   833
      for (NodeIt n(_graph); n != INVALID; ++n)
kpeter@874
   834
        (*_potential)[n] = bf.dist(n);
kpeter@874
   835
kpeter@874
   836
      // Handle non-zero lower bounds
kpeter@874
   837
      if (_lower) {
kpeter@874
   838
        for (ArcIt e(_graph); e != INVALID; ++e)
kpeter@874
   839
          (*_flow)[e] += (*_lower)[e];
kpeter@874
   840
      }
kpeter@874
   841
      return true;
kpeter@874
   842
    }
kpeter@874
   843
kpeter@874
   844
  }; //class CostScaling
kpeter@874
   845
kpeter@874
   846
  ///@}
kpeter@874
   847
kpeter@874
   848
} //namespace lemon
kpeter@874
   849
kpeter@874
   850
#endif //LEMON_COST_SCALING_H