lemon/preflow.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 891 bb70ad62c95f
parent 688 1f08e846df29
child 892 a22b3f1bf83e
child 923 30d5f950aa5f
permissions -rw-r--r--
Fix critical bug in preflow (#372)

The wrong transition between the bound decrease and highest active
heuristics caused the bug. The last node chosen in bound decrease mode
is used in the first iteration in highest active mode.
alpar@389
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@389
     2
 *
alpar@389
     3
 * This file is a part of LEMON, a generic C++ optimization library.
alpar@389
     4
 *
alpar@440
     5
 * Copyright (C) 2003-2009
alpar@389
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@389
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@389
     8
 *
alpar@389
     9
 * Permission to use, modify and distribute this software is granted
alpar@389
    10
 * provided that this copyright notice appears in all copies. For
alpar@389
    11
 * precise terms see the accompanying LICENSE file.
alpar@389
    12
 *
alpar@389
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@389
    14
 * express or implied, and with no claim as to its suitability for any
alpar@389
    15
 * purpose.
alpar@389
    16
 *
alpar@389
    17
 */
alpar@389
    18
alpar@389
    19
#ifndef LEMON_PREFLOW_H
alpar@389
    20
#define LEMON_PREFLOW_H
alpar@389
    21
alpar@389
    22
#include <lemon/tolerance.h>
alpar@389
    23
#include <lemon/elevator.h>
alpar@389
    24
alpar@389
    25
/// \file
alpar@389
    26
/// \ingroup max_flow
alpar@389
    27
/// \brief Implementation of the preflow algorithm.
alpar@389
    28
alpar@389
    29
namespace lemon {
alpar@389
    30
alpar@389
    31
  /// \brief Default traits class of Preflow class.
alpar@389
    32
  ///
alpar@389
    33
  /// Default traits class of Preflow class.
kpeter@503
    34
  /// \tparam GR Digraph type.
kpeter@559
    35
  /// \tparam CAP Capacity map type.
kpeter@559
    36
  template <typename GR, typename CAP>
alpar@389
    37
  struct PreflowDefaultTraits {
alpar@389
    38
kpeter@393
    39
    /// \brief The type of the digraph the algorithm runs on.
kpeter@503
    40
    typedef GR Digraph;
alpar@389
    41
alpar@389
    42
    /// \brief The type of the map that stores the arc capacities.
alpar@389
    43
    ///
alpar@389
    44
    /// The type of the map that stores the arc capacities.
alpar@389
    45
    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
kpeter@559
    46
    typedef CAP CapacityMap;
alpar@389
    47
kpeter@393
    48
    /// \brief The type of the flow values.
kpeter@641
    49
    typedef typename CapacityMap::Value Value;
alpar@389
    50
kpeter@393
    51
    /// \brief The type of the map that stores the flow values.
alpar@389
    52
    ///
kpeter@393
    53
    /// The type of the map that stores the flow values.
alpar@389
    54
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
kpeter@641
    55
    typedef typename Digraph::template ArcMap<Value> FlowMap;
alpar@389
    56
alpar@389
    57
    /// \brief Instantiates a FlowMap.
alpar@389
    58
    ///
alpar@389
    59
    /// This function instantiates a \ref FlowMap.
kpeter@610
    60
    /// \param digraph The digraph for which we would like to define
alpar@389
    61
    /// the flow map.
alpar@389
    62
    static FlowMap* createFlowMap(const Digraph& digraph) {
alpar@389
    63
      return new FlowMap(digraph);
alpar@389
    64
    }
alpar@389
    65
kpeter@393
    66
    /// \brief The elevator type used by Preflow algorithm.
alpar@389
    67
    ///
alpar@389
    68
    /// The elevator type used by Preflow algorithm.
alpar@389
    69
    ///
alpar@389
    70
    /// \sa Elevator
alpar@389
    71
    /// \sa LinkedElevator
alpar@389
    72
    typedef LinkedElevator<Digraph, typename Digraph::Node> Elevator;
alpar@389
    73
alpar@389
    74
    /// \brief Instantiates an Elevator.
alpar@389
    75
    ///
kpeter@393
    76
    /// This function instantiates an \ref Elevator.
kpeter@610
    77
    /// \param digraph The digraph for which we would like to define
alpar@389
    78
    /// the elevator.
alpar@389
    79
    /// \param max_level The maximum level of the elevator.
alpar@389
    80
    static Elevator* createElevator(const Digraph& digraph, int max_level) {
alpar@389
    81
      return new Elevator(digraph, max_level);
alpar@389
    82
    }
alpar@389
    83
alpar@389
    84
    /// \brief The tolerance used by the algorithm
alpar@389
    85
    ///
alpar@389
    86
    /// The tolerance used by the algorithm to handle inexact computation.
kpeter@641
    87
    typedef lemon::Tolerance<Value> Tolerance;
alpar@389
    88
alpar@389
    89
  };
alpar@389
    90
alpar@389
    91
alpar@389
    92
  /// \ingroup max_flow
alpar@389
    93
  ///
kpeter@393
    94
  /// \brief %Preflow algorithm class.
alpar@389
    95
  ///
kpeter@393
    96
  /// This class provides an implementation of Goldberg-Tarjan's \e preflow
kpeter@559
    97
  /// \e push-relabel algorithm producing a \ref max_flow
kpeter@559
    98
  /// "flow of maximum value" in a digraph.
kpeter@559
    99
  /// The preflow algorithms are the fastest known maximum
alpar@389
   100
  /// flow algorithms. The current implementation use a mixture of the
alpar@389
   101
  /// \e "highest label" and the \e "bound decrease" heuristics.
alpar@389
   102
  /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
alpar@389
   103
  ///
kpeter@393
   104
  /// The algorithm consists of two phases. After the first phase
kpeter@393
   105
  /// the maximum flow value and the minimum cut is obtained. The
kpeter@393
   106
  /// second phase constructs a feasible maximum flow on each arc.
alpar@389
   107
  ///
kpeter@503
   108
  /// \tparam GR The type of the digraph the algorithm runs on.
kpeter@559
   109
  /// \tparam CAP The type of the capacity map. The default map
kpeter@503
   110
  /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
alpar@389
   111
#ifdef DOXYGEN
kpeter@559
   112
  template <typename GR, typename CAP, typename TR>
alpar@389
   113
#else
kpeter@503
   114
  template <typename GR,
kpeter@559
   115
            typename CAP = typename GR::template ArcMap<int>,
kpeter@559
   116
            typename TR = PreflowDefaultTraits<GR, CAP> >
alpar@389
   117
#endif
alpar@389
   118
  class Preflow {
alpar@389
   119
  public:
alpar@389
   120
kpeter@393
   121
    ///The \ref PreflowDefaultTraits "traits class" of the algorithm.
kpeter@503
   122
    typedef TR Traits;
kpeter@393
   123
    ///The type of the digraph the algorithm runs on.
alpar@389
   124
    typedef typename Traits::Digraph Digraph;
kpeter@393
   125
    ///The type of the capacity map.
alpar@389
   126
    typedef typename Traits::CapacityMap CapacityMap;
kpeter@393
   127
    ///The type of the flow values.
kpeter@641
   128
    typedef typename Traits::Value Value;
alpar@389
   129
kpeter@393
   130
    ///The type of the flow map.
alpar@389
   131
    typedef typename Traits::FlowMap FlowMap;
kpeter@393
   132
    ///The type of the elevator.
alpar@389
   133
    typedef typename Traits::Elevator Elevator;
kpeter@393
   134
    ///The type of the tolerance.
alpar@389
   135
    typedef typename Traits::Tolerance Tolerance;
alpar@389
   136
alpar@389
   137
  private:
alpar@389
   138
alpar@389
   139
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
alpar@389
   140
alpar@389
   141
    const Digraph& _graph;
alpar@389
   142
    const CapacityMap* _capacity;
alpar@389
   143
alpar@389
   144
    int _node_num;
alpar@389
   145
alpar@389
   146
    Node _source, _target;
alpar@389
   147
alpar@389
   148
    FlowMap* _flow;
alpar@389
   149
    bool _local_flow;
alpar@389
   150
alpar@389
   151
    Elevator* _level;
alpar@389
   152
    bool _local_level;
alpar@389
   153
kpeter@641
   154
    typedef typename Digraph::template NodeMap<Value> ExcessMap;
alpar@389
   155
    ExcessMap* _excess;
alpar@389
   156
alpar@389
   157
    Tolerance _tolerance;
alpar@389
   158
alpar@389
   159
    bool _phase;
alpar@389
   160
alpar@389
   161
alpar@389
   162
    void createStructures() {
alpar@389
   163
      _node_num = countNodes(_graph);
alpar@389
   164
alpar@389
   165
      if (!_flow) {
alpar@389
   166
        _flow = Traits::createFlowMap(_graph);
alpar@389
   167
        _local_flow = true;
alpar@389
   168
      }
alpar@389
   169
      if (!_level) {
alpar@389
   170
        _level = Traits::createElevator(_graph, _node_num);
alpar@389
   171
        _local_level = true;
alpar@389
   172
      }
alpar@389
   173
      if (!_excess) {
alpar@389
   174
        _excess = new ExcessMap(_graph);
alpar@389
   175
      }
alpar@389
   176
    }
alpar@389
   177
alpar@389
   178
    void destroyStructures() {
alpar@389
   179
      if (_local_flow) {
alpar@389
   180
        delete _flow;
alpar@389
   181
      }
alpar@389
   182
      if (_local_level) {
alpar@389
   183
        delete _level;
alpar@389
   184
      }
alpar@389
   185
      if (_excess) {
alpar@389
   186
        delete _excess;
alpar@389
   187
      }
alpar@389
   188
    }
alpar@389
   189
alpar@389
   190
  public:
alpar@389
   191
alpar@389
   192
    typedef Preflow Create;
alpar@389
   193
kpeter@393
   194
    ///\name Named Template Parameters
alpar@389
   195
alpar@389
   196
    ///@{
alpar@389
   197
kpeter@559
   198
    template <typename T>
alpar@391
   199
    struct SetFlowMapTraits : public Traits {
kpeter@559
   200
      typedef T FlowMap;
alpar@389
   201
      static FlowMap *createFlowMap(const Digraph&) {
alpar@390
   202
        LEMON_ASSERT(false, "FlowMap is not initialized");
alpar@390
   203
        return 0; // ignore warnings
alpar@389
   204
      }
alpar@389
   205
    };
alpar@389
   206
alpar@389
   207
    /// \brief \ref named-templ-param "Named parameter" for setting
alpar@389
   208
    /// FlowMap type
alpar@389
   209
    ///
alpar@389
   210
    /// \ref named-templ-param "Named parameter" for setting FlowMap
kpeter@393
   211
    /// type.
kpeter@559
   212
    template <typename T>
alpar@391
   213
    struct SetFlowMap
kpeter@559
   214
      : public Preflow<Digraph, CapacityMap, SetFlowMapTraits<T> > {
alpar@389
   215
      typedef Preflow<Digraph, CapacityMap,
kpeter@559
   216
                      SetFlowMapTraits<T> > Create;
alpar@389
   217
    };
alpar@389
   218
kpeter@559
   219
    template <typename T>
alpar@391
   220
    struct SetElevatorTraits : public Traits {
kpeter@559
   221
      typedef T Elevator;
alpar@389
   222
      static Elevator *createElevator(const Digraph&, int) {
alpar@390
   223
        LEMON_ASSERT(false, "Elevator is not initialized");
alpar@390
   224
        return 0; // ignore warnings
alpar@389
   225
      }
alpar@389
   226
    };
alpar@389
   227
alpar@389
   228
    /// \brief \ref named-templ-param "Named parameter" for setting
alpar@389
   229
    /// Elevator type
alpar@389
   230
    ///
alpar@389
   231
    /// \ref named-templ-param "Named parameter" for setting Elevator
kpeter@393
   232
    /// type. If this named parameter is used, then an external
kpeter@393
   233
    /// elevator object must be passed to the algorithm using the
kpeter@393
   234
    /// \ref elevator(Elevator&) "elevator()" function before calling
kpeter@393
   235
    /// \ref run() or \ref init().
kpeter@393
   236
    /// \sa SetStandardElevator
kpeter@559
   237
    template <typename T>
alpar@391
   238
    struct SetElevator
kpeter@559
   239
      : public Preflow<Digraph, CapacityMap, SetElevatorTraits<T> > {
alpar@389
   240
      typedef Preflow<Digraph, CapacityMap,
kpeter@559
   241
                      SetElevatorTraits<T> > Create;
alpar@389
   242
    };
alpar@389
   243
kpeter@559
   244
    template <typename T>
alpar@391
   245
    struct SetStandardElevatorTraits : public Traits {
kpeter@559
   246
      typedef T Elevator;
alpar@389
   247
      static Elevator *createElevator(const Digraph& digraph, int max_level) {
alpar@389
   248
        return new Elevator(digraph, max_level);
alpar@389
   249
      }
alpar@389
   250
    };
alpar@389
   251
alpar@389
   252
    /// \brief \ref named-templ-param "Named parameter" for setting
kpeter@393
   253
    /// Elevator type with automatic allocation
alpar@389
   254
    ///
alpar@389
   255
    /// \ref named-templ-param "Named parameter" for setting Elevator
kpeter@393
   256
    /// type with automatic allocation.
kpeter@393
   257
    /// The Elevator should have standard constructor interface to be
kpeter@393
   258
    /// able to automatically created by the algorithm (i.e. the
kpeter@393
   259
    /// digraph and the maximum level should be passed to it).
kpeter@393
   260
    /// However an external elevator object could also be passed to the
kpeter@393
   261
    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
kpeter@393
   262
    /// before calling \ref run() or \ref init().
kpeter@393
   263
    /// \sa SetElevator
kpeter@559
   264
    template <typename T>
alpar@391
   265
    struct SetStandardElevator
alpar@389
   266
      : public Preflow<Digraph, CapacityMap,
kpeter@559
   267
                       SetStandardElevatorTraits<T> > {
alpar@389
   268
      typedef Preflow<Digraph, CapacityMap,
kpeter@559
   269
                      SetStandardElevatorTraits<T> > Create;
alpar@389
   270
    };
alpar@389
   271
alpar@389
   272
    /// @}
alpar@389
   273
alpar@389
   274
  protected:
alpar@389
   275
alpar@389
   276
    Preflow() {}
alpar@389
   277
alpar@389
   278
  public:
alpar@389
   279
alpar@389
   280
alpar@389
   281
    /// \brief The constructor of the class.
alpar@389
   282
    ///
alpar@389
   283
    /// The constructor of the class.
alpar@389
   284
    /// \param digraph The digraph the algorithm runs on.
alpar@389
   285
    /// \param capacity The capacity of the arcs.
alpar@389
   286
    /// \param source The source node.
alpar@389
   287
    /// \param target The target node.
alpar@389
   288
    Preflow(const Digraph& digraph, const CapacityMap& capacity,
kpeter@393
   289
            Node source, Node target)
alpar@389
   290
      : _graph(digraph), _capacity(&capacity),
alpar@389
   291
        _node_num(0), _source(source), _target(target),
alpar@389
   292
        _flow(0), _local_flow(false),
alpar@389
   293
        _level(0), _local_level(false),
alpar@389
   294
        _excess(0), _tolerance(), _phase() {}
alpar@389
   295
kpeter@393
   296
    /// \brief Destructor.
alpar@389
   297
    ///
alpar@389
   298
    /// Destructor.
alpar@389
   299
    ~Preflow() {
alpar@389
   300
      destroyStructures();
alpar@389
   301
    }
alpar@389
   302
alpar@389
   303
    /// \brief Sets the capacity map.
alpar@389
   304
    ///
alpar@389
   305
    /// Sets the capacity map.
kpeter@393
   306
    /// \return <tt>(*this)</tt>
alpar@389
   307
    Preflow& capacityMap(const CapacityMap& map) {
alpar@389
   308
      _capacity = &map;
alpar@389
   309
      return *this;
alpar@389
   310
    }
alpar@389
   311
alpar@389
   312
    /// \brief Sets the flow map.
alpar@389
   313
    ///
alpar@389
   314
    /// Sets the flow map.
kpeter@393
   315
    /// If you don't use this function before calling \ref run() or
kpeter@393
   316
    /// \ref init(), an instance will be allocated automatically.
kpeter@393
   317
    /// The destructor deallocates this automatically allocated map,
kpeter@393
   318
    /// of course.
kpeter@393
   319
    /// \return <tt>(*this)</tt>
alpar@389
   320
    Preflow& flowMap(FlowMap& map) {
alpar@389
   321
      if (_local_flow) {
alpar@389
   322
        delete _flow;
alpar@389
   323
        _local_flow = false;
alpar@389
   324
      }
alpar@389
   325
      _flow = &map;
alpar@389
   326
      return *this;
alpar@389
   327
    }
alpar@389
   328
kpeter@393
   329
    /// \brief Sets the source node.
alpar@389
   330
    ///
kpeter@393
   331
    /// Sets the source node.
kpeter@393
   332
    /// \return <tt>(*this)</tt>
kpeter@393
   333
    Preflow& source(const Node& node) {
kpeter@393
   334
      _source = node;
kpeter@393
   335
      return *this;
alpar@389
   336
    }
alpar@389
   337
kpeter@393
   338
    /// \brief Sets the target node.
alpar@389
   339
    ///
kpeter@393
   340
    /// Sets the target node.
kpeter@393
   341
    /// \return <tt>(*this)</tt>
kpeter@393
   342
    Preflow& target(const Node& node) {
kpeter@393
   343
      _target = node;
kpeter@393
   344
      return *this;
kpeter@393
   345
    }
kpeter@393
   346
kpeter@393
   347
    /// \brief Sets the elevator used by algorithm.
kpeter@393
   348
    ///
kpeter@393
   349
    /// Sets the elevator used by algorithm.
kpeter@393
   350
    /// If you don't use this function before calling \ref run() or
kpeter@393
   351
    /// \ref init(), an instance will be allocated automatically.
kpeter@393
   352
    /// The destructor deallocates this automatically allocated elevator,
kpeter@393
   353
    /// of course.
kpeter@393
   354
    /// \return <tt>(*this)</tt>
alpar@389
   355
    Preflow& elevator(Elevator& elevator) {
alpar@389
   356
      if (_local_level) {
alpar@389
   357
        delete _level;
alpar@389
   358
        _local_level = false;
alpar@389
   359
      }
alpar@389
   360
      _level = &elevator;
alpar@389
   361
      return *this;
alpar@389
   362
    }
alpar@389
   363
kpeter@393
   364
    /// \brief Returns a const reference to the elevator.
alpar@389
   365
    ///
kpeter@393
   366
    /// Returns a const reference to the elevator.
kpeter@393
   367
    ///
kpeter@393
   368
    /// \pre Either \ref run() or \ref init() must be called before
kpeter@393
   369
    /// using this function.
kpeter@420
   370
    const Elevator& elevator() const {
alpar@389
   371
      return *_level;
alpar@389
   372
    }
alpar@389
   373
alpar@389
   374
    /// \brief Sets the tolerance used by algorithm.
alpar@389
   375
    ///
alpar@389
   376
    /// Sets the tolerance used by algorithm.
kpeter@688
   377
    Preflow& tolerance(const Tolerance& tolerance) {
alpar@389
   378
      _tolerance = tolerance;
alpar@389
   379
      return *this;
alpar@389
   380
    }
alpar@389
   381
kpeter@393
   382
    /// \brief Returns a const reference to the tolerance.
alpar@389
   383
    ///
kpeter@393
   384
    /// Returns a const reference to the tolerance.
alpar@389
   385
    const Tolerance& tolerance() const {
kpeter@688
   386
      return _tolerance;
alpar@389
   387
    }
alpar@389
   388
kpeter@393
   389
    /// \name Execution Control
kpeter@393
   390
    /// The simplest way to execute the preflow algorithm is to use
kpeter@393
   391
    /// \ref run() or \ref runMinCut().\n
kpeter@393
   392
    /// If you need more control on the initial solution or the execution,
kpeter@393
   393
    /// first you have to call one of the \ref init() functions, then
kpeter@393
   394
    /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
alpar@389
   395
alpar@389
   396
    ///@{
alpar@389
   397
alpar@389
   398
    /// \brief Initializes the internal data structures.
alpar@389
   399
    ///
kpeter@393
   400
    /// Initializes the internal data structures and sets the initial
kpeter@393
   401
    /// flow to zero on each arc.
alpar@389
   402
    void init() {
alpar@389
   403
      createStructures();
alpar@389
   404
alpar@389
   405
      _phase = true;
alpar@389
   406
      for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@581
   407
        (*_excess)[n] = 0;
alpar@389
   408
      }
alpar@389
   409
alpar@389
   410
      for (ArcIt e(_graph); e != INVALID; ++e) {
alpar@389
   411
        _flow->set(e, 0);
alpar@389
   412
      }
alpar@389
   413
alpar@389
   414
      typename Digraph::template NodeMap<bool> reached(_graph, false);
alpar@389
   415
alpar@389
   416
      _level->initStart();
alpar@389
   417
      _level->initAddItem(_target);
alpar@389
   418
alpar@389
   419
      std::vector<Node> queue;
kpeter@581
   420
      reached[_source] = true;
alpar@389
   421
alpar@389
   422
      queue.push_back(_target);
kpeter@581
   423
      reached[_target] = true;
alpar@389
   424
      while (!queue.empty()) {
alpar@389
   425
        _level->initNewLevel();
alpar@389
   426
        std::vector<Node> nqueue;
alpar@389
   427
        for (int i = 0; i < int(queue.size()); ++i) {
alpar@389
   428
          Node n = queue[i];
alpar@389
   429
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
alpar@389
   430
            Node u = _graph.source(e);
alpar@389
   431
            if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
kpeter@581
   432
              reached[u] = true;
alpar@389
   433
              _level->initAddItem(u);
alpar@389
   434
              nqueue.push_back(u);
alpar@389
   435
            }
alpar@389
   436
          }
alpar@389
   437
        }
alpar@389
   438
        queue.swap(nqueue);
alpar@389
   439
      }
alpar@389
   440
      _level->initFinish();
alpar@389
   441
alpar@389
   442
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
alpar@389
   443
        if (_tolerance.positive((*_capacity)[e])) {
alpar@389
   444
          Node u = _graph.target(e);
alpar@389
   445
          if ((*_level)[u] == _level->maxLevel()) continue;
alpar@389
   446
          _flow->set(e, (*_capacity)[e]);
kpeter@581
   447
          (*_excess)[u] += (*_capacity)[e];
alpar@389
   448
          if (u != _target && !_level->active(u)) {
alpar@389
   449
            _level->activate(u);
alpar@389
   450
          }
alpar@389
   451
        }
alpar@389
   452
      }
alpar@389
   453
    }
alpar@389
   454
kpeter@393
   455
    /// \brief Initializes the internal data structures using the
kpeter@393
   456
    /// given flow map.
alpar@389
   457
    ///
alpar@389
   458
    /// Initializes the internal data structures and sets the initial
alpar@389
   459
    /// flow to the given \c flowMap. The \c flowMap should contain a
kpeter@393
   460
    /// flow or at least a preflow, i.e. at each node excluding the
kpeter@393
   461
    /// source node the incoming flow should greater or equal to the
alpar@389
   462
    /// outgoing flow.
kpeter@393
   463
    /// \return \c false if the given \c flowMap is not a preflow.
alpar@389
   464
    template <typename FlowMap>
kpeter@392
   465
    bool init(const FlowMap& flowMap) {
alpar@389
   466
      createStructures();
alpar@389
   467
alpar@389
   468
      for (ArcIt e(_graph); e != INVALID; ++e) {
alpar@389
   469
        _flow->set(e, flowMap[e]);
alpar@389
   470
      }
alpar@389
   471
alpar@389
   472
      for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@641
   473
        Value excess = 0;
alpar@389
   474
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
alpar@389
   475
          excess += (*_flow)[e];
alpar@389
   476
        }
alpar@389
   477
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
alpar@389
   478
          excess -= (*_flow)[e];
alpar@389
   479
        }
alpar@389
   480
        if (excess < 0 && n != _source) return false;
kpeter@581
   481
        (*_excess)[n] = excess;
alpar@389
   482
      }
alpar@389
   483
alpar@389
   484
      typename Digraph::template NodeMap<bool> reached(_graph, false);
alpar@389
   485
alpar@389
   486
      _level->initStart();
alpar@389
   487
      _level->initAddItem(_target);
alpar@389
   488
alpar@389
   489
      std::vector<Node> queue;
kpeter@581
   490
      reached[_source] = true;
alpar@389
   491
alpar@389
   492
      queue.push_back(_target);
kpeter@581
   493
      reached[_target] = true;
alpar@389
   494
      while (!queue.empty()) {
alpar@389
   495
        _level->initNewLevel();
alpar@389
   496
        std::vector<Node> nqueue;
alpar@389
   497
        for (int i = 0; i < int(queue.size()); ++i) {
alpar@389
   498
          Node n = queue[i];
alpar@389
   499
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
alpar@389
   500
            Node u = _graph.source(e);
alpar@389
   501
            if (!reached[u] &&
alpar@389
   502
                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
kpeter@581
   503
              reached[u] = true;
alpar@389
   504
              _level->initAddItem(u);
alpar@389
   505
              nqueue.push_back(u);
alpar@389
   506
            }
alpar@389
   507
          }
alpar@389
   508
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
alpar@389
   509
            Node v = _graph.target(e);
alpar@389
   510
            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
kpeter@581
   511
              reached[v] = true;
alpar@389
   512
              _level->initAddItem(v);
alpar@389
   513
              nqueue.push_back(v);
alpar@389
   514
            }
alpar@389
   515
          }
alpar@389
   516
        }
alpar@389
   517
        queue.swap(nqueue);
alpar@389
   518
      }
alpar@389
   519
      _level->initFinish();
alpar@389
   520
alpar@389
   521
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
kpeter@641
   522
        Value rem = (*_capacity)[e] - (*_flow)[e];
alpar@389
   523
        if (_tolerance.positive(rem)) {
alpar@389
   524
          Node u = _graph.target(e);
alpar@389
   525
          if ((*_level)[u] == _level->maxLevel()) continue;
alpar@389
   526
          _flow->set(e, (*_capacity)[e]);
kpeter@581
   527
          (*_excess)[u] += rem;
alpar@389
   528
          if (u != _target && !_level->active(u)) {
alpar@389
   529
            _level->activate(u);
alpar@389
   530
          }
alpar@389
   531
        }
alpar@389
   532
      }
alpar@389
   533
      for (InArcIt e(_graph, _source); e != INVALID; ++e) {
kpeter@641
   534
        Value rem = (*_flow)[e];
alpar@389
   535
        if (_tolerance.positive(rem)) {
alpar@389
   536
          Node v = _graph.source(e);
alpar@389
   537
          if ((*_level)[v] == _level->maxLevel()) continue;
alpar@389
   538
          _flow->set(e, 0);
kpeter@581
   539
          (*_excess)[v] += rem;
alpar@389
   540
          if (v != _target && !_level->active(v)) {
alpar@389
   541
            _level->activate(v);
alpar@389
   542
          }
alpar@389
   543
        }
alpar@389
   544
      }
alpar@389
   545
      return true;
alpar@389
   546
    }
alpar@389
   547
alpar@389
   548
    /// \brief Starts the first phase of the preflow algorithm.
alpar@389
   549
    ///
alpar@389
   550
    /// The preflow algorithm consists of two phases, this method runs
alpar@389
   551
    /// the first phase. After the first phase the maximum flow value
alpar@389
   552
    /// and a minimum value cut can already be computed, although a
alpar@389
   553
    /// maximum flow is not yet obtained. So after calling this method
alpar@389
   554
    /// \ref flowValue() returns the value of a maximum flow and \ref
alpar@389
   555
    /// minCut() returns a minimum cut.
kpeter@393
   556
    /// \pre One of the \ref init() functions must be called before
kpeter@393
   557
    /// using this function.
alpar@389
   558
    void startFirstPhase() {
alpar@389
   559
      _phase = true;
alpar@389
   560
deba@891
   561
      while (true) {
alpar@389
   562
        int num = _node_num;
alpar@389
   563
deba@891
   564
        Node n = INVALID;
deba@891
   565
        int level = -1;
deba@891
   566
deba@891
   567
        while (num > 0) {
deba@891
   568
          n = _level->highestActive();
deba@891
   569
          if (n == INVALID) goto first_phase_done;
deba@891
   570
          level = _level->highestActiveLevel();
deba@891
   571
          --num;
deba@891
   572
          
kpeter@641
   573
          Value excess = (*_excess)[n];
alpar@389
   574
          int new_level = _level->maxLevel();
alpar@389
   575
alpar@389
   576
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
kpeter@641
   577
            Value rem = (*_capacity)[e] - (*_flow)[e];
alpar@389
   578
            if (!_tolerance.positive(rem)) continue;
alpar@389
   579
            Node v = _graph.target(e);
alpar@389
   580
            if ((*_level)[v] < level) {
alpar@389
   581
              if (!_level->active(v) && v != _target) {
alpar@389
   582
                _level->activate(v);
alpar@389
   583
              }
alpar@389
   584
              if (!_tolerance.less(rem, excess)) {
alpar@389
   585
                _flow->set(e, (*_flow)[e] + excess);
kpeter@581
   586
                (*_excess)[v] += excess;
alpar@389
   587
                excess = 0;
alpar@389
   588
                goto no_more_push_1;
alpar@389
   589
              } else {
alpar@389
   590
                excess -= rem;
kpeter@581
   591
                (*_excess)[v] += rem;
alpar@389
   592
                _flow->set(e, (*_capacity)[e]);
alpar@389
   593
              }
alpar@389
   594
            } else if (new_level > (*_level)[v]) {
alpar@389
   595
              new_level = (*_level)[v];
alpar@389
   596
            }
alpar@389
   597
          }
alpar@389
   598
alpar@389
   599
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
kpeter@641
   600
            Value rem = (*_flow)[e];
alpar@389
   601
            if (!_tolerance.positive(rem)) continue;
alpar@389
   602
            Node v = _graph.source(e);
alpar@389
   603
            if ((*_level)[v] < level) {
alpar@389
   604
              if (!_level->active(v) && v != _target) {
alpar@389
   605
                _level->activate(v);
alpar@389
   606
              }
alpar@389
   607
              if (!_tolerance.less(rem, excess)) {
alpar@389
   608
                _flow->set(e, (*_flow)[e] - excess);
kpeter@581
   609
                (*_excess)[v] += excess;
alpar@389
   610
                excess = 0;
alpar@389
   611
                goto no_more_push_1;
alpar@389
   612
              } else {
alpar@389
   613
                excess -= rem;
kpeter@581
   614
                (*_excess)[v] += rem;
alpar@389
   615
                _flow->set(e, 0);
alpar@389
   616
              }
alpar@389
   617
            } else if (new_level > (*_level)[v]) {
alpar@389
   618
              new_level = (*_level)[v];
alpar@389
   619
            }
alpar@389
   620
          }
alpar@389
   621
alpar@389
   622
        no_more_push_1:
alpar@389
   623
kpeter@581
   624
          (*_excess)[n] = excess;
alpar@389
   625
alpar@389
   626
          if (excess != 0) {
alpar@389
   627
            if (new_level + 1 < _level->maxLevel()) {
alpar@389
   628
              _level->liftHighestActive(new_level + 1);
alpar@389
   629
            } else {
alpar@389
   630
              _level->liftHighestActiveToTop();
alpar@389
   631
            }
alpar@389
   632
            if (_level->emptyLevel(level)) {
alpar@389
   633
              _level->liftToTop(level);
alpar@389
   634
            }
alpar@389
   635
          } else {
alpar@389
   636
            _level->deactivate(n);
alpar@389
   637
          }
alpar@389
   638
        }
alpar@389
   639
alpar@389
   640
        num = _node_num * 20;
deba@891
   641
        while (num > 0) {
deba@891
   642
          while (level >= 0 && _level->activeFree(level)) {
deba@891
   643
            --level;
deba@891
   644
          }
deba@891
   645
          if (level == -1) {
deba@891
   646
            n = _level->highestActive();
deba@891
   647
            level = _level->highestActiveLevel();
deba@891
   648
            if (n == INVALID) goto first_phase_done;
deba@891
   649
          } else {
deba@891
   650
            n = _level->activeOn(level);
deba@891
   651
          }
deba@891
   652
          --num;
deba@891
   653
kpeter@641
   654
          Value excess = (*_excess)[n];
alpar@389
   655
          int new_level = _level->maxLevel();
alpar@389
   656
alpar@389
   657
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
kpeter@641
   658
            Value rem = (*_capacity)[e] - (*_flow)[e];
alpar@389
   659
            if (!_tolerance.positive(rem)) continue;
alpar@389
   660
            Node v = _graph.target(e);
alpar@389
   661
            if ((*_level)[v] < level) {
alpar@389
   662
              if (!_level->active(v) && v != _target) {
alpar@389
   663
                _level->activate(v);
alpar@389
   664
              }
alpar@389
   665
              if (!_tolerance.less(rem, excess)) {
alpar@389
   666
                _flow->set(e, (*_flow)[e] + excess);
kpeter@581
   667
                (*_excess)[v] += excess;
alpar@389
   668
                excess = 0;
alpar@389
   669
                goto no_more_push_2;
alpar@389
   670
              } else {
alpar@389
   671
                excess -= rem;
kpeter@581
   672
                (*_excess)[v] += rem;
alpar@389
   673
                _flow->set(e, (*_capacity)[e]);
alpar@389
   674
              }
alpar@389
   675
            } else if (new_level > (*_level)[v]) {
alpar@389
   676
              new_level = (*_level)[v];
alpar@389
   677
            }
alpar@389
   678
          }
alpar@389
   679
alpar@389
   680
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
kpeter@641
   681
            Value rem = (*_flow)[e];
alpar@389
   682
            if (!_tolerance.positive(rem)) continue;
alpar@389
   683
            Node v = _graph.source(e);
alpar@389
   684
            if ((*_level)[v] < level) {
alpar@389
   685
              if (!_level->active(v) && v != _target) {
alpar@389
   686
                _level->activate(v);
alpar@389
   687
              }
alpar@389
   688
              if (!_tolerance.less(rem, excess)) {
alpar@389
   689
                _flow->set(e, (*_flow)[e] - excess);
kpeter@581
   690
                (*_excess)[v] += excess;
alpar@389
   691
                excess = 0;
alpar@389
   692
                goto no_more_push_2;
alpar@389
   693
              } else {
alpar@389
   694
                excess -= rem;
kpeter@581
   695
                (*_excess)[v] += rem;
alpar@389
   696
                _flow->set(e, 0);
alpar@389
   697
              }
alpar@389
   698
            } else if (new_level > (*_level)[v]) {
alpar@389
   699
              new_level = (*_level)[v];
alpar@389
   700
            }
alpar@389
   701
          }
alpar@389
   702
alpar@389
   703
        no_more_push_2:
alpar@389
   704
kpeter@581
   705
          (*_excess)[n] = excess;
alpar@389
   706
alpar@389
   707
          if (excess != 0) {
alpar@389
   708
            if (new_level + 1 < _level->maxLevel()) {
alpar@389
   709
              _level->liftActiveOn(level, new_level + 1);
alpar@389
   710
            } else {
alpar@389
   711
              _level->liftActiveToTop(level);
alpar@389
   712
            }
alpar@389
   713
            if (_level->emptyLevel(level)) {
alpar@389
   714
              _level->liftToTop(level);
alpar@389
   715
            }
alpar@389
   716
          } else {
alpar@389
   717
            _level->deactivate(n);
alpar@389
   718
          }
alpar@389
   719
        }
alpar@389
   720
      }
deba@891
   721
    first_phase_done:;
alpar@389
   722
    }
alpar@389
   723
alpar@389
   724
    /// \brief Starts the second phase of the preflow algorithm.
alpar@389
   725
    ///
alpar@389
   726
    /// The preflow algorithm consists of two phases, this method runs
kpeter@393
   727
    /// the second phase. After calling one of the \ref init() functions
kpeter@393
   728
    /// and \ref startFirstPhase() and then \ref startSecondPhase(),
kpeter@393
   729
    /// \ref flowMap() returns a maximum flow, \ref flowValue() returns the
alpar@389
   730
    /// value of a maximum flow, \ref minCut() returns a minimum cut
kpeter@393
   731
    /// \pre One of the \ref init() functions and \ref startFirstPhase()
kpeter@393
   732
    /// must be called before using this function.
alpar@389
   733
    void startSecondPhase() {
alpar@389
   734
      _phase = false;
alpar@389
   735
alpar@389
   736
      typename Digraph::template NodeMap<bool> reached(_graph);
alpar@389
   737
      for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@581
   738
        reached[n] = (*_level)[n] < _level->maxLevel();
alpar@389
   739
      }
alpar@389
   740
alpar@389
   741
      _level->initStart();
alpar@389
   742
      _level->initAddItem(_source);
alpar@389
   743
alpar@389
   744
      std::vector<Node> queue;
alpar@389
   745
      queue.push_back(_source);
kpeter@581
   746
      reached[_source] = true;
alpar@389
   747
alpar@389
   748
      while (!queue.empty()) {
alpar@389
   749
        _level->initNewLevel();
alpar@389
   750
        std::vector<Node> nqueue;
alpar@389
   751
        for (int i = 0; i < int(queue.size()); ++i) {
alpar@389
   752
          Node n = queue[i];
alpar@389
   753
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
alpar@389
   754
            Node v = _graph.target(e);
alpar@389
   755
            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
kpeter@581
   756
              reached[v] = true;
alpar@389
   757
              _level->initAddItem(v);
alpar@389
   758
              nqueue.push_back(v);
alpar@389
   759
            }
alpar@389
   760
          }
alpar@389
   761
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
alpar@389
   762
            Node u = _graph.source(e);
alpar@389
   763
            if (!reached[u] &&
alpar@389
   764
                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
kpeter@581
   765
              reached[u] = true;
alpar@389
   766
              _level->initAddItem(u);
alpar@389
   767
              nqueue.push_back(u);
alpar@389
   768
            }
alpar@389
   769
          }
alpar@389
   770
        }
alpar@389
   771
        queue.swap(nqueue);
alpar@389
   772
      }
alpar@389
   773
      _level->initFinish();
alpar@389
   774
alpar@389
   775
      for (NodeIt n(_graph); n != INVALID; ++n) {
alpar@389
   776
        if (!reached[n]) {
alpar@389
   777
          _level->dirtyTopButOne(n);
alpar@389
   778
        } else if ((*_excess)[n] > 0 && _target != n) {
alpar@389
   779
          _level->activate(n);
alpar@389
   780
        }
alpar@389
   781
      }
alpar@389
   782
alpar@389
   783
      Node n;
alpar@389
   784
      while ((n = _level->highestActive()) != INVALID) {
kpeter@641
   785
        Value excess = (*_excess)[n];
alpar@389
   786
        int level = _level->highestActiveLevel();
alpar@389
   787
        int new_level = _level->maxLevel();
alpar@389
   788
alpar@389
   789
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
kpeter@641
   790
          Value rem = (*_capacity)[e] - (*_flow)[e];
alpar@389
   791
          if (!_tolerance.positive(rem)) continue;
alpar@389
   792
          Node v = _graph.target(e);
alpar@389
   793
          if ((*_level)[v] < level) {
alpar@389
   794
            if (!_level->active(v) && v != _source) {
alpar@389
   795
              _level->activate(v);
alpar@389
   796
            }
alpar@389
   797
            if (!_tolerance.less(rem, excess)) {
alpar@389
   798
              _flow->set(e, (*_flow)[e] + excess);
kpeter@581
   799
              (*_excess)[v] += excess;
alpar@389
   800
              excess = 0;
alpar@389
   801
              goto no_more_push;
alpar@389
   802
            } else {
alpar@389
   803
              excess -= rem;
kpeter@581
   804
              (*_excess)[v] += rem;
alpar@389
   805
              _flow->set(e, (*_capacity)[e]);
alpar@389
   806
            }
alpar@389
   807
          } else if (new_level > (*_level)[v]) {
alpar@389
   808
            new_level = (*_level)[v];
alpar@389
   809
          }
alpar@389
   810
        }
alpar@389
   811
alpar@389
   812
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
kpeter@641
   813
          Value rem = (*_flow)[e];
alpar@389
   814
          if (!_tolerance.positive(rem)) continue;
alpar@389
   815
          Node v = _graph.source(e);
alpar@389
   816
          if ((*_level)[v] < level) {
alpar@389
   817
            if (!_level->active(v) && v != _source) {
alpar@389
   818
              _level->activate(v);
alpar@389
   819
            }
alpar@389
   820
            if (!_tolerance.less(rem, excess)) {
alpar@389
   821
              _flow->set(e, (*_flow)[e] - excess);
kpeter@581
   822
              (*_excess)[v] += excess;
alpar@389
   823
              excess = 0;
alpar@389
   824
              goto no_more_push;
alpar@389
   825
            } else {
alpar@389
   826
              excess -= rem;
kpeter@581
   827
              (*_excess)[v] += rem;
alpar@389
   828
              _flow->set(e, 0);
alpar@389
   829
            }
alpar@389
   830
          } else if (new_level > (*_level)[v]) {
alpar@389
   831
            new_level = (*_level)[v];
alpar@389
   832
          }
alpar@389
   833
        }
alpar@389
   834
alpar@389
   835
      no_more_push:
alpar@389
   836
kpeter@581
   837
        (*_excess)[n] = excess;
alpar@389
   838
alpar@389
   839
        if (excess != 0) {
alpar@389
   840
          if (new_level + 1 < _level->maxLevel()) {
alpar@389
   841
            _level->liftHighestActive(new_level + 1);
alpar@389
   842
          } else {
alpar@389
   843
            // Calculation error
alpar@389
   844
            _level->liftHighestActiveToTop();
alpar@389
   845
          }
alpar@389
   846
          if (_level->emptyLevel(level)) {
alpar@389
   847
            // Calculation error
alpar@389
   848
            _level->liftToTop(level);
alpar@389
   849
          }
alpar@389
   850
        } else {
alpar@389
   851
          _level->deactivate(n);
alpar@389
   852
        }
alpar@389
   853
alpar@389
   854
      }
alpar@389
   855
    }
alpar@389
   856
alpar@389
   857
    /// \brief Runs the preflow algorithm.
alpar@389
   858
    ///
alpar@389
   859
    /// Runs the preflow algorithm.
alpar@389
   860
    /// \note pf.run() is just a shortcut of the following code.
alpar@389
   861
    /// \code
alpar@389
   862
    ///   pf.init();
alpar@389
   863
    ///   pf.startFirstPhase();
alpar@389
   864
    ///   pf.startSecondPhase();
alpar@389
   865
    /// \endcode
alpar@389
   866
    void run() {
alpar@389
   867
      init();
alpar@389
   868
      startFirstPhase();
alpar@389
   869
      startSecondPhase();
alpar@389
   870
    }
alpar@389
   871
alpar@389
   872
    /// \brief Runs the preflow algorithm to compute the minimum cut.
alpar@389
   873
    ///
alpar@389
   874
    /// Runs the preflow algorithm to compute the minimum cut.
alpar@389
   875
    /// \note pf.runMinCut() is just a shortcut of the following code.
alpar@389
   876
    /// \code
alpar@389
   877
    ///   pf.init();
alpar@389
   878
    ///   pf.startFirstPhase();
alpar@389
   879
    /// \endcode
alpar@389
   880
    void runMinCut() {
alpar@389
   881
      init();
alpar@389
   882
      startFirstPhase();
alpar@389
   883
    }
alpar@389
   884
alpar@389
   885
    /// @}
alpar@389
   886
alpar@389
   887
    /// \name Query Functions
kpeter@393
   888
    /// The results of the preflow algorithm can be obtained using these
alpar@389
   889
    /// functions.\n
kpeter@393
   890
    /// Either one of the \ref run() "run*()" functions or one of the
kpeter@393
   891
    /// \ref startFirstPhase() "start*()" functions should be called
kpeter@393
   892
    /// before using them.
alpar@389
   893
alpar@389
   894
    ///@{
alpar@389
   895
alpar@389
   896
    /// \brief Returns the value of the maximum flow.
alpar@389
   897
    ///
alpar@389
   898
    /// Returns the value of the maximum flow by returning the excess
kpeter@393
   899
    /// of the target node. This value equals to the value of
kpeter@393
   900
    /// the maximum flow already after the first phase of the algorithm.
kpeter@393
   901
    ///
kpeter@393
   902
    /// \pre Either \ref run() or \ref init() must be called before
kpeter@393
   903
    /// using this function.
kpeter@641
   904
    Value flowValue() const {
alpar@389
   905
      return (*_excess)[_target];
alpar@389
   906
    }
alpar@389
   907
kpeter@641
   908
    /// \brief Returns the flow value on the given arc.
alpar@389
   909
    ///
kpeter@641
   910
    /// Returns the flow value on the given arc. This method can
kpeter@393
   911
    /// be called after the second phase of the algorithm.
kpeter@393
   912
    ///
kpeter@393
   913
    /// \pre Either \ref run() or \ref init() must be called before
kpeter@393
   914
    /// using this function.
kpeter@641
   915
    Value flow(const Arc& arc) const {
kpeter@393
   916
      return (*_flow)[arc];
kpeter@393
   917
    }
kpeter@393
   918
kpeter@393
   919
    /// \brief Returns a const reference to the flow map.
kpeter@393
   920
    ///
kpeter@393
   921
    /// Returns a const reference to the arc map storing the found flow.
kpeter@393
   922
    /// This method can be called after the second phase of the algorithm.
kpeter@393
   923
    ///
kpeter@393
   924
    /// \pre Either \ref run() or \ref init() must be called before
kpeter@393
   925
    /// using this function.
kpeter@420
   926
    const FlowMap& flowMap() const {
kpeter@393
   927
      return *_flow;
kpeter@393
   928
    }
kpeter@393
   929
kpeter@393
   930
    /// \brief Returns \c true when the node is on the source side of the
kpeter@393
   931
    /// minimum cut.
kpeter@393
   932
    ///
kpeter@393
   933
    /// Returns true when the node is on the source side of the found
kpeter@393
   934
    /// minimum cut. This method can be called both after running \ref
alpar@389
   935
    /// startFirstPhase() and \ref startSecondPhase().
kpeter@393
   936
    ///
kpeter@393
   937
    /// \pre Either \ref run() or \ref init() must be called before
kpeter@393
   938
    /// using this function.
alpar@389
   939
    bool minCut(const Node& node) const {
alpar@389
   940
      return ((*_level)[node] == _level->maxLevel()) == _phase;
alpar@389
   941
    }
alpar@389
   942
kpeter@393
   943
    /// \brief Gives back a minimum value cut.
alpar@389
   944
    ///
kpeter@393
   945
    /// Sets \c cutMap to the characteristic vector of a minimum value
kpeter@393
   946
    /// cut. \c cutMap should be a \ref concepts::WriteMap "writable"
kpeter@393
   947
    /// node map with \c bool (or convertible) value type.
kpeter@393
   948
    ///
kpeter@393
   949
    /// This method can be called both after running \ref startFirstPhase()
kpeter@393
   950
    /// and \ref startSecondPhase(). The result after the second phase
kpeter@393
   951
    /// could be slightly different if inexact computation is used.
kpeter@393
   952
    ///
kpeter@393
   953
    /// \note This function calls \ref minCut() for each node, so it runs in
kpeter@559
   954
    /// O(n) time.
kpeter@393
   955
    ///
kpeter@393
   956
    /// \pre Either \ref run() or \ref init() must be called before
kpeter@393
   957
    /// using this function.
alpar@389
   958
    template <typename CutMap>
alpar@389
   959
    void minCutMap(CutMap& cutMap) const {
alpar@389
   960
      for (NodeIt n(_graph); n != INVALID; ++n) {
alpar@389
   961
        cutMap.set(n, minCut(n));
alpar@389
   962
      }
alpar@389
   963
    }
alpar@389
   964
alpar@389
   965
    /// @}
alpar@389
   966
  };
alpar@389
   967
}
alpar@389
   968
alpar@389
   969
#endif