lemon/cancel_and_tighten.h
author kpeter
Mon, 01 Jun 2009 15:37:51 +0000
changeset 2636 1f99c95ddd2d
permissions -rw-r--r--
Add the Cancel and Tighten min cost flow algorithm
kpeter@2636
     1
/* -*- C++ -*-
kpeter@2636
     2
 *
kpeter@2636
     3
 * This file is a part of LEMON, a generic C++ optimization library
kpeter@2636
     4
 *
kpeter@2636
     5
 * Copyright (C) 2003-2008
kpeter@2636
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
kpeter@2636
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
kpeter@2636
     8
 *
kpeter@2636
     9
 * Permission to use, modify and distribute this software is granted
kpeter@2636
    10
 * provided that this copyright notice appears in all copies. For
kpeter@2636
    11
 * precise terms see the accompanying LICENSE file.
kpeter@2636
    12
 *
kpeter@2636
    13
 * This software is provided "AS IS" with no warranty of any kind,
kpeter@2636
    14
 * express or implied, and with no claim as to its suitability for any
kpeter@2636
    15
 * purpose.
kpeter@2636
    16
 *
kpeter@2636
    17
 */
kpeter@2636
    18
kpeter@2636
    19
#ifndef LEMON_CANCEL_AND_TIGHTEN_H
kpeter@2636
    20
#define LEMON_CANCEL_AND_TIGHTEN_H
kpeter@2636
    21
kpeter@2636
    22
/// \ingroup min_cost_flow
kpeter@2636
    23
///
kpeter@2636
    24
/// \file
kpeter@2636
    25
/// \brief Cancel and Tighten algorithm for finding a minimum cost flow.
kpeter@2636
    26
kpeter@2636
    27
#include <vector>
kpeter@2636
    28
kpeter@2636
    29
#include <lemon/circulation.h>
kpeter@2636
    30
#include <lemon/bellman_ford.h>
kpeter@2636
    31
#include <lemon/min_mean_cycle.h>
kpeter@2636
    32
#include <lemon/graph_adaptor.h>
kpeter@2636
    33
#include <lemon/tolerance.h>
kpeter@2636
    34
#include <lemon/math.h>
kpeter@2636
    35
kpeter@2636
    36
#include <lemon/static_graph.h>
kpeter@2636
    37
kpeter@2636
    38
namespace lemon {
kpeter@2636
    39
kpeter@2636
    40
  /// \addtogroup min_cost_flow
kpeter@2636
    41
  /// @{
kpeter@2636
    42
kpeter@2636
    43
  /// \brief Implementation of the Cancel and Tighten algorithm for
kpeter@2636
    44
  /// finding a minimum cost flow.
kpeter@2636
    45
  ///
kpeter@2636
    46
  /// \ref CancelAndTighten implements the Cancel and Tighten algorithm for
kpeter@2636
    47
  /// finding a minimum cost flow.
kpeter@2636
    48
  ///
kpeter@2636
    49
  /// \tparam Graph The directed graph type the algorithm runs on.
kpeter@2636
    50
  /// \tparam LowerMap The type of the lower bound map.
kpeter@2636
    51
  /// \tparam CapacityMap The type of the capacity (upper bound) map.
kpeter@2636
    52
  /// \tparam CostMap The type of the cost (length) map.
kpeter@2636
    53
  /// \tparam SupplyMap The type of the supply map.
kpeter@2636
    54
  ///
kpeter@2636
    55
  /// \warning
kpeter@2636
    56
  /// - Edge capacities and costs should be \e non-negative \e integers.
kpeter@2636
    57
  /// - Supply values should be \e signed \e integers.
kpeter@2636
    58
  /// - The value types of the maps should be convertible to each other.
kpeter@2636
    59
  /// - \c CostMap::Value must be signed type.
kpeter@2636
    60
  ///
kpeter@2636
    61
  /// \author Peter Kovacs
kpeter@2636
    62
  template < typename Graph,
kpeter@2636
    63
             typename LowerMap = typename Graph::template EdgeMap<int>,
kpeter@2636
    64
             typename CapacityMap = typename Graph::template EdgeMap<int>,
kpeter@2636
    65
             typename CostMap = typename Graph::template EdgeMap<int>,
kpeter@2636
    66
             typename SupplyMap = typename Graph::template NodeMap<int> >
kpeter@2636
    67
  class CancelAndTighten
kpeter@2636
    68
  {
kpeter@2636
    69
    GRAPH_TYPEDEFS(typename Graph);
kpeter@2636
    70
kpeter@2636
    71
    typedef typename CapacityMap::Value Capacity;
kpeter@2636
    72
    typedef typename CostMap::Value Cost;
kpeter@2636
    73
    typedef typename SupplyMap::Value Supply;
kpeter@2636
    74
    typedef typename Graph::template EdgeMap<Capacity> CapacityEdgeMap;
kpeter@2636
    75
    typedef typename Graph::template NodeMap<Supply> SupplyNodeMap;
kpeter@2636
    76
kpeter@2636
    77
    typedef ResGraphAdaptor< const Graph, Capacity,
kpeter@2636
    78
                             CapacityEdgeMap, CapacityEdgeMap > ResGraph;
kpeter@2636
    79
kpeter@2636
    80
  public:
kpeter@2636
    81
kpeter@2636
    82
    /// The type of the flow map.
kpeter@2636
    83
    typedef typename Graph::template EdgeMap<Capacity> FlowMap;
kpeter@2636
    84
    /// The type of the potential map.
kpeter@2636
    85
    typedef typename Graph::template NodeMap<Cost> PotentialMap;
kpeter@2636
    86
kpeter@2636
    87
  private:
kpeter@2636
    88
kpeter@2636
    89
    /// \brief Map adaptor class for handling residual edge costs.
kpeter@2636
    90
    ///
kpeter@2636
    91
    /// Map adaptor class for handling residual edge costs.
kpeter@2636
    92
    class ResidualCostMap : public MapBase<typename ResGraph::Edge, Cost>
kpeter@2636
    93
    {
kpeter@2636
    94
      typedef typename ResGraph::Edge Edge;
kpeter@2636
    95
      
kpeter@2636
    96
    private:
kpeter@2636
    97
kpeter@2636
    98
      const CostMap &_cost_map;
kpeter@2636
    99
kpeter@2636
   100
    public:
kpeter@2636
   101
kpeter@2636
   102
      ///\e
kpeter@2636
   103
      ResidualCostMap(const CostMap &cost_map) : _cost_map(cost_map) {}
kpeter@2636
   104
kpeter@2636
   105
      ///\e
kpeter@2636
   106
      Cost operator[](const Edge &e) const {
kpeter@2636
   107
        return ResGraph::forward(e) ? _cost_map[e] : -_cost_map[e];
kpeter@2636
   108
      }
kpeter@2636
   109
kpeter@2636
   110
    }; //class ResidualCostMap
kpeter@2636
   111
kpeter@2636
   112
    /// \brief Map adaptor class for handling reduced edge costs.
kpeter@2636
   113
    ///
kpeter@2636
   114
    /// Map adaptor class for handling reduced edge costs.
kpeter@2636
   115
    class ReducedCostMap : public MapBase<Edge, Cost>
kpeter@2636
   116
    {
kpeter@2636
   117
    private:
kpeter@2636
   118
kpeter@2636
   119
      const Graph &_gr;
kpeter@2636
   120
      const CostMap &_cost_map;
kpeter@2636
   121
      const PotentialMap &_pot_map;
kpeter@2636
   122
kpeter@2636
   123
    public:
kpeter@2636
   124
kpeter@2636
   125
      ///\e
kpeter@2636
   126
      ReducedCostMap( const Graph &gr,
kpeter@2636
   127
                      const CostMap &cost_map,
kpeter@2636
   128
                      const PotentialMap &pot_map ) :
kpeter@2636
   129
        _gr(gr), _cost_map(cost_map), _pot_map(pot_map) {}
kpeter@2636
   130
kpeter@2636
   131
      ///\e
kpeter@2636
   132
      inline Cost operator[](const Edge &e) const {
kpeter@2636
   133
        return _cost_map[e] + _pot_map[_gr.source(e)]
kpeter@2636
   134
                            - _pot_map[_gr.target(e)];
kpeter@2636
   135
      }
kpeter@2636
   136
kpeter@2636
   137
    }; //class ReducedCostMap
kpeter@2636
   138
kpeter@2636
   139
    struct BFOperationTraits {
kpeter@2636
   140
      static double zero() { return 0; }
kpeter@2636
   141
kpeter@2636
   142
      static double infinity() {
kpeter@2636
   143
        return std::numeric_limits<double>::infinity();
kpeter@2636
   144
      }
kpeter@2636
   145
kpeter@2636
   146
      static double plus(const double& left, const double& right) {
kpeter@2636
   147
        return left + right;
kpeter@2636
   148
      }
kpeter@2636
   149
kpeter@2636
   150
      static bool less(const double& left, const double& right) {
kpeter@2636
   151
        return left + 1e-6 < right;
kpeter@2636
   152
      }
kpeter@2636
   153
    }; // class BFOperationTraits
kpeter@2636
   154
kpeter@2636
   155
  private:
kpeter@2636
   156
kpeter@2636
   157
    // The directed graph the algorithm runs on
kpeter@2636
   158
    const Graph &_graph;
kpeter@2636
   159
    // The original lower bound map
kpeter@2636
   160
    const LowerMap *_lower;
kpeter@2636
   161
    // The modified capacity map
kpeter@2636
   162
    CapacityEdgeMap _capacity;
kpeter@2636
   163
    // The original cost map
kpeter@2636
   164
    const CostMap &_cost;
kpeter@2636
   165
    // The modified supply map
kpeter@2636
   166
    SupplyNodeMap _supply;
kpeter@2636
   167
    bool _valid_supply;
kpeter@2636
   168
kpeter@2636
   169
    // Edge map of the current flow
kpeter@2636
   170
    FlowMap *_flow;
kpeter@2636
   171
    bool _local_flow;
kpeter@2636
   172
    // Node map of the current potentials
kpeter@2636
   173
    PotentialMap *_potential;
kpeter@2636
   174
    bool _local_potential;
kpeter@2636
   175
kpeter@2636
   176
    // The residual graph
kpeter@2636
   177
    ResGraph *_res_graph;
kpeter@2636
   178
    // The residual cost map
kpeter@2636
   179
    ResidualCostMap _res_cost;
kpeter@2636
   180
kpeter@2636
   181
  public:
kpeter@2636
   182
kpeter@2636
   183
    /// \brief General constructor (with lower bounds).
kpeter@2636
   184
    ///
kpeter@2636
   185
    /// General constructor (with lower bounds).
kpeter@2636
   186
    ///
kpeter@2636
   187
    /// \param graph The directed graph the algorithm runs on.
kpeter@2636
   188
    /// \param lower The lower bounds of the edges.
kpeter@2636
   189
    /// \param capacity The capacities (upper bounds) of the edges.
kpeter@2636
   190
    /// \param cost The cost (length) values of the edges.
kpeter@2636
   191
    /// \param supply The supply values of the nodes (signed).
kpeter@2636
   192
    CancelAndTighten( const Graph &graph,
kpeter@2636
   193
                      const LowerMap &lower,
kpeter@2636
   194
                      const CapacityMap &capacity,
kpeter@2636
   195
                      const CostMap &cost,
kpeter@2636
   196
                      const SupplyMap &supply ) :
kpeter@2636
   197
      _graph(graph), _lower(&lower), _capacity(capacity), _cost(cost),
kpeter@2636
   198
      _supply(supply), _flow(NULL), _local_flow(false),
kpeter@2636
   199
      _potential(NULL), _local_potential(false),
kpeter@2636
   200
      _res_graph(NULL), _res_cost(_cost)
kpeter@2636
   201
    {
kpeter@2636
   202
      // Check the sum of supply values
kpeter@2636
   203
      Supply sum = 0;
kpeter@2636
   204
      for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
kpeter@2636
   205
      _valid_supply = sum == 0;
kpeter@2636
   206
kpeter@2636
   207
      // Remove non-zero lower bounds
kpeter@2636
   208
      for (EdgeIt e(_graph); e != INVALID; ++e) {
kpeter@2636
   209
        if (lower[e] != 0) {
kpeter@2636
   210
          _capacity[e] -= lower[e];
kpeter@2636
   211
          _supply[_graph.source(e)] -= lower[e];
kpeter@2636
   212
          _supply[_graph.target(e)] += lower[e];
kpeter@2636
   213
        }
kpeter@2636
   214
      }
kpeter@2636
   215
    }
kpeter@2636
   216
kpeter@2636
   217
    /// \brief General constructor (without lower bounds).
kpeter@2636
   218
    ///
kpeter@2636
   219
    /// General constructor (without lower bounds).
kpeter@2636
   220
    ///
kpeter@2636
   221
    /// \param graph The directed graph the algorithm runs on.
kpeter@2636
   222
    /// \param capacity The capacities (upper bounds) of the edges.
kpeter@2636
   223
    /// \param cost The cost (length) values of the edges.
kpeter@2636
   224
    /// \param supply The supply values of the nodes (signed).
kpeter@2636
   225
    CancelAndTighten( const Graph &graph,
kpeter@2636
   226
                      const CapacityMap &capacity,
kpeter@2636
   227
                      const CostMap &cost,
kpeter@2636
   228
                      const SupplyMap &supply ) :
kpeter@2636
   229
      _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
kpeter@2636
   230
      _supply(supply), _flow(NULL), _local_flow(false),
kpeter@2636
   231
      _potential(NULL), _local_potential(false),
kpeter@2636
   232
      _res_graph(NULL), _res_cost(_cost)
kpeter@2636
   233
    {
kpeter@2636
   234
      // Check the sum of supply values
kpeter@2636
   235
      Supply sum = 0;
kpeter@2636
   236
      for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
kpeter@2636
   237
      _valid_supply = sum == 0;
kpeter@2636
   238
    }
kpeter@2636
   239
kpeter@2636
   240
    /// \brief Simple constructor (with lower bounds).
kpeter@2636
   241
    ///
kpeter@2636
   242
    /// Simple constructor (with lower bounds).
kpeter@2636
   243
    ///
kpeter@2636
   244
    /// \param graph The directed graph the algorithm runs on.
kpeter@2636
   245
    /// \param lower The lower bounds of the edges.
kpeter@2636
   246
    /// \param capacity The capacities (upper bounds) of the edges.
kpeter@2636
   247
    /// \param cost The cost (length) values of the edges.
kpeter@2636
   248
    /// \param s The source node.
kpeter@2636
   249
    /// \param t The target node.
kpeter@2636
   250
    /// \param flow_value The required amount of flow from node \c s
kpeter@2636
   251
    /// to node \c t (i.e. the supply of \c s and the demand of \c t).
kpeter@2636
   252
    CancelAndTighten( const Graph &graph,
kpeter@2636
   253
                      const LowerMap &lower,
kpeter@2636
   254
                      const CapacityMap &capacity,
kpeter@2636
   255
                      const CostMap &cost,
kpeter@2636
   256
                      Node s, Node t,
kpeter@2636
   257
                      Supply flow_value ) :
kpeter@2636
   258
      _graph(graph), _lower(&lower), _capacity(capacity), _cost(cost),
kpeter@2636
   259
      _supply(graph, 0), _flow(NULL), _local_flow(false),
kpeter@2636
   260
      _potential(NULL), _local_potential(false),
kpeter@2636
   261
      _res_graph(NULL), _res_cost(_cost)
kpeter@2636
   262
    {
kpeter@2636
   263
      // Remove non-zero lower bounds
kpeter@2636
   264
      _supply[s] =  flow_value;
kpeter@2636
   265
      _supply[t] = -flow_value;
kpeter@2636
   266
      for (EdgeIt e(_graph); e != INVALID; ++e) {
kpeter@2636
   267
        if (lower[e] != 0) {
kpeter@2636
   268
          _capacity[e] -= lower[e];
kpeter@2636
   269
          _supply[_graph.source(e)] -= lower[e];
kpeter@2636
   270
          _supply[_graph.target(e)] += lower[e];
kpeter@2636
   271
        }
kpeter@2636
   272
      }
kpeter@2636
   273
      _valid_supply = true;
kpeter@2636
   274
    }
kpeter@2636
   275
kpeter@2636
   276
    /// \brief Simple constructor (without lower bounds).
kpeter@2636
   277
    ///
kpeter@2636
   278
    /// Simple constructor (without lower bounds).
kpeter@2636
   279
    ///
kpeter@2636
   280
    /// \param graph The directed graph the algorithm runs on.
kpeter@2636
   281
    /// \param capacity The capacities (upper bounds) of the edges.
kpeter@2636
   282
    /// \param cost The cost (length) values of the edges.
kpeter@2636
   283
    /// \param s The source node.
kpeter@2636
   284
    /// \param t The target node.
kpeter@2636
   285
    /// \param flow_value The required amount of flow from node \c s
kpeter@2636
   286
    /// to node \c t (i.e. the supply of \c s and the demand of \c t).
kpeter@2636
   287
    CancelAndTighten( const Graph &graph,
kpeter@2636
   288
                      const CapacityMap &capacity,
kpeter@2636
   289
                      const CostMap &cost,
kpeter@2636
   290
                      Node s, Node t,
kpeter@2636
   291
                      Supply flow_value ) :
kpeter@2636
   292
      _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
kpeter@2636
   293
      _supply(graph, 0), _flow(NULL), _local_flow(false),
kpeter@2636
   294
      _potential(NULL), _local_potential(false),
kpeter@2636
   295
      _res_graph(NULL), _res_cost(_cost)
kpeter@2636
   296
    {
kpeter@2636
   297
      _supply[s] =  flow_value;
kpeter@2636
   298
      _supply[t] = -flow_value;
kpeter@2636
   299
      _valid_supply = true;
kpeter@2636
   300
    }
kpeter@2636
   301
kpeter@2636
   302
    /// Destructor.
kpeter@2636
   303
    ~CancelAndTighten() {
kpeter@2636
   304
      if (_local_flow) delete _flow;
kpeter@2636
   305
      if (_local_potential) delete _potential;
kpeter@2636
   306
      delete _res_graph;
kpeter@2636
   307
    }
kpeter@2636
   308
kpeter@2636
   309
    /// \brief Set the flow map.
kpeter@2636
   310
    ///
kpeter@2636
   311
    /// Set the flow map.
kpeter@2636
   312
    ///
kpeter@2636
   313
    /// \return \c (*this)
kpeter@2636
   314
    CancelAndTighten& flowMap(FlowMap &map) {
kpeter@2636
   315
      if (_local_flow) {
kpeter@2636
   316
        delete _flow;
kpeter@2636
   317
        _local_flow = false;
kpeter@2636
   318
      }
kpeter@2636
   319
      _flow = &map;
kpeter@2636
   320
      return *this;
kpeter@2636
   321
    }
kpeter@2636
   322
kpeter@2636
   323
    /// \brief Set the potential map.
kpeter@2636
   324
    ///
kpeter@2636
   325
    /// Set the potential map.
kpeter@2636
   326
    ///
kpeter@2636
   327
    /// \return \c (*this)
kpeter@2636
   328
    CancelAndTighten& potentialMap(PotentialMap &map) {
kpeter@2636
   329
      if (_local_potential) {
kpeter@2636
   330
        delete _potential;
kpeter@2636
   331
        _local_potential = false;
kpeter@2636
   332
      }
kpeter@2636
   333
      _potential = &map;
kpeter@2636
   334
      return *this;
kpeter@2636
   335
    }
kpeter@2636
   336
kpeter@2636
   337
    /// \name Execution control
kpeter@2636
   338
kpeter@2636
   339
    /// @{
kpeter@2636
   340
kpeter@2636
   341
    /// \brief Run the algorithm.
kpeter@2636
   342
    ///
kpeter@2636
   343
    /// Run the algorithm.
kpeter@2636
   344
    ///
kpeter@2636
   345
    /// \return \c true if a feasible flow can be found.
kpeter@2636
   346
    bool run() {
kpeter@2636
   347
      return init() && start();
kpeter@2636
   348
    }
kpeter@2636
   349
kpeter@2636
   350
    /// @}
kpeter@2636
   351
kpeter@2636
   352
    /// \name Query Functions
kpeter@2636
   353
    /// The result of the algorithm can be obtained using these
kpeter@2636
   354
    /// functions.\n
kpeter@2636
   355
    /// \ref lemon::CancelAndTighten::run() "run()" must be called before
kpeter@2636
   356
    /// using them.
kpeter@2636
   357
kpeter@2636
   358
    /// @{
kpeter@2636
   359
kpeter@2636
   360
    /// \brief Return a const reference to the edge map storing the
kpeter@2636
   361
    /// found flow.
kpeter@2636
   362
    ///
kpeter@2636
   363
    /// Return a const reference to the edge map storing the found flow.
kpeter@2636
   364
    ///
kpeter@2636
   365
    /// \pre \ref run() must be called before using this function.
kpeter@2636
   366
    const FlowMap& flowMap() const {
kpeter@2636
   367
      return *_flow;
kpeter@2636
   368
    }
kpeter@2636
   369
kpeter@2636
   370
    /// \brief Return a const reference to the node map storing the
kpeter@2636
   371
    /// found potentials (the dual solution).
kpeter@2636
   372
    ///
kpeter@2636
   373
    /// Return a const reference to the node map storing the found
kpeter@2636
   374
    /// potentials (the dual solution).
kpeter@2636
   375
    ///
kpeter@2636
   376
    /// \pre \ref run() must be called before using this function.
kpeter@2636
   377
    const PotentialMap& potentialMap() const {
kpeter@2636
   378
      return *_potential;
kpeter@2636
   379
    }
kpeter@2636
   380
kpeter@2636
   381
    /// \brief Return the flow on the given edge.
kpeter@2636
   382
    ///
kpeter@2636
   383
    /// Return the flow on the given edge.
kpeter@2636
   384
    ///
kpeter@2636
   385
    /// \pre \ref run() must be called before using this function.
kpeter@2636
   386
    Capacity flow(const Edge& edge) const {
kpeter@2636
   387
      return (*_flow)[edge];
kpeter@2636
   388
    }
kpeter@2636
   389
kpeter@2636
   390
    /// \brief Return the potential of the given node.
kpeter@2636
   391
    ///
kpeter@2636
   392
    /// Return the potential of the given node.
kpeter@2636
   393
    ///
kpeter@2636
   394
    /// \pre \ref run() must be called before using this function.
kpeter@2636
   395
    Cost potential(const Node& node) const {
kpeter@2636
   396
      return (*_potential)[node];
kpeter@2636
   397
    }
kpeter@2636
   398
kpeter@2636
   399
    /// \brief Return the total cost of the found flow.
kpeter@2636
   400
    ///
kpeter@2636
   401
    /// Return the total cost of the found flow. The complexity of the
kpeter@2636
   402
    /// function is \f$ O(e) \f$.
kpeter@2636
   403
    ///
kpeter@2636
   404
    /// \pre \ref run() must be called before using this function.
kpeter@2636
   405
    Cost totalCost() const {
kpeter@2636
   406
      Cost c = 0;
kpeter@2636
   407
      for (EdgeIt e(_graph); e != INVALID; ++e)
kpeter@2636
   408
        c += (*_flow)[e] * _cost[e];
kpeter@2636
   409
      return c;
kpeter@2636
   410
    }
kpeter@2636
   411
kpeter@2636
   412
    /// @}
kpeter@2636
   413
kpeter@2636
   414
  private:
kpeter@2636
   415
kpeter@2636
   416
    /// Initialize the algorithm.
kpeter@2636
   417
    bool init() {
kpeter@2636
   418
      if (!_valid_supply) return false;
kpeter@2636
   419
kpeter@2636
   420
      // Initialize flow and potential maps
kpeter@2636
   421
      if (!_flow) {
kpeter@2636
   422
        _flow = new FlowMap(_graph);
kpeter@2636
   423
        _local_flow = true;
kpeter@2636
   424
      }
kpeter@2636
   425
      if (!_potential) {
kpeter@2636
   426
        _potential = new PotentialMap(_graph);
kpeter@2636
   427
        _local_potential = true;
kpeter@2636
   428
      }
kpeter@2636
   429
kpeter@2636
   430
      _res_graph = new ResGraph(_graph, _capacity, *_flow);
kpeter@2636
   431
kpeter@2636
   432
      // Find a feasible flow using Circulation
kpeter@2636
   433
      Circulation< Graph, ConstMap<Edge, Capacity>,
kpeter@2636
   434
                   CapacityEdgeMap, SupplyMap >
kpeter@2636
   435
        circulation( _graph, constMap<Edge>(Capacity(0)),
kpeter@2636
   436
                     _capacity, _supply );
kpeter@2636
   437
      return circulation.flowMap(*_flow).run();
kpeter@2636
   438
    }
kpeter@2636
   439
kpeter@2636
   440
    bool start() {
kpeter@2636
   441
      const double LIMIT_FACTOR = 0.01;
kpeter@2636
   442
      const int MIN_LIMIT = 3;
kpeter@2636
   443
kpeter@2636
   444
      typedef typename Graph::template NodeMap<double> FloatPotentialMap;
kpeter@2636
   445
      typedef typename Graph::template NodeMap<int> LevelMap;
kpeter@2636
   446
      typedef typename Graph::template NodeMap<bool> BoolNodeMap;
kpeter@2636
   447
      typedef typename Graph::template NodeMap<Node> PredNodeMap;
kpeter@2636
   448
      typedef typename Graph::template NodeMap<Edge> PredEdgeMap;
kpeter@2636
   449
      typedef typename ResGraph::template EdgeMap<double> ResShiftCostMap;
kpeter@2636
   450
      FloatPotentialMap pi(_graph);
kpeter@2636
   451
      LevelMap level(_graph);
kpeter@2636
   452
      BoolNodeMap reached(_graph);
kpeter@2636
   453
      BoolNodeMap processed(_graph);
kpeter@2636
   454
      PredNodeMap pred_node(_graph);
kpeter@2636
   455
      PredEdgeMap pred_edge(_graph);
kpeter@2636
   456
      int node_num = countNodes(_graph);
kpeter@2636
   457
      typedef std::pair<Edge, bool> pair;
kpeter@2636
   458
      std::vector<pair> stack(node_num);
kpeter@2636
   459
      std::vector<Node> proc_vector(node_num);
kpeter@2636
   460
      ResShiftCostMap shift_cost(*_res_graph);
kpeter@2636
   461
kpeter@2636
   462
      Tolerance<double> tol;
kpeter@2636
   463
      tol.epsilon(1e-6);
kpeter@2636
   464
kpeter@2636
   465
      Timer t1, t2, t3;
kpeter@2636
   466
      t1.reset();
kpeter@2636
   467
      t2.reset();
kpeter@2636
   468
      t3.reset();
kpeter@2636
   469
kpeter@2636
   470
      // Initialize epsilon and the node potentials
kpeter@2636
   471
      double epsilon = 0;
kpeter@2636
   472
      for (EdgeIt e(_graph); e != INVALID; ++e) {
kpeter@2636
   473
        if (_capacity[e] - (*_flow)[e] > 0 && _cost[e] < -epsilon)
kpeter@2636
   474
          epsilon = -_cost[e];
kpeter@2636
   475
        else if ((*_flow)[e] > 0 && _cost[e] > epsilon)
kpeter@2636
   476
          epsilon = _cost[e];
kpeter@2636
   477
      }
kpeter@2636
   478
      for (NodeIt v(_graph); v != INVALID; ++v) {
kpeter@2636
   479
        pi[v] = 0;
kpeter@2636
   480
      }
kpeter@2636
   481
kpeter@2636
   482
      // Start phases
kpeter@2636
   483
      int limit = int(LIMIT_FACTOR * node_num);
kpeter@2636
   484
      if (limit < MIN_LIMIT) limit = MIN_LIMIT;
kpeter@2636
   485
      int iter = limit;
kpeter@2636
   486
      while (epsilon * node_num >= 1) {
kpeter@2636
   487
        t1.start();
kpeter@2636
   488
        // Find and cancel cycles in the admissible graph using DFS
kpeter@2636
   489
        for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@2636
   490
          reached[n] = false;
kpeter@2636
   491
          processed[n] = false;
kpeter@2636
   492
        }
kpeter@2636
   493
        int stack_head = -1;
kpeter@2636
   494
        int proc_head = -1;
kpeter@2636
   495
kpeter@2636
   496
        for (NodeIt start(_graph); start != INVALID; ++start) {
kpeter@2636
   497
          if (reached[start]) continue;
kpeter@2636
   498
kpeter@2636
   499
          // New start node
kpeter@2636
   500
          reached[start] = true;
kpeter@2636
   501
          pred_edge[start] = INVALID;
kpeter@2636
   502
          pred_node[start] = INVALID;
kpeter@2636
   503
kpeter@2636
   504
          // Find the first admissible residual outgoing edge
kpeter@2636
   505
          double p = pi[start];
kpeter@2636
   506
          Edge e;
kpeter@2636
   507
          _graph.firstOut(e, start);
kpeter@2636
   508
          while ( e != INVALID && (_capacity[e] - (*_flow)[e] == 0 ||
kpeter@2636
   509
                  !tol.negative(_cost[e] + p - pi[_graph.target(e)])) )
kpeter@2636
   510
            _graph.nextOut(e);
kpeter@2636
   511
          if (e != INVALID) {
kpeter@2636
   512
            stack[++stack_head] = pair(e, true);
kpeter@2636
   513
            goto next_step_1;
kpeter@2636
   514
          }
kpeter@2636
   515
          _graph.firstIn(e, start);
kpeter@2636
   516
          while ( e != INVALID && ((*_flow)[e] == 0 ||
kpeter@2636
   517
                  !tol.negative(-_cost[e] + p - pi[_graph.source(e)])) )
kpeter@2636
   518
            _graph.nextIn(e);
kpeter@2636
   519
          if (e != INVALID) {
kpeter@2636
   520
            stack[++stack_head] = pair(e, false);
kpeter@2636
   521
            goto next_step_1;
kpeter@2636
   522
          }
kpeter@2636
   523
          processed[start] = true;
kpeter@2636
   524
          proc_vector[++proc_head] = start;
kpeter@2636
   525
          continue;
kpeter@2636
   526
        next_step_1:
kpeter@2636
   527
kpeter@2636
   528
          while (stack_head >= 0) {
kpeter@2636
   529
            Edge se = stack[stack_head].first;
kpeter@2636
   530
            bool sf = stack[stack_head].second;
kpeter@2636
   531
            Node u, v;
kpeter@2636
   532
            if (sf) {
kpeter@2636
   533
              u = _graph.source(se);
kpeter@2636
   534
              v = _graph.target(se);
kpeter@2636
   535
            } else {
kpeter@2636
   536
              u = _graph.target(se);
kpeter@2636
   537
              v = _graph.source(se);
kpeter@2636
   538
            }
kpeter@2636
   539
kpeter@2636
   540
            if (!reached[v]) {
kpeter@2636
   541
              // A new node is reached
kpeter@2636
   542
              reached[v] = true;
kpeter@2636
   543
              pred_node[v] = u;
kpeter@2636
   544
              pred_edge[v] = se;
kpeter@2636
   545
              // Find the first admissible residual outgoing edge
kpeter@2636
   546
              double p = pi[v];
kpeter@2636
   547
              Edge e;
kpeter@2636
   548
              _graph.firstOut(e, v);
kpeter@2636
   549
              while ( e != INVALID && (_capacity[e] - (*_flow)[e] == 0 ||
kpeter@2636
   550
                      !tol.negative(_cost[e] + p - pi[_graph.target(e)])) )
kpeter@2636
   551
                _graph.nextOut(e);
kpeter@2636
   552
              if (e != INVALID) {
kpeter@2636
   553
                stack[++stack_head] = pair(e, true);
kpeter@2636
   554
                goto next_step_2;
kpeter@2636
   555
              }
kpeter@2636
   556
              _graph.firstIn(e, v);
kpeter@2636
   557
              while ( e != INVALID && ((*_flow)[e] == 0 ||
kpeter@2636
   558
                      !tol.negative(-_cost[e] + p - pi[_graph.source(e)])) )
kpeter@2636
   559
                _graph.nextIn(e);
kpeter@2636
   560
              stack[++stack_head] = pair(e, false);
kpeter@2636
   561
            next_step_2: ;
kpeter@2636
   562
            } else {
kpeter@2636
   563
              if (!processed[v]) {
kpeter@2636
   564
                // A cycle is found
kpeter@2636
   565
                Node n, w = u;
kpeter@2636
   566
                Capacity d, delta = sf ? _capacity[se] - (*_flow)[se] :
kpeter@2636
   567
                                         (*_flow)[se];
kpeter@2636
   568
                for (n = u; n != v; n = pred_node[n]) {
kpeter@2636
   569
                  d = _graph.target(pred_edge[n]) == n ?
kpeter@2636
   570
                      _capacity[pred_edge[n]] - (*_flow)[pred_edge[n]] :
kpeter@2636
   571
                      (*_flow)[pred_edge[n]];
kpeter@2636
   572
                  if (d <= delta) {
kpeter@2636
   573
                    delta = d;
kpeter@2636
   574
                    w = pred_node[n];
kpeter@2636
   575
                  }
kpeter@2636
   576
                }
kpeter@2636
   577
kpeter@2636
   578
/*
kpeter@2636
   579
                std::cout << "CYCLE FOUND: ";
kpeter@2636
   580
                if (sf)
kpeter@2636
   581
                  std::cout << _cost[se] + pi[_graph.source(se)] - pi[_graph.target(se)];
kpeter@2636
   582
                else
kpeter@2636
   583
                  std::cout << _graph.id(se) << ":" << -(_cost[se] + pi[_graph.source(se)] - pi[_graph.target(se)]);
kpeter@2636
   584
                for (n = u; n != v; n = pred_node[n]) {
kpeter@2636
   585
                  if (_graph.target(pred_edge[n]) == n)
kpeter@2636
   586
                    std::cout << " " << _cost[pred_edge[n]] + pi[_graph.source(pred_edge[n])] - pi[_graph.target(pred_edge[n])];
kpeter@2636
   587
                  else
kpeter@2636
   588
                    std::cout << " " << -(_cost[pred_edge[n]] + pi[_graph.source(pred_edge[n])] - pi[_graph.target(pred_edge[n])]);
kpeter@2636
   589
                }
kpeter@2636
   590
                std::cout << "\n";
kpeter@2636
   591
*/
kpeter@2636
   592
                // Augment along the cycle
kpeter@2636
   593
                (*_flow)[se] = sf ? (*_flow)[se] + delta :
kpeter@2636
   594
                                    (*_flow)[se] - delta;
kpeter@2636
   595
                for (n = u; n != v; n = pred_node[n]) {
kpeter@2636
   596
                  if (_graph.target(pred_edge[n]) == n)
kpeter@2636
   597
                    (*_flow)[pred_edge[n]] += delta;
kpeter@2636
   598
                  else
kpeter@2636
   599
                    (*_flow)[pred_edge[n]] -= delta;
kpeter@2636
   600
                }
kpeter@2636
   601
                for (n = u; stack_head > 0 && n != w; n = pred_node[n]) {
kpeter@2636
   602
                  --stack_head;
kpeter@2636
   603
                  reached[n] = false;
kpeter@2636
   604
                }
kpeter@2636
   605
                u = w;
kpeter@2636
   606
              }
kpeter@2636
   607
              v = u;
kpeter@2636
   608
kpeter@2636
   609
              // Find the next admissible residual outgoing edge
kpeter@2636
   610
              double p = pi[v];
kpeter@2636
   611
              Edge e = stack[stack_head].first;
kpeter@2636
   612
              if (!stack[stack_head].second) {
kpeter@2636
   613
                _graph.nextIn(e);
kpeter@2636
   614
                goto in_edge_3;
kpeter@2636
   615
              }
kpeter@2636
   616
              _graph.nextOut(e);
kpeter@2636
   617
              while ( e != INVALID && (_capacity[e] - (*_flow)[e] == 0 ||
kpeter@2636
   618
                      !tol.negative(_cost[e] + p - pi[_graph.target(e)])) )
kpeter@2636
   619
                _graph.nextOut(e);
kpeter@2636
   620
              if (e != INVALID) {
kpeter@2636
   621
                stack[stack_head] = pair(e, true);
kpeter@2636
   622
                goto next_step_3;
kpeter@2636
   623
              }
kpeter@2636
   624
              _graph.firstIn(e, v);
kpeter@2636
   625
            in_edge_3:
kpeter@2636
   626
              while ( e != INVALID && ((*_flow)[e] == 0 ||
kpeter@2636
   627
                      !tol.negative(-_cost[e] + p - pi[_graph.source(e)])) )
kpeter@2636
   628
                _graph.nextIn(e);
kpeter@2636
   629
              stack[stack_head] = pair(e, false);
kpeter@2636
   630
            next_step_3: ;
kpeter@2636
   631
            }
kpeter@2636
   632
kpeter@2636
   633
            while (stack_head >= 0 && stack[stack_head].first == INVALID) {
kpeter@2636
   634
              processed[v] = true;
kpeter@2636
   635
              proc_vector[++proc_head] = v;
kpeter@2636
   636
              if (--stack_head >= 0) {
kpeter@2636
   637
                v = stack[stack_head].second ?
kpeter@2636
   638
                    _graph.source(stack[stack_head].first) :
kpeter@2636
   639
                    _graph.target(stack[stack_head].first);
kpeter@2636
   640
                // Find the next admissible residual outgoing edge
kpeter@2636
   641
                double p = pi[v];
kpeter@2636
   642
                Edge e = stack[stack_head].first;
kpeter@2636
   643
                if (!stack[stack_head].second) {
kpeter@2636
   644
                  _graph.nextIn(e);
kpeter@2636
   645
                  goto in_edge_4;
kpeter@2636
   646
                }
kpeter@2636
   647
                _graph.nextOut(e);
kpeter@2636
   648
                while ( e != INVALID && (_capacity[e] - (*_flow)[e] == 0 ||
kpeter@2636
   649
                        !tol.negative(_cost[e] + p - pi[_graph.target(e)])) )
kpeter@2636
   650
                  _graph.nextOut(e);
kpeter@2636
   651
                if (e != INVALID) {
kpeter@2636
   652
                  stack[stack_head] = pair(e, true);
kpeter@2636
   653
                  goto next_step_4;
kpeter@2636
   654
                }
kpeter@2636
   655
                _graph.firstIn(e, v);
kpeter@2636
   656
              in_edge_4:
kpeter@2636
   657
                while ( e != INVALID && ((*_flow)[e] == 0 ||
kpeter@2636
   658
                        !tol.negative(-_cost[e] + p - pi[_graph.source(e)])) )
kpeter@2636
   659
                  _graph.nextIn(e);
kpeter@2636
   660
                stack[stack_head] = pair(e, false);
kpeter@2636
   661
              next_step_4: ;
kpeter@2636
   662
              }
kpeter@2636
   663
            }
kpeter@2636
   664
          }
kpeter@2636
   665
        }
kpeter@2636
   666
        t1.stop();
kpeter@2636
   667
kpeter@2636
   668
        // Tighten potentials and epsilon
kpeter@2636
   669
        if (--iter > 0) {
kpeter@2636
   670
          // Compute levels
kpeter@2636
   671
          t2.start();
kpeter@2636
   672
          for (int i = proc_head; i >= 0; --i) {
kpeter@2636
   673
            Node v = proc_vector[i];
kpeter@2636
   674
            double p = pi[v];
kpeter@2636
   675
            int l = 0;
kpeter@2636
   676
            for (InEdgeIt e(_graph, v); e != INVALID; ++e) {
kpeter@2636
   677
              Node u = _graph.source(e);
kpeter@2636
   678
              if ( _capacity[e] - (*_flow)[e] > 0 &&
kpeter@2636
   679
                   tol.negative(_cost[e] + pi[u] - p) &&
kpeter@2636
   680
                   level[u] + 1 > l ) l = level[u] + 1;
kpeter@2636
   681
            }
kpeter@2636
   682
            for (OutEdgeIt e(_graph, v); e != INVALID; ++e) {
kpeter@2636
   683
              Node u = _graph.target(e);
kpeter@2636
   684
              if ( (*_flow)[e] > 0 &&
kpeter@2636
   685
                   tol.negative(-_cost[e] + pi[u] - p) &&
kpeter@2636
   686
                   level[u] + 1 > l ) l = level[u] + 1;
kpeter@2636
   687
            }
kpeter@2636
   688
            level[v] = l;
kpeter@2636
   689
          }
kpeter@2636
   690
kpeter@2636
   691
          // Modify potentials
kpeter@2636
   692
          double p, q = -1;
kpeter@2636
   693
          for (EdgeIt e(_graph); e != INVALID; ++e) {
kpeter@2636
   694
            Node u = _graph.source(e);
kpeter@2636
   695
            Node v = _graph.target(e);
kpeter@2636
   696
            if (_capacity[e] - (*_flow)[e] > 0 && level[u] - level[v] > 0) {
kpeter@2636
   697
              p = (_cost[e] + pi[u] - pi[v] + epsilon) /
kpeter@2636
   698
                  (level[u] - level[v] + 1);
kpeter@2636
   699
              if (q < 0 || p < q) q = p;
kpeter@2636
   700
            }
kpeter@2636
   701
            else if ((*_flow)[e] > 0 && level[v] - level[u] > 0) {
kpeter@2636
   702
              p = (-_cost[e] - pi[u] + pi[v] + epsilon) /
kpeter@2636
   703
                  (level[v] - level[u] + 1);
kpeter@2636
   704
              if (q < 0 || p < q) q = p;
kpeter@2636
   705
            }
kpeter@2636
   706
          }
kpeter@2636
   707
          for (NodeIt v(_graph); v != INVALID; ++v) {
kpeter@2636
   708
            pi[v] -= q * level[v];
kpeter@2636
   709
          }
kpeter@2636
   710
kpeter@2636
   711
          // Modify epsilon
kpeter@2636
   712
          epsilon = 0;
kpeter@2636
   713
          for (EdgeIt e(_graph); e != INVALID; ++e) {
kpeter@2636
   714
            double curr = _cost[e] + pi[_graph.source(e)]
kpeter@2636
   715
                                   - pi[_graph.target(e)];
kpeter@2636
   716
            if (_capacity[e] - (*_flow)[e] > 0 && curr < -epsilon)
kpeter@2636
   717
              epsilon = -curr;
kpeter@2636
   718
            else if ((*_flow)[e] > 0 && curr > epsilon)
kpeter@2636
   719
              epsilon = curr;
kpeter@2636
   720
          }
kpeter@2636
   721
          t2.stop();
kpeter@2636
   722
        } else {
kpeter@2636
   723
          // Set epsilon to the minimum cycle mean
kpeter@2636
   724
          t3.start();
kpeter@2636
   725
kpeter@2636
   726
/**/
kpeter@2636
   727
          StaticGraph static_graph;
kpeter@2636
   728
          typename ResGraph::template NodeMap<typename StaticGraph::Node> node_ref(*_res_graph);
kpeter@2636
   729
          typename ResGraph::template EdgeMap<typename StaticGraph::Edge> edge_ref(*_res_graph);
kpeter@2636
   730
          static_graph.build(*_res_graph, node_ref, edge_ref);
kpeter@2636
   731
          typename StaticGraph::template NodeMap<double> static_pi(static_graph);
kpeter@2636
   732
          typename StaticGraph::template EdgeMap<double> static_cost(static_graph);
kpeter@2636
   733
kpeter@2636
   734
          for (typename ResGraph::EdgeIt e(*_res_graph); e != INVALID; ++e)
kpeter@2636
   735
            static_cost[edge_ref[e]] = _res_cost[e];
kpeter@2636
   736
kpeter@2636
   737
          MinMeanCycle<StaticGraph, typename StaticGraph::template EdgeMap<double> >
kpeter@2636
   738
            mmc(static_graph, static_cost);
kpeter@2636
   739
          mmc.init();
kpeter@2636
   740
          mmc.findMinMean();
kpeter@2636
   741
          epsilon = -mmc.cycleMean();
kpeter@2636
   742
/**/
kpeter@2636
   743
kpeter@2636
   744
/*
kpeter@2636
   745
          MinMeanCycle<ResGraph, ResidualCostMap> mmc(*_res_graph, _res_cost);
kpeter@2636
   746
          mmc.init();
kpeter@2636
   747
          mmc.findMinMean();
kpeter@2636
   748
          epsilon = -mmc.cycleMean();
kpeter@2636
   749
*/
kpeter@2636
   750
kpeter@2636
   751
          // Compute feasible potentials for the current epsilon
kpeter@2636
   752
          for (typename StaticGraph::EdgeIt e(static_graph); e != INVALID; ++e)
kpeter@2636
   753
            static_cost[e] += epsilon;
kpeter@2636
   754
          typename BellmanFord<StaticGraph, typename StaticGraph::template EdgeMap<double> >::
kpeter@2636
   755
            template DefDistMap<typename StaticGraph::template NodeMap<double> >::
kpeter@2636
   756
            template DefOperationTraits<BFOperationTraits>::Create
kpeter@2636
   757
              bf(static_graph, static_cost);
kpeter@2636
   758
          bf.distMap(static_pi).init(0);
kpeter@2636
   759
          bf.start();
kpeter@2636
   760
          for (NodeIt n(_graph); n != INVALID; ++n)
kpeter@2636
   761
            pi[n] = static_pi[node_ref[n]];
kpeter@2636
   762
          
kpeter@2636
   763
/*
kpeter@2636
   764
          for (typename ResGraph::EdgeIt e(*_res_graph); e != INVALID; ++e)
kpeter@2636
   765
            shift_cost[e] = _res_cost[e] + epsilon;
kpeter@2636
   766
          typename BellmanFord<ResGraph, ResShiftCostMap>::
kpeter@2636
   767
            template DefDistMap<FloatPotentialMap>::
kpeter@2636
   768
            template DefOperationTraits<BFOperationTraits>::Create
kpeter@2636
   769
              bf(*_res_graph, shift_cost);
kpeter@2636
   770
          bf.distMap(pi).init(0);
kpeter@2636
   771
          bf.start();
kpeter@2636
   772
*/
kpeter@2636
   773
kpeter@2636
   774
          iter = limit;
kpeter@2636
   775
          t3.stop();
kpeter@2636
   776
        }
kpeter@2636
   777
      }
kpeter@2636
   778
kpeter@2636
   779
//      std::cout << t1.realTime() << " " << t2.realTime() << " " << t3.realTime() << "\n";
kpeter@2636
   780
kpeter@2636
   781
      // Handle non-zero lower bounds
kpeter@2636
   782
      if (_lower) {
kpeter@2636
   783
        for (EdgeIt e(_graph); e != INVALID; ++e)
kpeter@2636
   784
          (*_flow)[e] += (*_lower)[e];
kpeter@2636
   785
      }
kpeter@2636
   786
      return true;
kpeter@2636
   787
    }
kpeter@2636
   788
kpeter@2636
   789
  }; //class CancelAndTighten
kpeter@2636
   790
kpeter@2636
   791
  ///@}
kpeter@2636
   792
kpeter@2636
   793
} //namespace lemon
kpeter@2636
   794
kpeter@2636
   795
#endif //LEMON_CANCEL_AND_TIGHTEN_H