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