lemon/preflow.h
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 806 fa6f37d7a25b
parent 755 134852d7fb0a
parent 786 e20173729589
child 823 a7e93de12cbd
permissions -rw-r--r--
Entirely rework CapacityScaling (#180)

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