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