lemon/cycle_canceling.h
author deba
Sun, 05 Oct 2008 20:08:13 +0000
changeset 2622 fa2877651022
parent 2593 8eed667ea23c
child 2623 90defb96ee61
permissions -rw-r--r--
Fix _setCoeff
deba@2440
     1
/* -*- C++ -*-
deba@2440
     2
 *
deba@2440
     3
 * This file is a part of LEMON, a generic C++ optimization library
deba@2440
     4
 *
alpar@2553
     5
 * Copyright (C) 2003-2008
deba@2440
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@2440
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@2440
     8
 *
deba@2440
     9
 * Permission to use, modify and distribute this software is granted
deba@2440
    10
 * provided that this copyright notice appears in all copies. For
deba@2440
    11
 * precise terms see the accompanying LICENSE file.
deba@2440
    12
 *
deba@2440
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@2440
    14
 * express or implied, and with no claim as to its suitability for any
deba@2440
    15
 * purpose.
deba@2440
    16
 *
deba@2440
    17
 */
deba@2440
    18
deba@2440
    19
#ifndef LEMON_CYCLE_CANCELING_H
deba@2440
    20
#define LEMON_CYCLE_CANCELING_H
deba@2440
    21
deba@2440
    22
/// \ingroup min_cost_flow
deba@2440
    23
///
deba@2440
    24
/// \file
kpeter@2573
    25
/// \brief Cycle-canceling algorithm for finding a minimum cost flow.
deba@2440
    26
deba@2440
    27
#include <vector>
kpeter@2509
    28
#include <lemon/graph_adaptor.h>
kpeter@2573
    29
#include <lemon/path.h>
kpeter@2573
    30
deba@2440
    31
#include <lemon/circulation.h>
kpeter@2573
    32
#include <lemon/bellman_ford.h>
kpeter@2573
    33
#include <lemon/min_mean_cycle.h>
kpeter@2556
    34
deba@2440
    35
namespace lemon {
deba@2440
    36
deba@2440
    37
  /// \addtogroup min_cost_flow
deba@2440
    38
  /// @{
deba@2440
    39
kpeter@2556
    40
  /// \brief Implementation of a cycle-canceling algorithm for
kpeter@2556
    41
  /// finding a minimum cost flow.
deba@2440
    42
  ///
kpeter@2556
    43
  /// \ref CycleCanceling implements a cycle-canceling algorithm for
kpeter@2556
    44
  /// finding a minimum cost flow.
deba@2440
    45
  ///
kpeter@2573
    46
  /// \tparam Graph The directed graph type the algorithm runs on.
kpeter@2573
    47
  /// \tparam LowerMap The type of the lower bound map.
kpeter@2573
    48
  /// \tparam CapacityMap The type of the capacity (upper bound) map.
kpeter@2573
    49
  /// \tparam CostMap The type of the cost (length) map.
kpeter@2573
    50
  /// \tparam SupplyMap The type of the supply map.
deba@2440
    51
  ///
deba@2440
    52
  /// \warning
kpeter@2573
    53
  /// - Edge capacities and costs should be \e non-negative \e integers.
kpeter@2573
    54
  /// - Supply values should be \e signed \e integers.
kpeter@2581
    55
  /// - The value types of the maps should be convertible to each other.
kpeter@2581
    56
  /// - \c CostMap::Value must be signed type.
kpeter@2573
    57
  ///
kpeter@2573
    58
  /// \note By default the \ref BellmanFord "Bellman-Ford" algorithm is
kpeter@2573
    59
  /// used for negative cycle detection with limited iteration number.
kpeter@2573
    60
  /// However \ref CycleCanceling also provides the "Minimum Mean
kpeter@2573
    61
  /// Cycle-Canceling" algorithm, which is \e strongly \e polynomial,
kpeter@2573
    62
  /// but rather slower in practice.
kpeter@2573
    63
  /// To use this version of the algorithm, call \ref run() with \c true
kpeter@2573
    64
  /// parameter.
deba@2440
    65
  ///
deba@2440
    66
  /// \author Peter Kovacs
kpeter@2533
    67
  template < typename Graph,
kpeter@2533
    68
             typename LowerMap = typename Graph::template EdgeMap<int>,
kpeter@2573
    69
             typename CapacityMap = typename Graph::template EdgeMap<int>,
kpeter@2533
    70
             typename CostMap = typename Graph::template EdgeMap<int>,
kpeter@2573
    71
             typename SupplyMap = typename Graph::template NodeMap<int> >
deba@2440
    72
  class CycleCanceling
deba@2440
    73
  {
kpeter@2556
    74
    GRAPH_TYPEDEFS(typename Graph);
deba@2440
    75
deba@2440
    76
    typedef typename CapacityMap::Value Capacity;
deba@2440
    77
    typedef typename CostMap::Value Cost;
deba@2440
    78
    typedef typename SupplyMap::Value Supply;
kpeter@2556
    79
    typedef typename Graph::template EdgeMap<Capacity> CapacityEdgeMap;
kpeter@2556
    80
    typedef typename Graph::template NodeMap<Supply> SupplyNodeMap;
deba@2440
    81
deba@2440
    82
    typedef ResGraphAdaptor< const Graph, Capacity,
kpeter@2556
    83
                             CapacityEdgeMap, CapacityEdgeMap > ResGraph;
deba@2440
    84
    typedef typename ResGraph::Node ResNode;
deba@2440
    85
    typedef typename ResGraph::NodeIt ResNodeIt;
deba@2440
    86
    typedef typename ResGraph::Edge ResEdge;
deba@2440
    87
    typedef typename ResGraph::EdgeIt ResEdgeIt;
deba@2440
    88
deba@2440
    89
  public:
deba@2440
    90
kpeter@2556
    91
    /// The type of the flow map.
kpeter@2556
    92
    typedef typename Graph::template EdgeMap<Capacity> FlowMap;
kpeter@2581
    93
    /// The type of the potential map.
kpeter@2581
    94
    typedef typename Graph::template NodeMap<Cost> PotentialMap;
deba@2440
    95
kpeter@2573
    96
  private:
deba@2440
    97
kpeter@2573
    98
    /// \brief Map adaptor class for handling residual edge costs.
kpeter@2573
    99
    ///
kpeter@2620
   100
    /// Map adaptor class for handling residual edge costs.
kpeter@2573
   101
    class ResidualCostMap : public MapBase<ResEdge, Cost>
deba@2440
   102
    {
deba@2440
   103
    private:
deba@2440
   104
kpeter@2573
   105
      const CostMap &_cost_map;
deba@2440
   106
deba@2440
   107
    public:
deba@2440
   108
kpeter@2573
   109
      ///\e
kpeter@2573
   110
      ResidualCostMap(const CostMap &cost_map) : _cost_map(cost_map) {}
deba@2440
   111
kpeter@2573
   112
      ///\e
kpeter@2509
   113
      Cost operator[](const ResEdge &e) const {
kpeter@2573
   114
        return ResGraph::forward(e) ? _cost_map[e] : -_cost_map[e];
deba@2440
   115
      }
deba@2440
   116
kpeter@2573
   117
    }; //class ResidualCostMap
deba@2440
   118
kpeter@2573
   119
  private:
deba@2440
   120
kpeter@2573
   121
    // The maximum number of iterations for the first execution of the
kpeter@2573
   122
    // Bellman-Ford algorithm. It should be at least 2.
kpeter@2593
   123
    static const int BF_FIRST_LIMIT  = 2;
kpeter@2573
   124
    // The iteration limit for the Bellman-Ford algorithm is multiplied
kpeter@2593
   125
    // by BF_LIMIT_FACTOR/100 in every round.
kpeter@2593
   126
    static const int BF_LIMIT_FACTOR = 150;
deba@2440
   127
kpeter@2573
   128
  private:
deba@2440
   129
kpeter@2573
   130
    // The directed graph the algorithm runs on
kpeter@2573
   131
    const Graph &_graph;
kpeter@2573
   132
    // The original lower bound map
kpeter@2573
   133
    const LowerMap *_lower;
kpeter@2573
   134
    // The modified capacity map
kpeter@2573
   135
    CapacityEdgeMap _capacity;
kpeter@2573
   136
    // The original cost map
kpeter@2573
   137
    const CostMap &_cost;
kpeter@2573
   138
    // The modified supply map
kpeter@2573
   139
    SupplyNodeMap _supply;
kpeter@2573
   140
    bool _valid_supply;
kpeter@2573
   141
kpeter@2573
   142
    // Edge map of the current flow
kpeter@2581
   143
    FlowMap *_flow;
kpeter@2581
   144
    bool _local_flow;
kpeter@2581
   145
    // Node map of the current potentials
kpeter@2581
   146
    PotentialMap *_potential;
kpeter@2581
   147
    bool _local_potential;
kpeter@2573
   148
kpeter@2573
   149
    // The residual graph
kpeter@2581
   150
    ResGraph *_res_graph;
kpeter@2573
   151
    // The residual cost map
kpeter@2573
   152
    ResidualCostMap _res_cost;
kpeter@2573
   153
kpeter@2573
   154
  public:
deba@2440
   155
kpeter@2581
   156
    /// \brief General constructor (with lower bounds).
deba@2440
   157
    ///
kpeter@2581
   158
    /// General constructor (with lower bounds).
deba@2440
   159
    ///
kpeter@2573
   160
    /// \param graph The directed graph the algorithm runs on.
kpeter@2573
   161
    /// \param lower The lower bounds of the edges.
kpeter@2573
   162
    /// \param capacity The capacities (upper bounds) of the edges.
kpeter@2573
   163
    /// \param cost The cost (length) values of the edges.
kpeter@2573
   164
    /// \param supply The supply values of the nodes (signed).
kpeter@2573
   165
    CycleCanceling( const Graph &graph,
kpeter@2573
   166
                    const LowerMap &lower,
kpeter@2573
   167
                    const CapacityMap &capacity,
kpeter@2573
   168
                    const CostMap &cost,
kpeter@2573
   169
                    const SupplyMap &supply ) :
kpeter@2573
   170
      _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
kpeter@2581
   171
      _supply(graph), _flow(0), _local_flow(false),
kpeter@2581
   172
      _potential(0), _local_potential(false), _res_cost(_cost)
deba@2440
   173
    {
kpeter@2556
   174
      // Removing non-zero lower bounds
kpeter@2573
   175
      _capacity = subMap(capacity, lower);
deba@2440
   176
      Supply sum = 0;
kpeter@2573
   177
      for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@2573
   178
        Supply s = supply[n];
kpeter@2573
   179
        for (InEdgeIt e(_graph, n); e != INVALID; ++e)
kpeter@2573
   180
          s += lower[e];
kpeter@2573
   181
        for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
kpeter@2573
   182
          s -= lower[e];
kpeter@2573
   183
        sum += (_supply[n] = s);
deba@2440
   184
      }
kpeter@2573
   185
      _valid_supply = sum == 0;
deba@2440
   186
    }
deba@2440
   187
kpeter@2581
   188
    /// \brief General constructor (without lower bounds).
deba@2440
   189
    ///
kpeter@2581
   190
    /// General constructor (without lower bounds).
deba@2440
   191
    ///
kpeter@2573
   192
    /// \param graph The directed graph the algorithm runs on.
kpeter@2573
   193
    /// \param capacity The capacities (upper bounds) of the edges.
kpeter@2573
   194
    /// \param cost The cost (length) values of the edges.
kpeter@2573
   195
    /// \param supply The supply values of the nodes (signed).
kpeter@2573
   196
    CycleCanceling( const Graph &graph,
kpeter@2573
   197
                    const CapacityMap &capacity,
kpeter@2573
   198
                    const CostMap &cost,
kpeter@2573
   199
                    const SupplyMap &supply ) :
kpeter@2573
   200
      _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
kpeter@2581
   201
      _supply(supply), _flow(0), _local_flow(false),
kpeter@2581
   202
      _potential(0), _local_potential(false), _res_cost(_cost)
deba@2440
   203
    {
deba@2440
   204
      // Checking the sum of supply values
deba@2440
   205
      Supply sum = 0;
kpeter@2573
   206
      for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
kpeter@2573
   207
      _valid_supply = sum == 0;
deba@2440
   208
    }
deba@2440
   209
kpeter@2581
   210
    /// \brief Simple constructor (with lower bounds).
deba@2440
   211
    ///
kpeter@2581
   212
    /// Simple constructor (with lower bounds).
deba@2440
   213
    ///
kpeter@2573
   214
    /// \param graph The directed graph the algorithm runs on.
kpeter@2573
   215
    /// \param lower The lower bounds of the edges.
kpeter@2573
   216
    /// \param capacity The capacities (upper bounds) of the edges.
kpeter@2573
   217
    /// \param cost The cost (length) values of the edges.
kpeter@2573
   218
    /// \param s The source node.
kpeter@2573
   219
    /// \param t The target node.
kpeter@2573
   220
    /// \param flow_value The required amount of flow from node \c s
kpeter@2573
   221
    /// to node \c t (i.e. the supply of \c s and the demand of \c t).
kpeter@2573
   222
    CycleCanceling( const Graph &graph,
kpeter@2573
   223
                    const LowerMap &lower,
kpeter@2573
   224
                    const CapacityMap &capacity,
kpeter@2573
   225
                    const CostMap &cost,
kpeter@2573
   226
                    Node s, Node t,
kpeter@2573
   227
                    Supply flow_value ) :
kpeter@2573
   228
      _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
kpeter@2581
   229
      _supply(graph), _flow(0), _local_flow(false),
kpeter@2581
   230
      _potential(0), _local_potential(false), _res_cost(_cost)
deba@2440
   231
    {
kpeter@2556
   232
      // Removing non-zero lower bounds
kpeter@2573
   233
      _capacity = subMap(capacity, lower);
kpeter@2573
   234
      for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@2573
   235
        Supply sum = 0;
kpeter@2573
   236
        if (n == s) sum =  flow_value;
kpeter@2573
   237
        if (n == t) sum = -flow_value;
kpeter@2573
   238
        for (InEdgeIt e(_graph, n); e != INVALID; ++e)
kpeter@2573
   239
          sum += lower[e];
kpeter@2573
   240
        for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
kpeter@2573
   241
          sum -= lower[e];
kpeter@2573
   242
        _supply[n] = sum;
deba@2440
   243
      }
kpeter@2573
   244
      _valid_supply = true;
deba@2440
   245
    }
deba@2440
   246
kpeter@2581
   247
    /// \brief Simple constructor (without lower bounds).
deba@2440
   248
    ///
kpeter@2581
   249
    /// Simple constructor (without lower bounds).
deba@2440
   250
    ///
kpeter@2573
   251
    /// \param graph The directed graph the algorithm runs on.
kpeter@2573
   252
    /// \param capacity The capacities (upper bounds) of the edges.
kpeter@2573
   253
    /// \param cost The cost (length) values of the edges.
kpeter@2573
   254
    /// \param s The source node.
kpeter@2573
   255
    /// \param t The target node.
kpeter@2573
   256
    /// \param flow_value The required amount of flow from node \c s
kpeter@2573
   257
    /// to node \c t (i.e. the supply of \c s and the demand of \c t).
kpeter@2573
   258
    CycleCanceling( const Graph &graph,
kpeter@2573
   259
                    const CapacityMap &capacity,
kpeter@2573
   260
                    const CostMap &cost,
kpeter@2573
   261
                    Node s, Node t,
kpeter@2573
   262
                    Supply flow_value ) :
kpeter@2573
   263
      _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
kpeter@2581
   264
      _supply(graph, 0), _flow(0), _local_flow(false),
kpeter@2581
   265
      _potential(0), _local_potential(false), _res_cost(_cost)
deba@2440
   266
    {
kpeter@2573
   267
      _supply[s] =  flow_value;
kpeter@2573
   268
      _supply[t] = -flow_value;
kpeter@2573
   269
      _valid_supply = true;
deba@2440
   270
    }
deba@2440
   271
kpeter@2581
   272
    /// Destructor.
kpeter@2581
   273
    ~CycleCanceling() {
kpeter@2581
   274
      if (_local_flow) delete _flow;
kpeter@2581
   275
      if (_local_potential) delete _potential;
kpeter@2581
   276
      delete _res_graph;
kpeter@2581
   277
    }
kpeter@2581
   278
kpeter@2620
   279
    /// \brief Set the flow map.
kpeter@2581
   280
    ///
kpeter@2620
   281
    /// Set the flow map.
kpeter@2581
   282
    ///
kpeter@2581
   283
    /// \return \c (*this)
kpeter@2581
   284
    CycleCanceling& flowMap(FlowMap &map) {
kpeter@2581
   285
      if (_local_flow) {
kpeter@2581
   286
        delete _flow;
kpeter@2581
   287
        _local_flow = false;
kpeter@2581
   288
      }
kpeter@2581
   289
      _flow = &map;
kpeter@2581
   290
      return *this;
kpeter@2581
   291
    }
kpeter@2581
   292
kpeter@2620
   293
    /// \brief Set the potential map.
kpeter@2581
   294
    ///
kpeter@2620
   295
    /// Set the potential map.
kpeter@2581
   296
    ///
kpeter@2581
   297
    /// \return \c (*this)
kpeter@2581
   298
    CycleCanceling& potentialMap(PotentialMap &map) {
kpeter@2581
   299
      if (_local_potential) {
kpeter@2581
   300
        delete _potential;
kpeter@2581
   301
        _local_potential = false;
kpeter@2581
   302
      }
kpeter@2581
   303
      _potential = &map;
kpeter@2581
   304
      return *this;
kpeter@2581
   305
    }
kpeter@2581
   306
kpeter@2581
   307
    /// \name Execution control
kpeter@2581
   308
kpeter@2581
   309
    /// @{
kpeter@2581
   310
kpeter@2620
   311
    /// \brief Run the algorithm.
kpeter@2556
   312
    ///
kpeter@2620
   313
    /// Run the algorithm.
kpeter@2556
   314
    ///
kpeter@2573
   315
    /// \param min_mean_cc Set this parameter to \c true to run the
kpeter@2573
   316
    /// "Minimum Mean Cycle-Canceling" algorithm, which is strongly
kpeter@2573
   317
    /// polynomial, but rather slower in practice.
kpeter@2573
   318
    ///
kpeter@2556
   319
    /// \return \c true if a feasible flow can be found.
kpeter@2573
   320
    bool run(bool min_mean_cc = false) {
kpeter@2573
   321
      return init() && start(min_mean_cc);
kpeter@2556
   322
    }
kpeter@2556
   323
kpeter@2581
   324
    /// @}
kpeter@2581
   325
kpeter@2581
   326
    /// \name Query Functions
kpeter@2581
   327
    /// The result of the algorithm can be obtained using these
kpeter@2620
   328
    /// functions.\n
kpeter@2620
   329
    /// \ref lemon::CycleCanceling::run() "run()" must be called before
kpeter@2620
   330
    /// using them.
kpeter@2581
   331
kpeter@2581
   332
    /// @{
kpeter@2581
   333
kpeter@2620
   334
    /// \brief Return a const reference to the edge map storing the
kpeter@2573
   335
    /// found flow.
deba@2440
   336
    ///
kpeter@2620
   337
    /// Return a const reference to the edge map storing the found flow.
deba@2440
   338
    ///
deba@2440
   339
    /// \pre \ref run() must be called before using this function.
deba@2440
   340
    const FlowMap& flowMap() const {
kpeter@2581
   341
      return *_flow;
kpeter@2581
   342
    }
kpeter@2581
   343
kpeter@2620
   344
    /// \brief Return a const reference to the node map storing the
kpeter@2581
   345
    /// found potentials (the dual solution).
kpeter@2581
   346
    ///
kpeter@2620
   347
    /// Return a const reference to the node map storing the found
kpeter@2581
   348
    /// potentials (the dual solution).
kpeter@2581
   349
    ///
kpeter@2581
   350
    /// \pre \ref run() must be called before using this function.
kpeter@2581
   351
    const PotentialMap& potentialMap() const {
kpeter@2581
   352
      return *_potential;
kpeter@2581
   353
    }
kpeter@2581
   354
kpeter@2620
   355
    /// \brief Return the flow on the given edge.
kpeter@2581
   356
    ///
kpeter@2620
   357
    /// Return the flow on the given edge.
kpeter@2581
   358
    ///
kpeter@2581
   359
    /// \pre \ref run() must be called before using this function.
kpeter@2581
   360
    Capacity flow(const Edge& edge) const {
kpeter@2581
   361
      return (*_flow)[edge];
kpeter@2581
   362
    }
kpeter@2581
   363
kpeter@2620
   364
    /// \brief Return the potential of the given node.
kpeter@2581
   365
    ///
kpeter@2620
   366
    /// Return the potential of the given node.
kpeter@2581
   367
    ///
kpeter@2581
   368
    /// \pre \ref run() must be called before using this function.
kpeter@2581
   369
    Cost potential(const Node& node) const {
kpeter@2581
   370
      return (*_potential)[node];
deba@2440
   371
    }
deba@2440
   372
kpeter@2620
   373
    /// \brief Return the total cost of the found flow.
deba@2440
   374
    ///
kpeter@2620
   375
    /// Return the total cost of the found flow. The complexity of the
deba@2440
   376
    /// function is \f$ O(e) \f$.
deba@2440
   377
    ///
deba@2440
   378
    /// \pre \ref run() must be called before using this function.
deba@2440
   379
    Cost totalCost() const {
deba@2440
   380
      Cost c = 0;
kpeter@2573
   381
      for (EdgeIt e(_graph); e != INVALID; ++e)
kpeter@2581
   382
        c += (*_flow)[e] * _cost[e];
deba@2440
   383
      return c;
deba@2440
   384
    }
deba@2440
   385
kpeter@2581
   386
    /// @}
kpeter@2581
   387
kpeter@2573
   388
  private:
deba@2440
   389
kpeter@2620
   390
    /// Initialize the algorithm.
deba@2440
   391
    bool init() {
kpeter@2573
   392
      if (!_valid_supply) return false;
deba@2440
   393
kpeter@2581
   394
      // Initializing flow and potential maps
kpeter@2581
   395
      if (!_flow) {
kpeter@2581
   396
        _flow = new FlowMap(_graph);
kpeter@2581
   397
        _local_flow = true;
kpeter@2581
   398
      }
kpeter@2581
   399
      if (!_potential) {
kpeter@2581
   400
        _potential = new PotentialMap(_graph);
kpeter@2581
   401
        _local_potential = true;
kpeter@2581
   402
      }
kpeter@2581
   403
kpeter@2581
   404
      _res_graph = new ResGraph(_graph, _capacity, *_flow);
kpeter@2581
   405
kpeter@2573
   406
      // Finding a feasible flow using Circulation
kpeter@2556
   407
      Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap,
kpeter@2556
   408
                   SupplyMap >
kpeter@2581
   409
        circulation( _graph, constMap<Edge>(Capacity(0)), _capacity,
kpeter@2573
   410
                     _supply );
kpeter@2581
   411
      return circulation.flowMap(*_flow).run();
deba@2440
   412
    }
deba@2440
   413
kpeter@2573
   414
    bool start(bool min_mean_cc) {
kpeter@2573
   415
      if (min_mean_cc)
kpeter@2581
   416
        startMinMean();
kpeter@2573
   417
      else
kpeter@2581
   418
        start();
kpeter@2581
   419
kpeter@2581
   420
      // Handling non-zero lower bounds
kpeter@2581
   421
      if (_lower) {
kpeter@2581
   422
        for (EdgeIt e(_graph); e != INVALID; ++e)
kpeter@2581
   423
          (*_flow)[e] += (*_lower)[e];
kpeter@2581
   424
      }
kpeter@2581
   425
      return true;
kpeter@2573
   426
    }
kpeter@2573
   427
kpeter@2620
   428
    /// \brief Execute the algorithm using \ref BellmanFord.
kpeter@2573
   429
    ///
kpeter@2620
   430
    /// Execute the algorithm using the \ref BellmanFord
kpeter@2573
   431
    /// "Bellman-Ford" algorithm for negative cycle detection with
kpeter@2573
   432
    /// successively larger limit for the number of iterations.
kpeter@2581
   433
    void start() {
kpeter@2581
   434
      typename BellmanFord<ResGraph, ResidualCostMap>::PredMap pred(*_res_graph);
kpeter@2581
   435
      typename ResGraph::template NodeMap<int> visited(*_res_graph);
deba@2440
   436
      std::vector<ResEdge> cycle;
kpeter@2573
   437
      int node_num = countNodes(_graph);
deba@2440
   438
kpeter@2573
   439
      int length_bound = BF_FIRST_LIMIT;
deba@2440
   440
      bool optimal = false;
deba@2440
   441
      while (!optimal) {
kpeter@2581
   442
        BellmanFord<ResGraph, ResidualCostMap> bf(*_res_graph, _res_cost);
kpeter@2556
   443
        bf.predMap(pred);
kpeter@2556
   444
        bf.init(0);
kpeter@2556
   445
        int iter_num = 0;
kpeter@2556
   446
        bool cycle_found = false;
kpeter@2556
   447
        while (!cycle_found) {
kpeter@2556
   448
          int curr_iter_num = iter_num + length_bound <= node_num ?
kpeter@2556
   449
                              length_bound : node_num - iter_num;
kpeter@2556
   450
          iter_num += curr_iter_num;
kpeter@2556
   451
          int real_iter_num = curr_iter_num;
kpeter@2556
   452
          for (int i = 0; i < curr_iter_num; ++i) {
kpeter@2556
   453
            if (bf.processNextWeakRound()) {
kpeter@2556
   454
              real_iter_num = i;
kpeter@2556
   455
              break;
kpeter@2556
   456
            }
kpeter@2556
   457
          }
kpeter@2556
   458
          if (real_iter_num < curr_iter_num) {
kpeter@2581
   459
            // Optimal flow is found
kpeter@2556
   460
            optimal = true;
kpeter@2581
   461
            // Setting node potentials
kpeter@2581
   462
            for (NodeIt n(_graph); n != INVALID; ++n)
kpeter@2581
   463
              (*_potential)[n] = bf.dist(n);
kpeter@2556
   464
            break;
kpeter@2556
   465
          } else {
kpeter@2556
   466
            // Searching for node disjoint negative cycles
kpeter@2581
   467
            for (ResNodeIt n(*_res_graph); n != INVALID; ++n)
kpeter@2556
   468
              visited[n] = 0;
kpeter@2556
   469
            int id = 0;
kpeter@2581
   470
            for (ResNodeIt n(*_res_graph); n != INVALID; ++n) {
kpeter@2556
   471
              if (visited[n] > 0) continue;
kpeter@2556
   472
              visited[n] = ++id;
kpeter@2556
   473
              ResNode u = pred[n] == INVALID ?
kpeter@2581
   474
                          INVALID : _res_graph->source(pred[n]);
kpeter@2556
   475
              while (u != INVALID && visited[u] == 0) {
kpeter@2556
   476
                visited[u] = id;
kpeter@2556
   477
                u = pred[u] == INVALID ?
kpeter@2581
   478
                    INVALID : _res_graph->source(pred[u]);
kpeter@2556
   479
              }
kpeter@2556
   480
              if (u != INVALID && visited[u] == id) {
kpeter@2556
   481
                // Finding the negative cycle
kpeter@2556
   482
                cycle_found = true;
kpeter@2556
   483
                cycle.clear();
kpeter@2556
   484
                ResEdge e = pred[u];
kpeter@2556
   485
                cycle.push_back(e);
kpeter@2581
   486
                Capacity d = _res_graph->rescap(e);
kpeter@2581
   487
                while (_res_graph->source(e) != u) {
kpeter@2581
   488
                  cycle.push_back(e = pred[_res_graph->source(e)]);
kpeter@2581
   489
                  if (_res_graph->rescap(e) < d)
kpeter@2581
   490
                    d = _res_graph->rescap(e);
kpeter@2556
   491
                }
kpeter@2573
   492
kpeter@2556
   493
                // Augmenting along the cycle
kpeter@2573
   494
                for (int i = 0; i < int(cycle.size()); ++i)
kpeter@2581
   495
                  _res_graph->augment(cycle[i], d);
kpeter@2556
   496
              }
kpeter@2556
   497
            }
kpeter@2556
   498
          }
deba@2440
   499
kpeter@2556
   500
          if (!cycle_found)
kpeter@2593
   501
            length_bound = length_bound * BF_LIMIT_FACTOR / 100;
kpeter@2556
   502
        }
deba@2440
   503
      }
deba@2440
   504
    }
deba@2440
   505
kpeter@2620
   506
    /// \brief Execute the algorithm using \ref MinMeanCycle.
kpeter@2573
   507
    ///
kpeter@2620
   508
    /// Execute the algorithm using \ref MinMeanCycle for negative
kpeter@2573
   509
    /// cycle detection.
kpeter@2581
   510
    void startMinMean() {
deba@2440
   511
      typedef Path<ResGraph> ResPath;
kpeter@2581
   512
      MinMeanCycle<ResGraph, ResidualCostMap> mmc(*_res_graph, _res_cost);
deba@2440
   513
      ResPath cycle;
deba@2440
   514
deba@2440
   515
      mmc.cyclePath(cycle).init();
deba@2440
   516
      if (mmc.findMinMean()) {
kpeter@2556
   517
        while (mmc.cycleLength() < 0) {
kpeter@2556
   518
          // Finding the cycle
kpeter@2556
   519
          mmc.findCycle();
deba@2440
   520
kpeter@2556
   521
          // Finding the largest flow amount that can be augmented
kpeter@2556
   522
          // along the cycle
kpeter@2556
   523
          Capacity delta = 0;
kpeter@2556
   524
          for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) {
kpeter@2581
   525
            if (delta == 0 || _res_graph->rescap(e) < delta)
kpeter@2581
   526
              delta = _res_graph->rescap(e);
kpeter@2556
   527
          }
deba@2440
   528
kpeter@2556
   529
          // Augmenting along the cycle
kpeter@2556
   530
          for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e)
kpeter@2581
   531
            _res_graph->augment(e, delta);
deba@2440
   532
kpeter@2556
   533
          // Finding the minimum cycle mean for the modified residual
kpeter@2556
   534
          // graph
kpeter@2556
   535
          mmc.reset();
kpeter@2556
   536
          if (!mmc.findMinMean()) break;
kpeter@2556
   537
        }
deba@2440
   538
      }
deba@2440
   539
kpeter@2581
   540
      // Computing node potentials
kpeter@2581
   541
      BellmanFord<ResGraph, ResidualCostMap> bf(*_res_graph, _res_cost);
kpeter@2581
   542
      bf.init(0); bf.start();
kpeter@2581
   543
      for (NodeIt n(_graph); n != INVALID; ++n)
kpeter@2581
   544
        (*_potential)[n] = bf.dist(n);
deba@2440
   545
    }
deba@2440
   546
deba@2440
   547
  }; //class CycleCanceling
deba@2440
   548
deba@2440
   549
  ///@}
deba@2440
   550
deba@2440
   551
} //namespace lemon
deba@2440
   552
deba@2440
   553
#endif //LEMON_CYCLE_CANCELING_H