lemon/cycle_canceling.h
author alpar
Mon, 21 Jan 2008 15:35:55 +0000
changeset 2557 673cb4d1060b
parent 2553 bfced05fa852
child 2573 a9758ea1f01c
permissions -rw-r--r--
Reveal an existing functionality in the documentation
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
deba@2457
    25
/// \brief A 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>
deba@2440
    29
#include <lemon/circulation.h>
deba@2440
    30
deba@2457
    31
/// \brief The used cycle-canceling method.
deba@2440
    32
#define LIMITED_CYCLE_CANCELING
deba@2440
    33
//#define MIN_MEAN_CYCLE_CANCELING
deba@2440
    34
deba@2440
    35
#ifdef LIMITED_CYCLE_CANCELING
deba@2440
    36
  #include <lemon/bellman_ford.h>
kpeter@2556
    37
  // The maximum number of iterations for the first execution of the
kpeter@2556
    38
  // Bellman-Ford algorithm. It should be at least 2.
kpeter@2556
    39
  #define STARTING_LIMIT        2
kpeter@2556
    40
  // The iteration limit for the Bellman-Ford algorithm is multiplied by
kpeter@2556
    41
  // <tt>ALPHA_MUL / ALPHA_DIV</tt> in every round.
kpeter@2556
    42
  // <tt>ALPHA_MUL / ALPHA_DIV</tt> must be greater than 1.
kpeter@2556
    43
  #define ALPHA_MUL             3
kpeter@2556
    44
  #define ALPHA_DIV             2
deba@2440
    45
deba@2440
    46
//#define _ONLY_ONE_CYCLE_
deba@2457
    47
//#define _NO_BACK_STEP_
deba@2440
    48
#endif
deba@2440
    49
deba@2440
    50
#ifdef MIN_MEAN_CYCLE_CANCELING
deba@2440
    51
  #include <lemon/min_mean_cycle.h>
deba@2440
    52
  #include <lemon/path.h>
deba@2440
    53
#endif
deba@2440
    54
kpeter@2556
    55
//#define _DEBUG_ITER_
kpeter@2556
    56
deba@2440
    57
namespace lemon {
deba@2440
    58
deba@2440
    59
  /// \addtogroup min_cost_flow
deba@2440
    60
  /// @{
deba@2440
    61
kpeter@2556
    62
  /// \brief Implementation of a cycle-canceling algorithm for
kpeter@2556
    63
  /// finding a minimum cost flow.
deba@2440
    64
  ///
kpeter@2556
    65
  /// \ref CycleCanceling implements a cycle-canceling algorithm for
kpeter@2556
    66
  /// finding a minimum cost flow.
deba@2440
    67
  ///
deba@2440
    68
  /// \param Graph The directed graph type the algorithm runs on.
deba@2440
    69
  /// \param LowerMap The type of the lower bound map.
deba@2440
    70
  /// \param CapacityMap The type of the capacity (upper bound) map.
deba@2440
    71
  /// \param CostMap The type of the cost (length) map.
deba@2440
    72
  /// \param SupplyMap The type of the supply map.
deba@2440
    73
  ///
deba@2440
    74
  /// \warning
kpeter@2556
    75
  /// - Edge capacities and costs should be non-negative integers.
kpeter@2556
    76
  ///   However \c CostMap::Value should be signed type.
kpeter@2509
    77
  /// - Supply values should be signed integers.
deba@2440
    78
  /// - \c LowerMap::Value must be convertible to
kpeter@2556
    79
  ///   \c CapacityMap::Value and \c CapacityMap::Value must be
kpeter@2556
    80
  ///   convertible to \c SupplyMap::Value.
deba@2440
    81
  ///
deba@2440
    82
  /// \author Peter Kovacs
deba@2440
    83
kpeter@2533
    84
  template < typename Graph,
kpeter@2533
    85
             typename LowerMap = typename Graph::template EdgeMap<int>,
kpeter@2533
    86
             typename CapacityMap = LowerMap,
kpeter@2533
    87
             typename CostMap = typename Graph::template EdgeMap<int>,
kpeter@2533
    88
             typename SupplyMap = typename Graph::template NodeMap
kpeter@2533
    89
                                  <typename CapacityMap::Value> >
deba@2440
    90
  class CycleCanceling
deba@2440
    91
  {
kpeter@2556
    92
    GRAPH_TYPEDEFS(typename Graph);
deba@2440
    93
deba@2440
    94
    typedef typename LowerMap::Value Lower;
deba@2440
    95
    typedef typename CapacityMap::Value Capacity;
deba@2440
    96
    typedef typename CostMap::Value Cost;
deba@2440
    97
    typedef typename SupplyMap::Value Supply;
kpeter@2556
    98
    typedef typename Graph::template EdgeMap<Capacity> CapacityEdgeMap;
kpeter@2556
    99
    typedef typename Graph::template NodeMap<Supply> SupplyNodeMap;
deba@2440
   100
deba@2440
   101
    typedef ResGraphAdaptor< const Graph, Capacity,
kpeter@2556
   102
                             CapacityEdgeMap, CapacityEdgeMap > ResGraph;
deba@2440
   103
    typedef typename ResGraph::Node ResNode;
deba@2440
   104
    typedef typename ResGraph::NodeIt ResNodeIt;
deba@2440
   105
    typedef typename ResGraph::Edge ResEdge;
deba@2440
   106
    typedef typename ResGraph::EdgeIt ResEdgeIt;
deba@2440
   107
deba@2440
   108
  public:
deba@2440
   109
kpeter@2556
   110
    /// The type of the flow map.
kpeter@2556
   111
    typedef typename Graph::template EdgeMap<Capacity> FlowMap;
deba@2440
   112
deba@2440
   113
  protected:
deba@2440
   114
kpeter@2556
   115
    /// Map adaptor class for handling residual edge costs.
deba@2440
   116
    class ResCostMap : public MapBase<ResEdge, Cost>
deba@2440
   117
    {
deba@2440
   118
    private:
deba@2440
   119
deba@2440
   120
      const CostMap &cost_map;
deba@2440
   121
deba@2440
   122
    public:
deba@2440
   123
deba@2440
   124
      ResCostMap(const CostMap &_cost) : cost_map(_cost) {}
deba@2440
   125
kpeter@2509
   126
      Cost operator[](const ResEdge &e) const {
kpeter@2556
   127
        return ResGraph::forward(e) ? cost_map[e] : -cost_map[e];
deba@2440
   128
      }
deba@2440
   129
deba@2440
   130
    }; //class ResCostMap
deba@2440
   131
deba@2440
   132
  protected:
deba@2440
   133
kpeter@2556
   134
    /// The directed graph the algorithm runs on.
deba@2440
   135
    const Graph &graph;
kpeter@2556
   136
    /// The original lower bound map.
deba@2440
   137
    const LowerMap *lower;
kpeter@2556
   138
    /// The modified capacity map.
kpeter@2556
   139
    CapacityEdgeMap capacity;
kpeter@2556
   140
    /// The cost map.
deba@2440
   141
    const CostMap &cost;
kpeter@2556
   142
    /// The modified supply map.
kpeter@2556
   143
    SupplyNodeMap supply;
deba@2440
   144
    bool valid_supply;
deba@2440
   145
kpeter@2556
   146
    /// The current flow.
deba@2440
   147
    FlowMap flow;
kpeter@2556
   148
    /// The residual graph.
deba@2440
   149
    ResGraph res_graph;
kpeter@2556
   150
    /// The residual cost map.
deba@2440
   151
    ResCostMap res_cost;
deba@2440
   152
deba@2440
   153
  public :
deba@2440
   154
deba@2440
   155
    /// \brief General constructor of the class (with lower bounds).
deba@2440
   156
    ///
deba@2440
   157
    /// General constructor of the class (with lower bounds).
deba@2440
   158
    ///
deba@2440
   159
    /// \param _graph The directed graph the algorithm runs on.
deba@2440
   160
    /// \param _lower The lower bounds of the edges.
deba@2440
   161
    /// \param _capacity The capacities (upper bounds) of the edges.
deba@2440
   162
    /// \param _cost The cost (length) values of the edges.
deba@2440
   163
    /// \param _supply The supply values of the nodes (signed).
deba@2440
   164
    CycleCanceling( const Graph &_graph,
kpeter@2556
   165
                    const LowerMap &_lower,
kpeter@2556
   166
                    const CapacityMap &_capacity,
kpeter@2556
   167
                    const CostMap &_cost,
kpeter@2556
   168
                    const SupplyMap &_supply ) :
deba@2440
   169
      graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
deba@2457
   170
      supply(_graph), flow(_graph, 0),
deba@2440
   171
      res_graph(_graph, capacity, flow), res_cost(cost)
deba@2440
   172
    {
kpeter@2556
   173
      // Removing non-zero lower bounds
deba@2440
   174
      capacity = subMap(_capacity, _lower);
deba@2440
   175
      Supply sum = 0;
deba@2440
   176
      for (NodeIt n(graph); n != INVALID; ++n) {
kpeter@2556
   177
        Supply s = _supply[n];
kpeter@2556
   178
        for (InEdgeIt e(graph, n); e != INVALID; ++e)
kpeter@2556
   179
          s += _lower[e];
kpeter@2556
   180
        for (OutEdgeIt e(graph, n); e != INVALID; ++e)
kpeter@2556
   181
          s -= _lower[e];
kpeter@2556
   182
        sum += (supply[n] = s);
deba@2440
   183
      }
deba@2440
   184
      valid_supply = sum == 0;
deba@2440
   185
    }
deba@2440
   186
deba@2440
   187
    /// \brief General constructor of the class (without lower bounds).
deba@2440
   188
    ///
deba@2440
   189
    /// General constructor of the class (without lower bounds).
deba@2440
   190
    ///
deba@2440
   191
    /// \param _graph The directed graph the algorithm runs on.
deba@2440
   192
    /// \param _capacity The capacities (upper bounds) of the edges.
deba@2440
   193
    /// \param _cost The cost (length) values of the edges.
deba@2440
   194
    /// \param _supply The supply values of the nodes (signed).
deba@2440
   195
    CycleCanceling( const Graph &_graph,
kpeter@2556
   196
                    const CapacityMap &_capacity,
kpeter@2556
   197
                    const CostMap &_cost,
kpeter@2556
   198
                    const SupplyMap &_supply ) :
deba@2440
   199
      graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
deba@2457
   200
      supply(_supply), flow(_graph, 0),
deba@2440
   201
      res_graph(_graph, capacity, flow), res_cost(cost)
deba@2440
   202
    {
deba@2440
   203
      // Checking the sum of supply values
deba@2440
   204
      Supply sum = 0;
deba@2440
   205
      for (NodeIt n(graph); n != INVALID; ++n) sum += supply[n];
deba@2440
   206
      valid_supply = sum == 0;
deba@2440
   207
    }
deba@2440
   208
deba@2440
   209
    /// \brief Simple constructor of the class (with lower bounds).
deba@2440
   210
    ///
deba@2440
   211
    /// Simple constructor of the class (with lower bounds).
deba@2440
   212
    ///
deba@2440
   213
    /// \param _graph The directed graph the algorithm runs on.
deba@2440
   214
    /// \param _lower The lower bounds of the edges.
deba@2440
   215
    /// \param _capacity The capacities (upper bounds) of the edges.
deba@2440
   216
    /// \param _cost The cost (length) values of the edges.
deba@2440
   217
    /// \param _s The source node.
deba@2440
   218
    /// \param _t The target node.
deba@2440
   219
    /// \param _flow_value The required amount of flow from node \c _s
kpeter@2556
   220
    /// to node \c _t (i.e. the supply of \c _s and the demand of \c _t).
deba@2440
   221
    CycleCanceling( const Graph &_graph,
kpeter@2556
   222
                    const LowerMap &_lower,
kpeter@2556
   223
                    const CapacityMap &_capacity,
kpeter@2556
   224
                    const CostMap &_cost,
kpeter@2556
   225
                    Node _s, Node _t,
kpeter@2556
   226
                    Supply _flow_value ) :
deba@2440
   227
      graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
deba@2457
   228
      supply(_graph), flow(_graph, 0),
deba@2440
   229
      res_graph(_graph, capacity, flow), res_cost(cost)
deba@2440
   230
    {
kpeter@2556
   231
      // Removing non-zero lower bounds
deba@2440
   232
      capacity = subMap(_capacity, _lower);
deba@2440
   233
      for (NodeIt n(graph); n != INVALID; ++n) {
kpeter@2556
   234
        Supply s = 0;
kpeter@2556
   235
        if (n == _s) s =  _flow_value;
kpeter@2556
   236
        if (n == _t) s = -_flow_value;
kpeter@2556
   237
        for (InEdgeIt e(graph, n); e != INVALID; ++e)
kpeter@2556
   238
          s += _lower[e];
kpeter@2556
   239
        for (OutEdgeIt e(graph, n); e != INVALID; ++e)
kpeter@2556
   240
          s -= _lower[e];
kpeter@2556
   241
        supply[n] = s;
deba@2440
   242
      }
deba@2440
   243
      valid_supply = true;
deba@2440
   244
    }
deba@2440
   245
deba@2440
   246
    /// \brief Simple constructor of the class (without lower bounds).
deba@2440
   247
    ///
deba@2440
   248
    /// Simple constructor of the class (without lower bounds).
deba@2440
   249
    ///
deba@2440
   250
    /// \param _graph The directed graph the algorithm runs on.
deba@2440
   251
    /// \param _capacity The capacities (upper bounds) of the edges.
deba@2440
   252
    /// \param _cost The cost (length) values of the edges.
deba@2440
   253
    /// \param _s The source node.
deba@2440
   254
    /// \param _t The target node.
deba@2440
   255
    /// \param _flow_value The required amount of flow from node \c _s
kpeter@2556
   256
    /// to node \c _t (i.e. the supply of \c _s and the demand of \c _t).
deba@2440
   257
    CycleCanceling( const Graph &_graph,
kpeter@2556
   258
                    const CapacityMap &_capacity,
kpeter@2556
   259
                    const CostMap &_cost,
kpeter@2556
   260
                    Node _s, Node _t,
kpeter@2556
   261
                    Supply _flow_value ) :
deba@2440
   262
      graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
deba@2457
   263
      supply(_graph, 0), flow(_graph, 0),
deba@2440
   264
      res_graph(_graph, capacity, flow), res_cost(cost)
deba@2440
   265
    {
deba@2440
   266
      supply[_s] =  _flow_value;
deba@2440
   267
      supply[_t] = -_flow_value;
deba@2440
   268
      valid_supply = true;
deba@2440
   269
    }
deba@2440
   270
kpeter@2556
   271
    /// \brief Runs the algorithm.
kpeter@2556
   272
    ///
kpeter@2556
   273
    /// Runs the algorithm.
kpeter@2556
   274
    ///
kpeter@2556
   275
    /// \return \c true if a feasible flow can be found.
kpeter@2556
   276
    bool run() {
kpeter@2556
   277
      return init() && start();
kpeter@2556
   278
    }
kpeter@2556
   279
deba@2440
   280
    /// \brief Returns a const reference to the flow map.
deba@2440
   281
    ///
deba@2440
   282
    /// Returns a const reference to the flow map.
deba@2440
   283
    ///
deba@2440
   284
    /// \pre \ref run() must be called before using this function.
deba@2440
   285
    const FlowMap& flowMap() const {
deba@2440
   286
      return flow;
deba@2440
   287
    }
deba@2440
   288
deba@2440
   289
    /// \brief Returns the total cost of the found flow.
deba@2440
   290
    ///
deba@2440
   291
    /// Returns the total cost of the found flow. The complexity of the
deba@2440
   292
    /// function is \f$ O(e) \f$.
deba@2440
   293
    ///
deba@2440
   294
    /// \pre \ref run() must be called before using this function.
deba@2440
   295
    Cost totalCost() const {
deba@2440
   296
      Cost c = 0;
deba@2440
   297
      for (EdgeIt e(graph); e != INVALID; ++e)
kpeter@2556
   298
        c += flow[e] * cost[e];
deba@2440
   299
      return c;
deba@2440
   300
    }
deba@2440
   301
deba@2440
   302
  protected:
deba@2440
   303
kpeter@2556
   304
    /// Initializes the algorithm.
deba@2440
   305
    bool init() {
deba@2440
   306
      // Checking the sum of supply values
deba@2440
   307
      Supply sum = 0;
deba@2440
   308
      for (NodeIt n(graph); n != INVALID; ++n) sum += supply[n];
deba@2440
   309
      if (sum != 0) return false;
deba@2440
   310
deba@2440
   311
      // Finding a feasible flow
kpeter@2556
   312
      Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap,
kpeter@2556
   313
                   SupplyMap >
kpeter@2556
   314
        circulation( graph, constMap<Edge>((Capacity)0), capacity,
kpeter@2556
   315
                     supply );
kpeter@2533
   316
      circulation.flowMap(flow);
kpeter@2544
   317
      return circulation.run();
deba@2440
   318
    }
deba@2440
   319
deba@2440
   320
#ifdef LIMITED_CYCLE_CANCELING
deba@2457
   321
    /// \brief Executes a cycle-canceling algorithm using
kpeter@2556
   322
    /// \ref Bellman-Ford algorithm with limited iteration count.
deba@2440
   323
    bool start() {
deba@2440
   324
      typename BellmanFord<ResGraph, ResCostMap>::PredMap pred(res_graph);
deba@2440
   325
      typename ResGraph::template NodeMap<int> visited(res_graph);
deba@2440
   326
      std::vector<ResEdge> cycle;
deba@2440
   327
      int node_num = countNodes(graph);
deba@2440
   328
deba@2440
   329
#ifdef _DEBUG_ITER_
deba@2440
   330
      int cycle_num = 0;
deba@2440
   331
#endif
deba@2440
   332
      int length_bound = STARTING_LIMIT;
deba@2440
   333
      bool optimal = false;
deba@2440
   334
      while (!optimal) {
kpeter@2556
   335
        BellmanFord<ResGraph, ResCostMap> bf(res_graph, res_cost);
kpeter@2556
   336
        bf.predMap(pred);
kpeter@2556
   337
        bf.init(0);
kpeter@2556
   338
        int iter_num = 0;
kpeter@2556
   339
        bool cycle_found = false;
kpeter@2556
   340
        while (!cycle_found) {
deba@2457
   341
#ifdef _NO_BACK_STEP_
kpeter@2556
   342
          int curr_iter_num = length_bound <= node_num ?
kpeter@2556
   343
                              length_bound - iter_num : node_num - iter_num;
deba@2457
   344
#else
kpeter@2556
   345
          int curr_iter_num = iter_num + length_bound <= node_num ?
kpeter@2556
   346
                              length_bound : node_num - iter_num;
deba@2457
   347
#endif
kpeter@2556
   348
          iter_num += curr_iter_num;
kpeter@2556
   349
          int real_iter_num = curr_iter_num;
kpeter@2556
   350
          for (int i = 0; i < curr_iter_num; ++i) {
kpeter@2556
   351
            if (bf.processNextWeakRound()) {
kpeter@2556
   352
              real_iter_num = i;
kpeter@2556
   353
              break;
kpeter@2556
   354
            }
kpeter@2556
   355
          }
kpeter@2556
   356
          if (real_iter_num < curr_iter_num) {
kpeter@2556
   357
            optimal = true;
kpeter@2556
   358
            break;
kpeter@2556
   359
          } else {
kpeter@2556
   360
            // Searching for node disjoint negative cycles
kpeter@2556
   361
            for (ResNodeIt n(res_graph); n != INVALID; ++n)
kpeter@2556
   362
              visited[n] = 0;
kpeter@2556
   363
            int id = 0;
kpeter@2556
   364
            for (ResNodeIt n(res_graph); n != INVALID; ++n) {
kpeter@2556
   365
              if (visited[n] > 0) continue;
kpeter@2556
   366
              visited[n] = ++id;
kpeter@2556
   367
              ResNode u = pred[n] == INVALID ?
kpeter@2556
   368
                          INVALID : res_graph.source(pred[n]);
kpeter@2556
   369
              while (u != INVALID && visited[u] == 0) {
kpeter@2556
   370
                visited[u] = id;
kpeter@2556
   371
                u = pred[u] == INVALID ?
kpeter@2556
   372
                    INVALID : res_graph.source(pred[u]);
kpeter@2556
   373
              }
kpeter@2556
   374
              if (u != INVALID && visited[u] == id) {
kpeter@2556
   375
                // Finding the negative cycle
kpeter@2556
   376
                cycle_found = true;
kpeter@2556
   377
                cycle.clear();
kpeter@2556
   378
                ResEdge e = pred[u];
kpeter@2556
   379
                cycle.push_back(e);
kpeter@2556
   380
                Capacity d = res_graph.rescap(e);
kpeter@2556
   381
                while (res_graph.source(e) != u) {
kpeter@2556
   382
                  cycle.push_back(e = pred[res_graph.source(e)]);
kpeter@2556
   383
                  if (res_graph.rescap(e) < d)
kpeter@2556
   384
                    d = res_graph.rescap(e);
kpeter@2556
   385
                }
deba@2440
   386
#ifdef _DEBUG_ITER_
kpeter@2556
   387
                ++cycle_num;
deba@2440
   388
#endif
kpeter@2556
   389
                // Augmenting along the cycle
kpeter@2556
   390
                for (int i = 0; i < cycle.size(); ++i)
kpeter@2556
   391
                  res_graph.augment(cycle[i], d);
deba@2440
   392
#ifdef _ONLY_ONE_CYCLE_
kpeter@2556
   393
                break;
deba@2440
   394
#endif
kpeter@2556
   395
              }
kpeter@2556
   396
            }
kpeter@2556
   397
          }
deba@2440
   398
kpeter@2556
   399
          if (!cycle_found)
kpeter@2556
   400
            length_bound = length_bound * ALPHA_MUL / ALPHA_DIV;
kpeter@2556
   401
        }
deba@2440
   402
      }
deba@2440
   403
deba@2440
   404
#ifdef _DEBUG_ITER_
deba@2457
   405
      std::cout << "Limited cycle-canceling algorithm finished. "
kpeter@2556
   406
                << "Found " << cycle_num << " negative cycles."
kpeter@2556
   407
                << std::endl;
deba@2440
   408
#endif
deba@2440
   409
kpeter@2556
   410
      // Handling non-zero lower bounds
deba@2440
   411
      if (lower) {
kpeter@2556
   412
        for (EdgeIt e(graph); e != INVALID; ++e)
kpeter@2556
   413
          flow[e] += (*lower)[e];
deba@2440
   414
      }
deba@2440
   415
      return true;
deba@2440
   416
    }
deba@2440
   417
#endif
deba@2440
   418
deba@2440
   419
#ifdef MIN_MEAN_CYCLE_CANCELING
deba@2457
   420
    /// \brief Executes the minimum mean cycle-canceling algorithm
kpeter@2556
   421
    /// using \ref MinMeanCycle.
deba@2440
   422
    bool start() {
deba@2440
   423
      typedef Path<ResGraph> ResPath;
deba@2440
   424
      MinMeanCycle<ResGraph, ResCostMap> mmc(res_graph, res_cost);
deba@2440
   425
      ResPath cycle;
deba@2440
   426
deba@2440
   427
#ifdef _DEBUG_ITER_
deba@2440
   428
      int cycle_num = 0;
deba@2440
   429
#endif
deba@2440
   430
      mmc.cyclePath(cycle).init();
deba@2440
   431
      if (mmc.findMinMean()) {
kpeter@2556
   432
        while (mmc.cycleLength() < 0) {
deba@2440
   433
#ifdef _DEBUG_ITER_
kpeter@2556
   434
          ++cycle_num;
deba@2440
   435
#endif
kpeter@2556
   436
          // Finding the cycle
kpeter@2556
   437
          mmc.findCycle();
deba@2440
   438
kpeter@2556
   439
          // Finding the largest flow amount that can be augmented
kpeter@2556
   440
          // along the cycle
kpeter@2556
   441
          Capacity delta = 0;
kpeter@2556
   442
          for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) {
kpeter@2556
   443
            if (delta == 0 || res_graph.rescap(e) < delta)
kpeter@2556
   444
              delta = res_graph.rescap(e);
kpeter@2556
   445
          }
deba@2440
   446
kpeter@2556
   447
          // Augmenting along the cycle
kpeter@2556
   448
          for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e)
kpeter@2556
   449
            res_graph.augment(e, delta);
deba@2440
   450
kpeter@2556
   451
          // Finding the minimum cycle mean for the modified residual
kpeter@2556
   452
          // graph
kpeter@2556
   453
          mmc.reset();
kpeter@2556
   454
          if (!mmc.findMinMean()) break;
kpeter@2556
   455
        }
deba@2440
   456
      }
deba@2440
   457
deba@2440
   458
#ifdef _DEBUG_ITER_
deba@2457
   459
      std::cout << "Minimum mean cycle-canceling algorithm finished. "
kpeter@2556
   460
                << "Found " << cycle_num << " negative cycles."
kpeter@2556
   461
                << std::endl;
deba@2440
   462
#endif
deba@2440
   463
kpeter@2556
   464
      // Handling non-zero lower bounds
deba@2440
   465
      if (lower) {
kpeter@2556
   466
        for (EdgeIt e(graph); e != INVALID; ++e)
kpeter@2556
   467
          flow[e] += (*lower)[e];
deba@2440
   468
      }
deba@2440
   469
      return true;
deba@2440
   470
    }
deba@2440
   471
#endif
deba@2440
   472
deba@2440
   473
  }; //class CycleCanceling
deba@2440
   474
deba@2440
   475
  ///@}
deba@2440
   476
deba@2440
   477
} //namespace lemon
deba@2440
   478
deba@2440
   479
#endif //LEMON_CYCLE_CANCELING_H