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