lemon/cycle_canceling.h
author convert-repo
Thu, 04 Mar 2010 19:34:55 +0000
changeset 2659 611ced85018b
parent 2623 90defb96ee61
permissions -rw-r--r--
update tags
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@2629
   170
      _graph(graph), _lower(&lower), _capacity(capacity), _cost(cost),
kpeter@2629
   171
      _supply(supply), _flow(NULL), _local_flow(false),
kpeter@2623
   172
      _potential(NULL), _local_potential(false), _res_graph(NULL),
kpeter@2623
   173
      _res_cost(_cost)
deba@2440
   174
    {
kpeter@2629
   175
      // Check the sum of supply values
deba@2440
   176
      Supply sum = 0;
kpeter@2629
   177
      for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
kpeter@2629
   178
      _valid_supply = sum == 0;
kpeter@2629
   179
kpeter@2629
   180
      // Remove non-zero lower bounds
kpeter@2629
   181
      for (EdgeIt e(_graph); e != INVALID; ++e) {
kpeter@2629
   182
        if (lower[e] != 0) {
kpeter@2629
   183
          _capacity[e] -= lower[e];
kpeter@2629
   184
          _supply[_graph.source(e)] -= lower[e];
kpeter@2629
   185
          _supply[_graph.target(e)] += lower[e];
kpeter@2629
   186
        }
deba@2440
   187
      }
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@2623
   203
      _supply(supply), _flow(NULL), _local_flow(false),
kpeter@2623
   204
      _potential(NULL), _local_potential(false), _res_graph(NULL),
kpeter@2623
   205
      _res_cost(_cost)
deba@2440
   206
    {
kpeter@2629
   207
      // Check the sum of supply values
deba@2440
   208
      Supply sum = 0;
kpeter@2573
   209
      for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
kpeter@2573
   210
      _valid_supply = sum == 0;
deba@2440
   211
    }
deba@2440
   212
kpeter@2581
   213
    /// \brief Simple constructor (with lower bounds).
deba@2440
   214
    ///
kpeter@2581
   215
    /// Simple constructor (with lower bounds).
deba@2440
   216
    ///
kpeter@2573
   217
    /// \param graph The directed graph the algorithm runs on.
kpeter@2573
   218
    /// \param lower The lower bounds of the edges.
kpeter@2573
   219
    /// \param capacity The capacities (upper bounds) of the edges.
kpeter@2573
   220
    /// \param cost The cost (length) values of the edges.
kpeter@2573
   221
    /// \param s The source node.
kpeter@2573
   222
    /// \param t The target node.
kpeter@2573
   223
    /// \param flow_value The required amount of flow from node \c s
kpeter@2573
   224
    /// to node \c t (i.e. the supply of \c s and the demand of \c t).
kpeter@2573
   225
    CycleCanceling( const Graph &graph,
kpeter@2573
   226
                    const LowerMap &lower,
kpeter@2573
   227
                    const CapacityMap &capacity,
kpeter@2573
   228
                    const CostMap &cost,
kpeter@2573
   229
                    Node s, Node t,
kpeter@2573
   230
                    Supply flow_value ) :
kpeter@2629
   231
      _graph(graph), _lower(&lower), _capacity(capacity), _cost(cost),
kpeter@2629
   232
      _supply(graph, 0), _flow(NULL), _local_flow(false),
kpeter@2623
   233
      _potential(NULL), _local_potential(false), _res_graph(NULL),
kpeter@2623
   234
      _res_cost(_cost)
deba@2440
   235
    {
kpeter@2629
   236
      // Remove non-zero lower bounds
kpeter@2629
   237
      _supply[s] =  flow_value;
kpeter@2629
   238
      _supply[t] = -flow_value;
kpeter@2629
   239
      for (EdgeIt e(_graph); e != INVALID; ++e) {
kpeter@2629
   240
        if (lower[e] != 0) {
kpeter@2629
   241
          _capacity[e] -= lower[e];
kpeter@2629
   242
          _supply[_graph.source(e)] -= lower[e];
kpeter@2629
   243
          _supply[_graph.target(e)] += lower[e];
kpeter@2629
   244
        }
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@2623
   266
      _supply(graph, 0), _flow(NULL), _local_flow(false),
kpeter@2623
   267
      _potential(NULL), _local_potential(false), _res_graph(NULL),
kpeter@2623
   268
      _res_cost(_cost)
deba@2440
   269
    {
kpeter@2573
   270
      _supply[s] =  flow_value;
kpeter@2573
   271
      _supply[t] = -flow_value;
kpeter@2573
   272
      _valid_supply = true;
deba@2440
   273
    }
deba@2440
   274
kpeter@2581
   275
    /// Destructor.
kpeter@2581
   276
    ~CycleCanceling() {
kpeter@2581
   277
      if (_local_flow) delete _flow;
kpeter@2581
   278
      if (_local_potential) delete _potential;
kpeter@2581
   279
      delete _res_graph;
kpeter@2581
   280
    }
kpeter@2581
   281
kpeter@2620
   282
    /// \brief Set the flow map.
kpeter@2581
   283
    ///
kpeter@2620
   284
    /// Set the flow map.
kpeter@2581
   285
    ///
kpeter@2581
   286
    /// \return \c (*this)
kpeter@2581
   287
    CycleCanceling& flowMap(FlowMap &map) {
kpeter@2581
   288
      if (_local_flow) {
kpeter@2581
   289
        delete _flow;
kpeter@2581
   290
        _local_flow = false;
kpeter@2581
   291
      }
kpeter@2581
   292
      _flow = &map;
kpeter@2581
   293
      return *this;
kpeter@2581
   294
    }
kpeter@2581
   295
kpeter@2620
   296
    /// \brief Set the potential map.
kpeter@2581
   297
    ///
kpeter@2620
   298
    /// Set the potential map.
kpeter@2581
   299
    ///
kpeter@2581
   300
    /// \return \c (*this)
kpeter@2581
   301
    CycleCanceling& potentialMap(PotentialMap &map) {
kpeter@2581
   302
      if (_local_potential) {
kpeter@2581
   303
        delete _potential;
kpeter@2581
   304
        _local_potential = false;
kpeter@2581
   305
      }
kpeter@2581
   306
      _potential = &map;
kpeter@2581
   307
      return *this;
kpeter@2581
   308
    }
kpeter@2581
   309
kpeter@2581
   310
    /// \name Execution control
kpeter@2581
   311
kpeter@2581
   312
    /// @{
kpeter@2581
   313
kpeter@2620
   314
    /// \brief Run the algorithm.
kpeter@2556
   315
    ///
kpeter@2620
   316
    /// Run the algorithm.
kpeter@2556
   317
    ///
kpeter@2573
   318
    /// \param min_mean_cc Set this parameter to \c true to run the
kpeter@2573
   319
    /// "Minimum Mean Cycle-Canceling" algorithm, which is strongly
kpeter@2573
   320
    /// polynomial, but rather slower in practice.
kpeter@2573
   321
    ///
kpeter@2556
   322
    /// \return \c true if a feasible flow can be found.
kpeter@2573
   323
    bool run(bool min_mean_cc = false) {
kpeter@2573
   324
      return init() && start(min_mean_cc);
kpeter@2556
   325
    }
kpeter@2556
   326
kpeter@2581
   327
    /// @}
kpeter@2581
   328
kpeter@2581
   329
    /// \name Query Functions
kpeter@2581
   330
    /// The result of the algorithm can be obtained using these
kpeter@2620
   331
    /// functions.\n
kpeter@2620
   332
    /// \ref lemon::CycleCanceling::run() "run()" must be called before
kpeter@2620
   333
    /// using them.
kpeter@2581
   334
kpeter@2581
   335
    /// @{
kpeter@2581
   336
kpeter@2620
   337
    /// \brief Return a const reference to the edge map storing the
kpeter@2573
   338
    /// found flow.
deba@2440
   339
    ///
kpeter@2620
   340
    /// Return 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@2620
   347
    /// \brief Return a const reference to the node map storing the
kpeter@2581
   348
    /// found potentials (the dual solution).
kpeter@2581
   349
    ///
kpeter@2620
   350
    /// Return 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@2620
   358
    /// \brief Return the flow on the given edge.
kpeter@2581
   359
    ///
kpeter@2620
   360
    /// Return 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@2620
   367
    /// \brief Return the potential of the given node.
kpeter@2581
   368
    ///
kpeter@2620
   369
    /// Return 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
kpeter@2620
   376
    /// \brief Return the total cost of the found flow.
deba@2440
   377
    ///
kpeter@2620
   378
    /// Return 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@2620
   393
    /// Initialize 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@2620
   431
    /// \brief Execute the algorithm using \ref BellmanFord.
kpeter@2573
   432
    ///
kpeter@2620
   433
    /// Execute 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@2620
   509
    /// \brief Execute the algorithm using \ref MinMeanCycle.
kpeter@2573
   510
    ///
kpeter@2620
   511
    /// Execute 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