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