lemon/hao_orlin.h
author Peter Kovacs <kpeter@inf.elte.hu>
Fri, 17 Apr 2009 09:54:14 +0200
changeset 640 7ac52d6a268e
parent 606 c5fd2d996909
child 643 293551ad254f
permissions -rw-r--r--
Extend and modify the interface of matching algorithms (#265)

- Rename decomposition() to status() in MaxMatching.
- Add a new query function statusMap() to MaxMatching.
- Add a new query function matchingMap() to all the three classes.
- Rename matchingValue() to matchingWeight() in the weighted
matching classes.
deba@425
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@425
     2
 *
deba@425
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@425
     4
 *
alpar@463
     5
 * Copyright (C) 2003-2009
deba@425
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@425
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@425
     8
 *
deba@425
     9
 * Permission to use, modify and distribute this software is granted
deba@425
    10
 * provided that this copyright notice appears in all copies. For
deba@425
    11
 * precise terms see the accompanying LICENSE file.
deba@425
    12
 *
deba@425
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@425
    14
 * express or implied, and with no claim as to its suitability for any
deba@425
    15
 * purpose.
deba@425
    16
 *
deba@425
    17
 */
deba@425
    18
deba@425
    19
#ifndef LEMON_HAO_ORLIN_H
deba@425
    20
#define LEMON_HAO_ORLIN_H
deba@425
    21
deba@425
    22
#include <vector>
deba@425
    23
#include <list>
deba@425
    24
#include <limits>
deba@425
    25
deba@425
    26
#include <lemon/maps.h>
deba@425
    27
#include <lemon/core.h>
deba@425
    28
#include <lemon/tolerance.h>
deba@425
    29
deba@425
    30
/// \file
deba@425
    31
/// \ingroup min_cut
deba@425
    32
/// \brief Implementation of the Hao-Orlin algorithm.
deba@425
    33
///
deba@425
    34
/// Implementation of the Hao-Orlin algorithm class for testing network
deba@425
    35
/// reliability.
deba@425
    36
deba@425
    37
namespace lemon {
deba@425
    38
deba@425
    39
  /// \ingroup min_cut
deba@425
    40
  ///
deba@425
    41
  /// \brief %Hao-Orlin algorithm to find a minimum cut in directed graphs.
deba@425
    42
  ///
deba@425
    43
  /// Hao-Orlin calculates a minimum cut in a directed graph
deba@425
    44
  /// \f$D=(V,A)\f$. It takes a fixed node \f$ source \in V \f$ and
deba@425
    45
  /// consists of two phases: in the first phase it determines a
deba@425
    46
  /// minimum cut with \f$ source \f$ on the source-side (i.e. a set
deba@425
    47
  /// \f$ X\subsetneq V \f$ with \f$ source \in X \f$ and minimal
deba@425
    48
  /// out-degree) and in the second phase it determines a minimum cut
deba@425
    49
  /// with \f$ source \f$ on the sink-side (i.e. a set
deba@425
    50
  /// \f$ X\subsetneq V \f$ with \f$ source \notin X \f$ and minimal
deba@425
    51
  /// out-degree). Obviously, the smaller of these two cuts will be a
deba@425
    52
  /// minimum cut of \f$ D \f$. The algorithm is a modified
deba@425
    53
  /// push-relabel preflow algorithm and our implementation calculates
deba@425
    54
  /// the minimum cut in \f$ O(n^2\sqrt{m}) \f$ time (we use the
deba@425
    55
  /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. The
deba@425
    56
  /// purpose of such algorithm is testing network reliability. For an
deba@425
    57
  /// undirected graph you can run just the first phase of the
deba@425
    58
  /// algorithm or you can use the algorithm of Nagamochi and Ibaraki
deba@425
    59
  /// which solves the undirected problem in
kpeter@606
    60
  /// \f$ O(nm + n^2 \log n) \f$ time: it is implemented in the
deba@425
    61
  /// NagamochiIbaraki algorithm class.
deba@425
    62
  ///
kpeter@606
    63
  /// \param GR The digraph class the algorithm runs on.
kpeter@606
    64
  /// \param CAP An arc map of capacities which can be any numreric type.
kpeter@606
    65
  /// The default type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
kpeter@606
    66
  /// \param TOL Tolerance class for handling inexact computations. The
kpeter@606
    67
  /// default tolerance type is \ref Tolerance "Tolerance<CAP::Value>".
deba@425
    68
#ifdef DOXYGEN
kpeter@606
    69
  template <typename GR, typename CAP, typename TOL>
deba@425
    70
#else
kpeter@606
    71
  template <typename GR,
kpeter@606
    72
            typename CAP = typename GR::template ArcMap<int>,
kpeter@606
    73
            typename TOL = Tolerance<typename CAP::Value> >
deba@425
    74
#endif
deba@425
    75
  class HaoOrlin {
deba@425
    76
  private:
deba@425
    77
kpeter@606
    78
    typedef GR Digraph;
kpeter@606
    79
    typedef CAP CapacityMap;
kpeter@606
    80
    typedef TOL Tolerance;
deba@425
    81
deba@425
    82
    typedef typename CapacityMap::Value Value;
deba@425
    83
deba@425
    84
    TEMPLATE_GRAPH_TYPEDEFS(Digraph);
deba@425
    85
deba@425
    86
    const Digraph& _graph;
deba@425
    87
    const CapacityMap* _capacity;
deba@425
    88
deba@425
    89
    typedef typename Digraph::template ArcMap<Value> FlowMap;
deba@425
    90
    FlowMap* _flow;
deba@425
    91
deba@425
    92
    Node _source;
deba@425
    93
deba@425
    94
    int _node_num;
deba@425
    95
deba@425
    96
    // Bucketing structure
deba@425
    97
    std::vector<Node> _first, _last;
deba@425
    98
    typename Digraph::template NodeMap<Node>* _next;
deba@425
    99
    typename Digraph::template NodeMap<Node>* _prev;
deba@425
   100
    typename Digraph::template NodeMap<bool>* _active;
deba@425
   101
    typename Digraph::template NodeMap<int>* _bucket;
deba@425
   102
deba@425
   103
    std::vector<bool> _dormant;
deba@425
   104
deba@425
   105
    std::list<std::list<int> > _sets;
deba@425
   106
    std::list<int>::iterator _highest;
deba@425
   107
deba@425
   108
    typedef typename Digraph::template NodeMap<Value> ExcessMap;
deba@425
   109
    ExcessMap* _excess;
deba@425
   110
deba@425
   111
    typedef typename Digraph::template NodeMap<bool> SourceSetMap;
deba@425
   112
    SourceSetMap* _source_set;
deba@425
   113
deba@425
   114
    Value _min_cut;
deba@425
   115
deba@425
   116
    typedef typename Digraph::template NodeMap<bool> MinCutMap;
deba@425
   117
    MinCutMap* _min_cut_map;
deba@425
   118
deba@425
   119
    Tolerance _tolerance;
deba@425
   120
deba@425
   121
  public:
deba@425
   122
deba@425
   123
    /// \brief Constructor
deba@425
   124
    ///
deba@425
   125
    /// Constructor of the algorithm class.
deba@425
   126
    HaoOrlin(const Digraph& graph, const CapacityMap& capacity,
deba@425
   127
             const Tolerance& tolerance = Tolerance()) :
deba@425
   128
      _graph(graph), _capacity(&capacity), _flow(0), _source(),
deba@425
   129
      _node_num(), _first(), _last(), _next(0), _prev(0),
deba@425
   130
      _active(0), _bucket(0), _dormant(), _sets(), _highest(),
deba@425
   131
      _excess(0), _source_set(0), _min_cut(), _min_cut_map(0),
deba@425
   132
      _tolerance(tolerance) {}
deba@425
   133
deba@425
   134
    ~HaoOrlin() {
deba@425
   135
      if (_min_cut_map) {
deba@425
   136
        delete _min_cut_map;
deba@425
   137
      }
deba@425
   138
      if (_source_set) {
deba@425
   139
        delete _source_set;
deba@425
   140
      }
deba@425
   141
      if (_excess) {
deba@425
   142
        delete _excess;
deba@425
   143
      }
deba@425
   144
      if (_next) {
deba@425
   145
        delete _next;
deba@425
   146
      }
deba@425
   147
      if (_prev) {
deba@425
   148
        delete _prev;
deba@425
   149
      }
deba@425
   150
      if (_active) {
deba@425
   151
        delete _active;
deba@425
   152
      }
deba@425
   153
      if (_bucket) {
deba@425
   154
        delete _bucket;
deba@425
   155
      }
deba@425
   156
      if (_flow) {
deba@425
   157
        delete _flow;
deba@425
   158
      }
deba@425
   159
    }
deba@425
   160
deba@425
   161
  private:
deba@425
   162
deba@425
   163
    void activate(const Node& i) {
kpeter@628
   164
      (*_active)[i] = true;
deba@425
   165
deba@425
   166
      int bucket = (*_bucket)[i];
deba@425
   167
deba@425
   168
      if ((*_prev)[i] == INVALID || (*_active)[(*_prev)[i]]) return;
deba@425
   169
      //unlace
kpeter@628
   170
      (*_next)[(*_prev)[i]] = (*_next)[i];
deba@425
   171
      if ((*_next)[i] != INVALID) {
kpeter@628
   172
        (*_prev)[(*_next)[i]] = (*_prev)[i];
deba@425
   173
      } else {
deba@425
   174
        _last[bucket] = (*_prev)[i];
deba@425
   175
      }
deba@425
   176
      //lace
kpeter@628
   177
      (*_next)[i] = _first[bucket];
kpeter@628
   178
      (*_prev)[_first[bucket]] = i;
kpeter@628
   179
      (*_prev)[i] = INVALID;
deba@425
   180
      _first[bucket] = i;
deba@425
   181
    }
deba@425
   182
deba@425
   183
    void deactivate(const Node& i) {
kpeter@628
   184
      (*_active)[i] = false;
deba@425
   185
      int bucket = (*_bucket)[i];
deba@425
   186
deba@425
   187
      if ((*_next)[i] == INVALID || !(*_active)[(*_next)[i]]) return;
deba@425
   188
deba@425
   189
      //unlace
kpeter@628
   190
      (*_prev)[(*_next)[i]] = (*_prev)[i];
deba@425
   191
      if ((*_prev)[i] != INVALID) {
kpeter@628
   192
        (*_next)[(*_prev)[i]] = (*_next)[i];
deba@425
   193
      } else {
deba@425
   194
        _first[bucket] = (*_next)[i];
deba@425
   195
      }
deba@425
   196
      //lace
kpeter@628
   197
      (*_prev)[i] = _last[bucket];
kpeter@628
   198
      (*_next)[_last[bucket]] = i;
kpeter@628
   199
      (*_next)[i] = INVALID;
deba@425
   200
      _last[bucket] = i;
deba@425
   201
    }
deba@425
   202
deba@425
   203
    void addItem(const Node& i, int bucket) {
deba@425
   204
      (*_bucket)[i] = bucket;
deba@425
   205
      if (_last[bucket] != INVALID) {
kpeter@628
   206
        (*_prev)[i] = _last[bucket];
kpeter@628
   207
        (*_next)[_last[bucket]] = i;
kpeter@628
   208
        (*_next)[i] = INVALID;
deba@425
   209
        _last[bucket] = i;
deba@425
   210
      } else {
kpeter@628
   211
        (*_prev)[i] = INVALID;
deba@425
   212
        _first[bucket] = i;
kpeter@628
   213
        (*_next)[i] = INVALID;
deba@425
   214
        _last[bucket] = i;
deba@425
   215
      }
deba@425
   216
    }
deba@425
   217
deba@425
   218
    void findMinCutOut() {
deba@425
   219
deba@425
   220
      for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@628
   221
        (*_excess)[n] = 0;
deba@425
   222
      }
deba@425
   223
deba@425
   224
      for (ArcIt a(_graph); a != INVALID; ++a) {
kpeter@628
   225
        (*_flow)[a] = 0;
deba@425
   226
      }
deba@425
   227
deba@427
   228
      int bucket_num = 0;
deba@427
   229
      std::vector<Node> queue(_node_num);
deba@427
   230
      int qfirst = 0, qlast = 0, qsep = 0;
deba@425
   231
deba@425
   232
      {
deba@425
   233
        typename Digraph::template NodeMap<bool> reached(_graph, false);
deba@425
   234
kpeter@628
   235
        reached[_source] = true;
deba@425
   236
        bool first_set = true;
deba@425
   237
deba@425
   238
        for (NodeIt t(_graph); t != INVALID; ++t) {
deba@425
   239
          if (reached[t]) continue;
deba@425
   240
          _sets.push_front(std::list<int>());
alpar@463
   241
deba@427
   242
          queue[qlast++] = t;
kpeter@628
   243
          reached[t] = true;
deba@425
   244
deba@427
   245
          while (qfirst != qlast) {
deba@427
   246
            if (qsep == qfirst) {
deba@427
   247
              ++bucket_num;
deba@427
   248
              _sets.front().push_front(bucket_num);
deba@427
   249
              _dormant[bucket_num] = !first_set;
deba@427
   250
              _first[bucket_num] = _last[bucket_num] = INVALID;
deba@427
   251
              qsep = qlast;
deba@427
   252
            }
deba@425
   253
deba@427
   254
            Node n = queue[qfirst++];
deba@427
   255
            addItem(n, bucket_num);
deba@427
   256
deba@427
   257
            for (InArcIt a(_graph, n); a != INVALID; ++a) {
deba@427
   258
              Node u = _graph.source(a);
deba@427
   259
              if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
kpeter@628
   260
                reached[u] = true;
deba@427
   261
                queue[qlast++] = u;
deba@425
   262
              }
deba@425
   263
            }
deba@425
   264
          }
deba@425
   265
          first_set = false;
deba@425
   266
        }
deba@425
   267
deba@427
   268
        ++bucket_num;
kpeter@628
   269
        (*_bucket)[_source] = 0;
deba@425
   270
        _dormant[0] = true;
deba@425
   271
      }
kpeter@628
   272
      (*_source_set)[_source] = true;
deba@425
   273
deba@425
   274
      Node target = _last[_sets.back().back()];
deba@425
   275
      {
deba@425
   276
        for (OutArcIt a(_graph, _source); a != INVALID; ++a) {
deba@425
   277
          if (_tolerance.positive((*_capacity)[a])) {
deba@425
   278
            Node u = _graph.target(a);
kpeter@628
   279
            (*_flow)[a] = (*_capacity)[a];
kpeter@628
   280
            (*_excess)[u] += (*_capacity)[a];
deba@425
   281
            if (!(*_active)[u] && u != _source) {
deba@425
   282
              activate(u);
deba@425
   283
            }
deba@425
   284
          }
deba@425
   285
        }
deba@425
   286
deba@425
   287
        if ((*_active)[target]) {
deba@425
   288
          deactivate(target);
deba@425
   289
        }
deba@425
   290
deba@425
   291
        _highest = _sets.back().begin();
deba@425
   292
        while (_highest != _sets.back().end() &&
deba@425
   293
               !(*_active)[_first[*_highest]]) {
deba@425
   294
          ++_highest;
deba@425
   295
        }
deba@425
   296
      }
deba@425
   297
deba@425
   298
      while (true) {
deba@425
   299
        while (_highest != _sets.back().end()) {
deba@425
   300
          Node n = _first[*_highest];
deba@425
   301
          Value excess = (*_excess)[n];
deba@425
   302
          int next_bucket = _node_num;
deba@425
   303
deba@425
   304
          int under_bucket;
deba@425
   305
          if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
deba@425
   306
            under_bucket = -1;
deba@425
   307
          } else {
deba@425
   308
            under_bucket = *(++std::list<int>::iterator(_highest));
deba@425
   309
          }
deba@425
   310
deba@425
   311
          for (OutArcIt a(_graph, n); a != INVALID; ++a) {
deba@425
   312
            Node v = _graph.target(a);
deba@425
   313
            if (_dormant[(*_bucket)[v]]) continue;
deba@425
   314
            Value rem = (*_capacity)[a] - (*_flow)[a];
deba@425
   315
            if (!_tolerance.positive(rem)) continue;
deba@425
   316
            if ((*_bucket)[v] == under_bucket) {
deba@425
   317
              if (!(*_active)[v] && v != target) {
deba@425
   318
                activate(v);
deba@425
   319
              }
deba@425
   320
              if (!_tolerance.less(rem, excess)) {
kpeter@628
   321
                (*_flow)[a] += excess;
kpeter@628
   322
                (*_excess)[v] += excess;
deba@425
   323
                excess = 0;
deba@425
   324
                goto no_more_push;
deba@425
   325
              } else {
deba@425
   326
                excess -= rem;
kpeter@628
   327
                (*_excess)[v] += rem;
kpeter@628
   328
                (*_flow)[a] = (*_capacity)[a];
deba@425
   329
              }
deba@425
   330
            } else if (next_bucket > (*_bucket)[v]) {
deba@425
   331
              next_bucket = (*_bucket)[v];
deba@425
   332
            }
deba@425
   333
          }
deba@425
   334
deba@425
   335
          for (InArcIt a(_graph, n); a != INVALID; ++a) {
deba@425
   336
            Node v = _graph.source(a);
deba@425
   337
            if (_dormant[(*_bucket)[v]]) continue;
deba@425
   338
            Value rem = (*_flow)[a];
deba@425
   339
            if (!_tolerance.positive(rem)) continue;
deba@425
   340
            if ((*_bucket)[v] == under_bucket) {
deba@425
   341
              if (!(*_active)[v] && v != target) {
deba@425
   342
                activate(v);
deba@425
   343
              }
deba@425
   344
              if (!_tolerance.less(rem, excess)) {
kpeter@628
   345
                (*_flow)[a] -= excess;
kpeter@628
   346
                (*_excess)[v] += excess;
deba@425
   347
                excess = 0;
deba@425
   348
                goto no_more_push;
deba@425
   349
              } else {
deba@425
   350
                excess -= rem;
kpeter@628
   351
                (*_excess)[v] += rem;
kpeter@628
   352
                (*_flow)[a] = 0;
deba@425
   353
              }
deba@425
   354
            } else if (next_bucket > (*_bucket)[v]) {
deba@425
   355
              next_bucket = (*_bucket)[v];
deba@425
   356
            }
deba@425
   357
          }
deba@425
   358
deba@425
   359
        no_more_push:
deba@425
   360
kpeter@628
   361
          (*_excess)[n] = excess;
deba@425
   362
deba@425
   363
          if (excess != 0) {
deba@425
   364
            if ((*_next)[n] == INVALID) {
deba@425
   365
              typename std::list<std::list<int> >::iterator new_set =
deba@425
   366
                _sets.insert(--_sets.end(), std::list<int>());
deba@425
   367
              new_set->splice(new_set->end(), _sets.back(),
deba@425
   368
                              _sets.back().begin(), ++_highest);
deba@425
   369
              for (std::list<int>::iterator it = new_set->begin();
deba@425
   370
                   it != new_set->end(); ++it) {
deba@425
   371
                _dormant[*it] = true;
deba@425
   372
              }
deba@425
   373
              while (_highest != _sets.back().end() &&
deba@425
   374
                     !(*_active)[_first[*_highest]]) {
deba@425
   375
                ++_highest;
deba@425
   376
              }
deba@425
   377
            } else if (next_bucket == _node_num) {
deba@425
   378
              _first[(*_bucket)[n]] = (*_next)[n];
kpeter@628
   379
              (*_prev)[(*_next)[n]] = INVALID;
deba@425
   380
deba@425
   381
              std::list<std::list<int> >::iterator new_set =
deba@425
   382
                _sets.insert(--_sets.end(), std::list<int>());
deba@425
   383
deba@425
   384
              new_set->push_front(bucket_num);
kpeter@628
   385
              (*_bucket)[n] = bucket_num;
deba@425
   386
              _first[bucket_num] = _last[bucket_num] = n;
kpeter@628
   387
              (*_next)[n] = INVALID;
kpeter@628
   388
              (*_prev)[n] = INVALID;
deba@425
   389
              _dormant[bucket_num] = true;
deba@425
   390
              ++bucket_num;
deba@425
   391
deba@425
   392
              while (_highest != _sets.back().end() &&
deba@425
   393
                     !(*_active)[_first[*_highest]]) {
deba@425
   394
                ++_highest;
deba@425
   395
              }
deba@425
   396
            } else {
deba@425
   397
              _first[*_highest] = (*_next)[n];
kpeter@628
   398
              (*_prev)[(*_next)[n]] = INVALID;
deba@425
   399
deba@425
   400
              while (next_bucket != *_highest) {
deba@425
   401
                --_highest;
deba@425
   402
              }
deba@425
   403
deba@425
   404
              if (_highest == _sets.back().begin()) {
deba@425
   405
                _sets.back().push_front(bucket_num);
deba@425
   406
                _dormant[bucket_num] = false;
deba@425
   407
                _first[bucket_num] = _last[bucket_num] = INVALID;
deba@425
   408
                ++bucket_num;
deba@425
   409
              }
deba@425
   410
              --_highest;
deba@425
   411
kpeter@628
   412
              (*_bucket)[n] = *_highest;
kpeter@628
   413
              (*_next)[n] = _first[*_highest];
deba@425
   414
              if (_first[*_highest] != INVALID) {
kpeter@628
   415
                (*_prev)[_first[*_highest]] = n;
deba@425
   416
              } else {
deba@425
   417
                _last[*_highest] = n;
deba@425
   418
              }
deba@425
   419
              _first[*_highest] = n;
deba@425
   420
            }
deba@425
   421
          } else {
deba@425
   422
deba@425
   423
            deactivate(n);
deba@425
   424
            if (!(*_active)[_first[*_highest]]) {
deba@425
   425
              ++_highest;
deba@425
   426
              if (_highest != _sets.back().end() &&
deba@425
   427
                  !(*_active)[_first[*_highest]]) {
deba@425
   428
                _highest = _sets.back().end();
deba@425
   429
              }
deba@425
   430
            }
deba@425
   431
          }
deba@425
   432
        }
deba@425
   433
deba@425
   434
        if ((*_excess)[target] < _min_cut) {
deba@425
   435
          _min_cut = (*_excess)[target];
deba@425
   436
          for (NodeIt i(_graph); i != INVALID; ++i) {
kpeter@628
   437
            (*_min_cut_map)[i] = true;
deba@425
   438
          }
deba@425
   439
          for (std::list<int>::iterator it = _sets.back().begin();
deba@425
   440
               it != _sets.back().end(); ++it) {
deba@425
   441
            Node n = _first[*it];
deba@425
   442
            while (n != INVALID) {
kpeter@628
   443
              (*_min_cut_map)[n] = false;
deba@425
   444
              n = (*_next)[n];
deba@425
   445
            }
deba@425
   446
          }
deba@425
   447
        }
deba@425
   448
deba@425
   449
        {
deba@425
   450
          Node new_target;
deba@425
   451
          if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
deba@425
   452
            if ((*_next)[target] == INVALID) {
deba@425
   453
              _last[(*_bucket)[target]] = (*_prev)[target];
deba@425
   454
              new_target = (*_prev)[target];
deba@425
   455
            } else {
kpeter@628
   456
              (*_prev)[(*_next)[target]] = (*_prev)[target];
deba@425
   457
              new_target = (*_next)[target];
deba@425
   458
            }
deba@425
   459
            if ((*_prev)[target] == INVALID) {
deba@425
   460
              _first[(*_bucket)[target]] = (*_next)[target];
deba@425
   461
            } else {
kpeter@628
   462
              (*_next)[(*_prev)[target]] = (*_next)[target];
deba@425
   463
            }
deba@425
   464
          } else {
deba@425
   465
            _sets.back().pop_back();
deba@425
   466
            if (_sets.back().empty()) {
deba@425
   467
              _sets.pop_back();
deba@425
   468
              if (_sets.empty())
deba@425
   469
                break;
deba@425
   470
              for (std::list<int>::iterator it = _sets.back().begin();
deba@425
   471
                   it != _sets.back().end(); ++it) {
deba@425
   472
                _dormant[*it] = false;
deba@425
   473
              }
deba@425
   474
            }
deba@425
   475
            new_target = _last[_sets.back().back()];
deba@425
   476
          }
deba@425
   477
kpeter@628
   478
          (*_bucket)[target] = 0;
deba@425
   479
kpeter@628
   480
          (*_source_set)[target] = true;
deba@425
   481
          for (OutArcIt a(_graph, target); a != INVALID; ++a) {
deba@425
   482
            Value rem = (*_capacity)[a] - (*_flow)[a];
deba@425
   483
            if (!_tolerance.positive(rem)) continue;
deba@425
   484
            Node v = _graph.target(a);
deba@425
   485
            if (!(*_active)[v] && !(*_source_set)[v]) {
deba@425
   486
              activate(v);
deba@425
   487
            }
kpeter@628
   488
            (*_excess)[v] += rem;
kpeter@628
   489
            (*_flow)[a] = (*_capacity)[a];
deba@425
   490
          }
deba@425
   491
deba@425
   492
          for (InArcIt a(_graph, target); a != INVALID; ++a) {
deba@425
   493
            Value rem = (*_flow)[a];
deba@425
   494
            if (!_tolerance.positive(rem)) continue;
deba@425
   495
            Node v = _graph.source(a);
deba@425
   496
            if (!(*_active)[v] && !(*_source_set)[v]) {
deba@425
   497
              activate(v);
deba@425
   498
            }
kpeter@628
   499
            (*_excess)[v] += rem;
kpeter@628
   500
            (*_flow)[a] = 0;
deba@425
   501
          }
deba@425
   502
deba@425
   503
          target = new_target;
deba@425
   504
          if ((*_active)[target]) {
deba@425
   505
            deactivate(target);
deba@425
   506
          }
deba@425
   507
deba@425
   508
          _highest = _sets.back().begin();
deba@425
   509
          while (_highest != _sets.back().end() &&
deba@425
   510
                 !(*_active)[_first[*_highest]]) {
deba@425
   511
            ++_highest;
deba@425
   512
          }
deba@425
   513
        }
deba@425
   514
      }
deba@425
   515
    }
deba@425
   516
deba@425
   517
    void findMinCutIn() {
deba@425
   518
deba@425
   519
      for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@628
   520
        (*_excess)[n] = 0;
deba@425
   521
      }
deba@425
   522
deba@425
   523
      for (ArcIt a(_graph); a != INVALID; ++a) {
kpeter@628
   524
        (*_flow)[a] = 0;
deba@425
   525
      }
deba@425
   526
deba@427
   527
      int bucket_num = 0;
deba@427
   528
      std::vector<Node> queue(_node_num);
deba@427
   529
      int qfirst = 0, qlast = 0, qsep = 0;
deba@425
   530
deba@425
   531
      {
deba@425
   532
        typename Digraph::template NodeMap<bool> reached(_graph, false);
deba@425
   533
kpeter@628
   534
        reached[_source] = true;
deba@425
   535
deba@425
   536
        bool first_set = true;
deba@425
   537
deba@425
   538
        for (NodeIt t(_graph); t != INVALID; ++t) {
deba@425
   539
          if (reached[t]) continue;
deba@425
   540
          _sets.push_front(std::list<int>());
alpar@463
   541
deba@427
   542
          queue[qlast++] = t;
kpeter@628
   543
          reached[t] = true;
deba@425
   544
deba@427
   545
          while (qfirst != qlast) {
deba@427
   546
            if (qsep == qfirst) {
deba@427
   547
              ++bucket_num;
deba@427
   548
              _sets.front().push_front(bucket_num);
deba@427
   549
              _dormant[bucket_num] = !first_set;
deba@427
   550
              _first[bucket_num] = _last[bucket_num] = INVALID;
deba@427
   551
              qsep = qlast;
deba@427
   552
            }
deba@425
   553
deba@427
   554
            Node n = queue[qfirst++];
deba@427
   555
            addItem(n, bucket_num);
deba@427
   556
deba@427
   557
            for (OutArcIt a(_graph, n); a != INVALID; ++a) {
deba@427
   558
              Node u = _graph.target(a);
deba@427
   559
              if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
kpeter@628
   560
                reached[u] = true;
deba@427
   561
                queue[qlast++] = u;
deba@425
   562
              }
deba@425
   563
            }
deba@425
   564
          }
deba@425
   565
          first_set = false;
deba@425
   566
        }
deba@425
   567
deba@427
   568
        ++bucket_num;
kpeter@628
   569
        (*_bucket)[_source] = 0;
deba@425
   570
        _dormant[0] = true;
deba@425
   571
      }
kpeter@628
   572
      (*_source_set)[_source] = true;
deba@425
   573
deba@425
   574
      Node target = _last[_sets.back().back()];
deba@425
   575
      {
deba@425
   576
        for (InArcIt a(_graph, _source); a != INVALID; ++a) {
deba@425
   577
          if (_tolerance.positive((*_capacity)[a])) {
deba@425
   578
            Node u = _graph.source(a);
kpeter@628
   579
            (*_flow)[a] = (*_capacity)[a];
kpeter@628
   580
            (*_excess)[u] += (*_capacity)[a];
deba@425
   581
            if (!(*_active)[u] && u != _source) {
deba@425
   582
              activate(u);
deba@425
   583
            }
deba@425
   584
          }
deba@425
   585
        }
deba@425
   586
        if ((*_active)[target]) {
deba@425
   587
          deactivate(target);
deba@425
   588
        }
deba@425
   589
deba@425
   590
        _highest = _sets.back().begin();
deba@425
   591
        while (_highest != _sets.back().end() &&
deba@425
   592
               !(*_active)[_first[*_highest]]) {
deba@425
   593
          ++_highest;
deba@425
   594
        }
deba@425
   595
      }
deba@425
   596
deba@425
   597
deba@425
   598
      while (true) {
deba@425
   599
        while (_highest != _sets.back().end()) {
deba@425
   600
          Node n = _first[*_highest];
deba@425
   601
          Value excess = (*_excess)[n];
deba@425
   602
          int next_bucket = _node_num;
deba@425
   603
deba@425
   604
          int under_bucket;
deba@425
   605
          if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
deba@425
   606
            under_bucket = -1;
deba@425
   607
          } else {
deba@425
   608
            under_bucket = *(++std::list<int>::iterator(_highest));
deba@425
   609
          }
deba@425
   610
deba@425
   611
          for (InArcIt a(_graph, n); a != INVALID; ++a) {
deba@425
   612
            Node v = _graph.source(a);
deba@425
   613
            if (_dormant[(*_bucket)[v]]) continue;
deba@425
   614
            Value rem = (*_capacity)[a] - (*_flow)[a];
deba@425
   615
            if (!_tolerance.positive(rem)) continue;
deba@425
   616
            if ((*_bucket)[v] == under_bucket) {
deba@425
   617
              if (!(*_active)[v] && v != target) {
deba@425
   618
                activate(v);
deba@425
   619
              }
deba@425
   620
              if (!_tolerance.less(rem, excess)) {
kpeter@628
   621
                (*_flow)[a] += excess;
kpeter@628
   622
                (*_excess)[v] += excess;
deba@425
   623
                excess = 0;
deba@425
   624
                goto no_more_push;
deba@425
   625
              } else {
deba@425
   626
                excess -= rem;
kpeter@628
   627
                (*_excess)[v] += rem;
kpeter@628
   628
                (*_flow)[a] = (*_capacity)[a];
deba@425
   629
              }
deba@425
   630
            } else if (next_bucket > (*_bucket)[v]) {
deba@425
   631
              next_bucket = (*_bucket)[v];
deba@425
   632
            }
deba@425
   633
          }
deba@425
   634
deba@425
   635
          for (OutArcIt a(_graph, n); a != INVALID; ++a) {
deba@425
   636
            Node v = _graph.target(a);
deba@425
   637
            if (_dormant[(*_bucket)[v]]) continue;
deba@425
   638
            Value rem = (*_flow)[a];
deba@425
   639
            if (!_tolerance.positive(rem)) continue;
deba@425
   640
            if ((*_bucket)[v] == under_bucket) {
deba@425
   641
              if (!(*_active)[v] && v != target) {
deba@425
   642
                activate(v);
deba@425
   643
              }
deba@425
   644
              if (!_tolerance.less(rem, excess)) {
kpeter@628
   645
                (*_flow)[a] -= excess;
kpeter@628
   646
                (*_excess)[v] += excess;
deba@425
   647
                excess = 0;
deba@425
   648
                goto no_more_push;
deba@425
   649
              } else {
deba@425
   650
                excess -= rem;
kpeter@628
   651
                (*_excess)[v] += rem;
kpeter@628
   652
                (*_flow)[a] = 0;
deba@425
   653
              }
deba@425
   654
            } else if (next_bucket > (*_bucket)[v]) {
deba@425
   655
              next_bucket = (*_bucket)[v];
deba@425
   656
            }
deba@425
   657
          }
deba@425
   658
deba@425
   659
        no_more_push:
deba@425
   660
kpeter@628
   661
          (*_excess)[n] = excess;
deba@425
   662
deba@425
   663
          if (excess != 0) {
deba@425
   664
            if ((*_next)[n] == INVALID) {
deba@425
   665
              typename std::list<std::list<int> >::iterator new_set =
deba@425
   666
                _sets.insert(--_sets.end(), std::list<int>());
deba@425
   667
              new_set->splice(new_set->end(), _sets.back(),
deba@425
   668
                              _sets.back().begin(), ++_highest);
deba@425
   669
              for (std::list<int>::iterator it = new_set->begin();
deba@425
   670
                   it != new_set->end(); ++it) {
deba@425
   671
                _dormant[*it] = true;
deba@425
   672
              }
deba@425
   673
              while (_highest != _sets.back().end() &&
deba@425
   674
                     !(*_active)[_first[*_highest]]) {
deba@425
   675
                ++_highest;
deba@425
   676
              }
deba@425
   677
            } else if (next_bucket == _node_num) {
deba@425
   678
              _first[(*_bucket)[n]] = (*_next)[n];
kpeter@628
   679
              (*_prev)[(*_next)[n]] = INVALID;
deba@425
   680
deba@425
   681
              std::list<std::list<int> >::iterator new_set =
deba@425
   682
                _sets.insert(--_sets.end(), std::list<int>());
deba@425
   683
deba@425
   684
              new_set->push_front(bucket_num);
kpeter@628
   685
              (*_bucket)[n] = bucket_num;
deba@425
   686
              _first[bucket_num] = _last[bucket_num] = n;
kpeter@628
   687
              (*_next)[n] = INVALID;
kpeter@628
   688
              (*_prev)[n] = INVALID;
deba@425
   689
              _dormant[bucket_num] = true;
deba@425
   690
              ++bucket_num;
deba@425
   691
deba@425
   692
              while (_highest != _sets.back().end() &&
deba@425
   693
                     !(*_active)[_first[*_highest]]) {
deba@425
   694
                ++_highest;
deba@425
   695
              }
deba@425
   696
            } else {
deba@425
   697
              _first[*_highest] = (*_next)[n];
kpeter@628
   698
              (*_prev)[(*_next)[n]] = INVALID;
deba@425
   699
deba@425
   700
              while (next_bucket != *_highest) {
deba@425
   701
                --_highest;
deba@425
   702
              }
deba@425
   703
              if (_highest == _sets.back().begin()) {
deba@425
   704
                _sets.back().push_front(bucket_num);
deba@425
   705
                _dormant[bucket_num] = false;
deba@425
   706
                _first[bucket_num] = _last[bucket_num] = INVALID;
deba@425
   707
                ++bucket_num;
deba@425
   708
              }
deba@425
   709
              --_highest;
deba@425
   710
kpeter@628
   711
              (*_bucket)[n] = *_highest;
kpeter@628
   712
              (*_next)[n] = _first[*_highest];
deba@425
   713
              if (_first[*_highest] != INVALID) {
kpeter@628
   714
                (*_prev)[_first[*_highest]] = n;
deba@425
   715
              } else {
deba@425
   716
                _last[*_highest] = n;
deba@425
   717
              }
deba@425
   718
              _first[*_highest] = n;
deba@425
   719
            }
deba@425
   720
          } else {
deba@425
   721
deba@425
   722
            deactivate(n);
deba@425
   723
            if (!(*_active)[_first[*_highest]]) {
deba@425
   724
              ++_highest;
deba@425
   725
              if (_highest != _sets.back().end() &&
deba@425
   726
                  !(*_active)[_first[*_highest]]) {
deba@425
   727
                _highest = _sets.back().end();
deba@425
   728
              }
deba@425
   729
            }
deba@425
   730
          }
deba@425
   731
        }
deba@425
   732
deba@425
   733
        if ((*_excess)[target] < _min_cut) {
deba@425
   734
          _min_cut = (*_excess)[target];
deba@425
   735
          for (NodeIt i(_graph); i != INVALID; ++i) {
kpeter@628
   736
            (*_min_cut_map)[i] = false;
deba@425
   737
          }
deba@425
   738
          for (std::list<int>::iterator it = _sets.back().begin();
deba@425
   739
               it != _sets.back().end(); ++it) {
deba@425
   740
            Node n = _first[*it];
deba@425
   741
            while (n != INVALID) {
kpeter@628
   742
              (*_min_cut_map)[n] = true;
deba@425
   743
              n = (*_next)[n];
deba@425
   744
            }
deba@425
   745
          }
deba@425
   746
        }
deba@425
   747
deba@425
   748
        {
deba@425
   749
          Node new_target;
deba@425
   750
          if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
deba@425
   751
            if ((*_next)[target] == INVALID) {
deba@425
   752
              _last[(*_bucket)[target]] = (*_prev)[target];
deba@425
   753
              new_target = (*_prev)[target];
deba@425
   754
            } else {
kpeter@628
   755
              (*_prev)[(*_next)[target]] = (*_prev)[target];
deba@425
   756
              new_target = (*_next)[target];
deba@425
   757
            }
deba@425
   758
            if ((*_prev)[target] == INVALID) {
deba@425
   759
              _first[(*_bucket)[target]] = (*_next)[target];
deba@425
   760
            } else {
kpeter@628
   761
              (*_next)[(*_prev)[target]] = (*_next)[target];
deba@425
   762
            }
deba@425
   763
          } else {
deba@425
   764
            _sets.back().pop_back();
deba@425
   765
            if (_sets.back().empty()) {
deba@425
   766
              _sets.pop_back();
deba@425
   767
              if (_sets.empty())
deba@425
   768
                break;
deba@425
   769
              for (std::list<int>::iterator it = _sets.back().begin();
deba@425
   770
                   it != _sets.back().end(); ++it) {
deba@425
   771
                _dormant[*it] = false;
deba@425
   772
              }
deba@425
   773
            }
deba@425
   774
            new_target = _last[_sets.back().back()];
deba@425
   775
          }
deba@425
   776
kpeter@628
   777
          (*_bucket)[target] = 0;
deba@425
   778
kpeter@628
   779
          (*_source_set)[target] = true;
deba@425
   780
          for (InArcIt a(_graph, target); a != INVALID; ++a) {
deba@425
   781
            Value rem = (*_capacity)[a] - (*_flow)[a];
deba@425
   782
            if (!_tolerance.positive(rem)) continue;
deba@425
   783
            Node v = _graph.source(a);
deba@425
   784
            if (!(*_active)[v] && !(*_source_set)[v]) {
deba@425
   785
              activate(v);
deba@425
   786
            }
kpeter@628
   787
            (*_excess)[v] += rem;
kpeter@628
   788
            (*_flow)[a] = (*_capacity)[a];
deba@425
   789
          }
deba@425
   790
deba@425
   791
          for (OutArcIt a(_graph, target); a != INVALID; ++a) {
deba@425
   792
            Value rem = (*_flow)[a];
deba@425
   793
            if (!_tolerance.positive(rem)) continue;
deba@425
   794
            Node v = _graph.target(a);
deba@425
   795
            if (!(*_active)[v] && !(*_source_set)[v]) {
deba@425
   796
              activate(v);
deba@425
   797
            }
kpeter@628
   798
            (*_excess)[v] += rem;
kpeter@628
   799
            (*_flow)[a] = 0;
deba@425
   800
          }
deba@425
   801
deba@425
   802
          target = new_target;
deba@425
   803
          if ((*_active)[target]) {
deba@425
   804
            deactivate(target);
deba@425
   805
          }
deba@425
   806
deba@425
   807
          _highest = _sets.back().begin();
deba@425
   808
          while (_highest != _sets.back().end() &&
deba@425
   809
                 !(*_active)[_first[*_highest]]) {
deba@425
   810
            ++_highest;
deba@425
   811
          }
deba@425
   812
        }
deba@425
   813
      }
deba@425
   814
    }
deba@425
   815
deba@425
   816
  public:
deba@425
   817
deba@425
   818
    /// \name Execution control
deba@425
   819
    /// The simplest way to execute the algorithm is to use
kpeter@606
   820
    /// one of the member functions called \ref run().
deba@425
   821
    /// \n
deba@425
   822
    /// If you need more control on the execution,
deba@425
   823
    /// first you must call \ref init(), then the \ref calculateIn() or
alpar@428
   824
    /// \ref calculateOut() functions.
deba@425
   825
deba@425
   826
    /// @{
deba@425
   827
deba@425
   828
    /// \brief Initializes the internal data structures.
deba@425
   829
    ///
deba@425
   830
    /// Initializes the internal data structures. It creates
deba@425
   831
    /// the maps, residual graph adaptors and some bucket structures
deba@425
   832
    /// for the algorithm.
deba@425
   833
    void init() {
deba@425
   834
      init(NodeIt(_graph));
deba@425
   835
    }
deba@425
   836
deba@425
   837
    /// \brief Initializes the internal data structures.
deba@425
   838
    ///
deba@425
   839
    /// Initializes the internal data structures. It creates
deba@425
   840
    /// the maps, residual graph adaptor and some bucket structures
deba@425
   841
    /// for the algorithm. Node \c source  is used as the push-relabel
deba@425
   842
    /// algorithm's source.
deba@425
   843
    void init(const Node& source) {
deba@425
   844
      _source = source;
deba@425
   845
deba@425
   846
      _node_num = countNodes(_graph);
deba@425
   847
deba@427
   848
      _first.resize(_node_num);
deba@427
   849
      _last.resize(_node_num);
deba@425
   850
deba@427
   851
      _dormant.resize(_node_num);
deba@425
   852
deba@425
   853
      if (!_flow) {
deba@425
   854
        _flow = new FlowMap(_graph);
deba@425
   855
      }
deba@425
   856
      if (!_next) {
deba@425
   857
        _next = new typename Digraph::template NodeMap<Node>(_graph);
deba@425
   858
      }
deba@425
   859
      if (!_prev) {
deba@425
   860
        _prev = new typename Digraph::template NodeMap<Node>(_graph);
deba@425
   861
      }
deba@425
   862
      if (!_active) {
deba@425
   863
        _active = new typename Digraph::template NodeMap<bool>(_graph);
deba@425
   864
      }
deba@425
   865
      if (!_bucket) {
deba@425
   866
        _bucket = new typename Digraph::template NodeMap<int>(_graph);
deba@425
   867
      }
deba@425
   868
      if (!_excess) {
deba@425
   869
        _excess = new ExcessMap(_graph);
deba@425
   870
      }
deba@425
   871
      if (!_source_set) {
deba@425
   872
        _source_set = new SourceSetMap(_graph);
deba@425
   873
      }
deba@425
   874
      if (!_min_cut_map) {
deba@425
   875
        _min_cut_map = new MinCutMap(_graph);
deba@425
   876
      }
deba@425
   877
deba@425
   878
      _min_cut = std::numeric_limits<Value>::max();
deba@425
   879
    }
deba@425
   880
deba@425
   881
deba@425
   882
    /// \brief Calculates a minimum cut with \f$ source \f$ on the
deba@425
   883
    /// source-side.
deba@425
   884
    ///
deba@425
   885
    /// Calculates a minimum cut with \f$ source \f$ on the
alpar@428
   886
    /// source-side (i.e. a set \f$ X\subsetneq V \f$ with
alpar@428
   887
    /// \f$ source \in X \f$ and minimal out-degree).
deba@425
   888
    void calculateOut() {
deba@425
   889
      findMinCutOut();
deba@425
   890
    }
deba@425
   891
deba@425
   892
    /// \brief Calculates a minimum cut with \f$ source \f$ on the
deba@425
   893
    /// target-side.
deba@425
   894
    ///
deba@425
   895
    /// Calculates a minimum cut with \f$ source \f$ on the
alpar@428
   896
    /// target-side (i.e. a set \f$ X\subsetneq V \f$ with
alpar@428
   897
    /// \f$ source \in X \f$ and minimal out-degree).
deba@425
   898
    void calculateIn() {
deba@425
   899
      findMinCutIn();
deba@425
   900
    }
deba@425
   901
deba@425
   902
deba@425
   903
    /// \brief Runs the algorithm.
deba@425
   904
    ///
deba@425
   905
    /// Runs the algorithm. It finds nodes \c source and \c target
deba@425
   906
    /// arbitrarily and then calls \ref init(), \ref calculateOut()
deba@425
   907
    /// and \ref calculateIn().
deba@425
   908
    void run() {
deba@425
   909
      init();
deba@425
   910
      calculateOut();
deba@425
   911
      calculateIn();
deba@425
   912
    }
deba@425
   913
deba@425
   914
    /// \brief Runs the algorithm.
deba@425
   915
    ///
deba@425
   916
    /// Runs the algorithm. It uses the given \c source node, finds a
deba@425
   917
    /// proper \c target and then calls the \ref init(), \ref
deba@425
   918
    /// calculateOut() and \ref calculateIn().
deba@425
   919
    void run(const Node& s) {
deba@425
   920
      init(s);
deba@425
   921
      calculateOut();
deba@425
   922
      calculateIn();
deba@425
   923
    }
deba@425
   924
deba@425
   925
    /// @}
deba@425
   926
deba@425
   927
    /// \name Query Functions
deba@425
   928
    /// The result of the %HaoOrlin algorithm
deba@425
   929
    /// can be obtained using these functions.
deba@425
   930
    /// \n
deba@425
   931
    /// Before using these functions, either \ref run(), \ref
deba@425
   932
    /// calculateOut() or \ref calculateIn() must be called.
deba@425
   933
deba@425
   934
    /// @{
deba@425
   935
deba@425
   936
    /// \brief Returns the value of the minimum value cut.
deba@425
   937
    ///
deba@425
   938
    /// Returns the value of the minimum value cut.
deba@425
   939
    Value minCutValue() const {
deba@425
   940
      return _min_cut;
deba@425
   941
    }
deba@425
   942
deba@425
   943
deba@425
   944
    /// \brief Returns a minimum cut.
deba@425
   945
    ///
deba@425
   946
    /// Sets \c nodeMap to the characteristic vector of a minimum
deba@425
   947
    /// value cut: it will give a nonempty set \f$ X\subsetneq V \f$
deba@425
   948
    /// with minimal out-degree (i.e. \c nodeMap will be true exactly
deba@425
   949
    /// for the nodes of \f$ X \f$).  \pre nodeMap should be a
deba@425
   950
    /// bool-valued node-map.
deba@425
   951
    template <typename NodeMap>
deba@425
   952
    Value minCutMap(NodeMap& nodeMap) const {
deba@425
   953
      for (NodeIt it(_graph); it != INVALID; ++it) {
deba@425
   954
        nodeMap.set(it, (*_min_cut_map)[it]);
deba@425
   955
      }
deba@425
   956
      return _min_cut;
deba@425
   957
    }
deba@425
   958
deba@425
   959
    /// @}
deba@425
   960
deba@425
   961
  }; //class HaoOrlin
deba@425
   962
deba@425
   963
deba@425
   964
} //namespace lemon
deba@425
   965
deba@425
   966
#endif //LEMON_HAO_ORLIN_H