lemon/preflow.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 24 Mar 2009 00:18:25 +0100
changeset 596 8c3112a66878
parent 440 88ed40ad0d4f
child 550 c5fd2d996909
child 602 dacc2cee2b4c
permissions -rw-r--r--
Use XTI implementation instead of ATI in NetworkSimplex (#234)

XTI (eXtended Threaded Index) is an imporved version of the widely
known ATI (Augmented Threaded Index) method for storing and updating
the spanning tree structure in Network Simplex algorithms.

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