lemon/hao_orlin.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 891 bb70ad62c95f
parent 596 293551ad254f
child 860 930ddeafdb20
permissions -rw-r--r--
Fix critical bug in preflow (#372)

The wrong transition between the bound decrease and highest active
heuristics caused the bug. The last node chosen in bound decrease mode
is used in the first iteration in highest active mode.
     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         (*_source_set)[n] = false;
   230       }
   231 
   232       for (ArcIt a(_graph); a != INVALID; ++a) {
   233         (*_flow)[a] = 0;
   234       }
   235 
   236       int bucket_num = 0;
   237       std::vector<Node> queue(_node_num);
   238       int qfirst = 0, qlast = 0, qsep = 0;
   239 
   240       {
   241         typename Digraph::template NodeMap<bool> reached(_graph, false);
   242 
   243         reached[_source] = true;
   244         bool first_set = true;
   245 
   246         for (NodeIt t(_graph); t != INVALID; ++t) {
   247           if (reached[t]) continue;
   248           _sets.push_front(std::list<int>());
   249 
   250           queue[qlast++] = t;
   251           reached[t] = true;
   252 
   253           while (qfirst != qlast) {
   254             if (qsep == qfirst) {
   255               ++bucket_num;
   256               _sets.front().push_front(bucket_num);
   257               _dormant[bucket_num] = !first_set;
   258               _first[bucket_num] = _last[bucket_num] = INVALID;
   259               qsep = qlast;
   260             }
   261 
   262             Node n = queue[qfirst++];
   263             addItem(n, bucket_num);
   264 
   265             for (InArcIt a(_graph, n); a != INVALID; ++a) {
   266               Node u = _graph.source(a);
   267               if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
   268                 reached[u] = true;
   269                 queue[qlast++] = u;
   270               }
   271             }
   272           }
   273           first_set = false;
   274         }
   275 
   276         ++bucket_num;
   277         (*_bucket)[_source] = 0;
   278         _dormant[0] = true;
   279       }
   280       (*_source_set)[_source] = true;
   281 
   282       Node target = _last[_sets.back().back()];
   283       {
   284         for (OutArcIt a(_graph, _source); a != INVALID; ++a) {
   285           if (_tolerance.positive((*_capacity)[a])) {
   286             Node u = _graph.target(a);
   287             (*_flow)[a] = (*_capacity)[a];
   288             (*_excess)[u] += (*_capacity)[a];
   289             if (!(*_active)[u] && u != _source) {
   290               activate(u);
   291             }
   292           }
   293         }
   294 
   295         if ((*_active)[target]) {
   296           deactivate(target);
   297         }
   298 
   299         _highest = _sets.back().begin();
   300         while (_highest != _sets.back().end() &&
   301                !(*_active)[_first[*_highest]]) {
   302           ++_highest;
   303         }
   304       }
   305 
   306       while (true) {
   307         while (_highest != _sets.back().end()) {
   308           Node n = _first[*_highest];
   309           Value excess = (*_excess)[n];
   310           int next_bucket = _node_num;
   311 
   312           int under_bucket;
   313           if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
   314             under_bucket = -1;
   315           } else {
   316             under_bucket = *(++std::list<int>::iterator(_highest));
   317           }
   318 
   319           for (OutArcIt a(_graph, n); a != INVALID; ++a) {
   320             Node v = _graph.target(a);
   321             if (_dormant[(*_bucket)[v]]) continue;
   322             Value rem = (*_capacity)[a] - (*_flow)[a];
   323             if (!_tolerance.positive(rem)) continue;
   324             if ((*_bucket)[v] == under_bucket) {
   325               if (!(*_active)[v] && v != target) {
   326                 activate(v);
   327               }
   328               if (!_tolerance.less(rem, excess)) {
   329                 (*_flow)[a] += excess;
   330                 (*_excess)[v] += excess;
   331                 excess = 0;
   332                 goto no_more_push;
   333               } else {
   334                 excess -= rem;
   335                 (*_excess)[v] += rem;
   336                 (*_flow)[a] = (*_capacity)[a];
   337               }
   338             } else if (next_bucket > (*_bucket)[v]) {
   339               next_bucket = (*_bucket)[v];
   340             }
   341           }
   342 
   343           for (InArcIt a(_graph, n); a != INVALID; ++a) {
   344             Node v = _graph.source(a);
   345             if (_dormant[(*_bucket)[v]]) continue;
   346             Value rem = (*_flow)[a];
   347             if (!_tolerance.positive(rem)) continue;
   348             if ((*_bucket)[v] == under_bucket) {
   349               if (!(*_active)[v] && v != target) {
   350                 activate(v);
   351               }
   352               if (!_tolerance.less(rem, excess)) {
   353                 (*_flow)[a] -= excess;
   354                 (*_excess)[v] += excess;
   355                 excess = 0;
   356                 goto no_more_push;
   357               } else {
   358                 excess -= rem;
   359                 (*_excess)[v] += rem;
   360                 (*_flow)[a] = 0;
   361               }
   362             } else if (next_bucket > (*_bucket)[v]) {
   363               next_bucket = (*_bucket)[v];
   364             }
   365           }
   366 
   367         no_more_push:
   368 
   369           (*_excess)[n] = excess;
   370 
   371           if (excess != 0) {
   372             if ((*_next)[n] == INVALID) {
   373               typename std::list<std::list<int> >::iterator new_set =
   374                 _sets.insert(--_sets.end(), std::list<int>());
   375               new_set->splice(new_set->end(), _sets.back(),
   376                               _sets.back().begin(), ++_highest);
   377               for (std::list<int>::iterator it = new_set->begin();
   378                    it != new_set->end(); ++it) {
   379                 _dormant[*it] = true;
   380               }
   381               while (_highest != _sets.back().end() &&
   382                      !(*_active)[_first[*_highest]]) {
   383                 ++_highest;
   384               }
   385             } else if (next_bucket == _node_num) {
   386               _first[(*_bucket)[n]] = (*_next)[n];
   387               (*_prev)[(*_next)[n]] = INVALID;
   388 
   389               std::list<std::list<int> >::iterator new_set =
   390                 _sets.insert(--_sets.end(), std::list<int>());
   391 
   392               new_set->push_front(bucket_num);
   393               (*_bucket)[n] = bucket_num;
   394               _first[bucket_num] = _last[bucket_num] = n;
   395               (*_next)[n] = INVALID;
   396               (*_prev)[n] = INVALID;
   397               _dormant[bucket_num] = true;
   398               ++bucket_num;
   399 
   400               while (_highest != _sets.back().end() &&
   401                      !(*_active)[_first[*_highest]]) {
   402                 ++_highest;
   403               }
   404             } else {
   405               _first[*_highest] = (*_next)[n];
   406               (*_prev)[(*_next)[n]] = INVALID;
   407 
   408               while (next_bucket != *_highest) {
   409                 --_highest;
   410               }
   411 
   412               if (_highest == _sets.back().begin()) {
   413                 _sets.back().push_front(bucket_num);
   414                 _dormant[bucket_num] = false;
   415                 _first[bucket_num] = _last[bucket_num] = INVALID;
   416                 ++bucket_num;
   417               }
   418               --_highest;
   419 
   420               (*_bucket)[n] = *_highest;
   421               (*_next)[n] = _first[*_highest];
   422               if (_first[*_highest] != INVALID) {
   423                 (*_prev)[_first[*_highest]] = n;
   424               } else {
   425                 _last[*_highest] = n;
   426               }
   427               _first[*_highest] = n;
   428             }
   429           } else {
   430 
   431             deactivate(n);
   432             if (!(*_active)[_first[*_highest]]) {
   433               ++_highest;
   434               if (_highest != _sets.back().end() &&
   435                   !(*_active)[_first[*_highest]]) {
   436                 _highest = _sets.back().end();
   437               }
   438             }
   439           }
   440         }
   441 
   442         if ((*_excess)[target] < _min_cut) {
   443           _min_cut = (*_excess)[target];
   444           for (NodeIt i(_graph); i != INVALID; ++i) {
   445             (*_min_cut_map)[i] = true;
   446           }
   447           for (std::list<int>::iterator it = _sets.back().begin();
   448                it != _sets.back().end(); ++it) {
   449             Node n = _first[*it];
   450             while (n != INVALID) {
   451               (*_min_cut_map)[n] = false;
   452               n = (*_next)[n];
   453             }
   454           }
   455         }
   456 
   457         {
   458           Node new_target;
   459           if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
   460             if ((*_next)[target] == INVALID) {
   461               _last[(*_bucket)[target]] = (*_prev)[target];
   462               new_target = (*_prev)[target];
   463             } else {
   464               (*_prev)[(*_next)[target]] = (*_prev)[target];
   465               new_target = (*_next)[target];
   466             }
   467             if ((*_prev)[target] == INVALID) {
   468               _first[(*_bucket)[target]] = (*_next)[target];
   469             } else {
   470               (*_next)[(*_prev)[target]] = (*_next)[target];
   471             }
   472           } else {
   473             _sets.back().pop_back();
   474             if (_sets.back().empty()) {
   475               _sets.pop_back();
   476               if (_sets.empty())
   477                 break;
   478               for (std::list<int>::iterator it = _sets.back().begin();
   479                    it != _sets.back().end(); ++it) {
   480                 _dormant[*it] = false;
   481               }
   482             }
   483             new_target = _last[_sets.back().back()];
   484           }
   485 
   486           (*_bucket)[target] = 0;
   487 
   488           (*_source_set)[target] = true;
   489           for (OutArcIt a(_graph, target); a != INVALID; ++a) {
   490             Value rem = (*_capacity)[a] - (*_flow)[a];
   491             if (!_tolerance.positive(rem)) continue;
   492             Node v = _graph.target(a);
   493             if (!(*_active)[v] && !(*_source_set)[v]) {
   494               activate(v);
   495             }
   496             (*_excess)[v] += rem;
   497             (*_flow)[a] = (*_capacity)[a];
   498           }
   499 
   500           for (InArcIt a(_graph, target); a != INVALID; ++a) {
   501             Value rem = (*_flow)[a];
   502             if (!_tolerance.positive(rem)) continue;
   503             Node v = _graph.source(a);
   504             if (!(*_active)[v] && !(*_source_set)[v]) {
   505               activate(v);
   506             }
   507             (*_excess)[v] += rem;
   508             (*_flow)[a] = 0;
   509           }
   510 
   511           target = new_target;
   512           if ((*_active)[target]) {
   513             deactivate(target);
   514           }
   515 
   516           _highest = _sets.back().begin();
   517           while (_highest != _sets.back().end() &&
   518                  !(*_active)[_first[*_highest]]) {
   519             ++_highest;
   520           }
   521         }
   522       }
   523     }
   524 
   525     void findMinCutIn() {
   526 
   527       for (NodeIt n(_graph); n != INVALID; ++n) {
   528         (*_excess)[n] = 0;
   529         (*_source_set)[n] = false;
   530       }
   531 
   532       for (ArcIt a(_graph); a != INVALID; ++a) {
   533         (*_flow)[a] = 0;
   534       }
   535 
   536       int bucket_num = 0;
   537       std::vector<Node> queue(_node_num);
   538       int qfirst = 0, qlast = 0, qsep = 0;
   539 
   540       {
   541         typename Digraph::template NodeMap<bool> reached(_graph, false);
   542 
   543         reached[_source] = true;
   544 
   545         bool first_set = true;
   546 
   547         for (NodeIt t(_graph); t != INVALID; ++t) {
   548           if (reached[t]) continue;
   549           _sets.push_front(std::list<int>());
   550 
   551           queue[qlast++] = t;
   552           reached[t] = true;
   553 
   554           while (qfirst != qlast) {
   555             if (qsep == qfirst) {
   556               ++bucket_num;
   557               _sets.front().push_front(bucket_num);
   558               _dormant[bucket_num] = !first_set;
   559               _first[bucket_num] = _last[bucket_num] = INVALID;
   560               qsep = qlast;
   561             }
   562 
   563             Node n = queue[qfirst++];
   564             addItem(n, bucket_num);
   565 
   566             for (OutArcIt a(_graph, n); a != INVALID; ++a) {
   567               Node u = _graph.target(a);
   568               if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
   569                 reached[u] = true;
   570                 queue[qlast++] = u;
   571               }
   572             }
   573           }
   574           first_set = false;
   575         }
   576 
   577         ++bucket_num;
   578         (*_bucket)[_source] = 0;
   579         _dormant[0] = true;
   580       }
   581       (*_source_set)[_source] = true;
   582 
   583       Node target = _last[_sets.back().back()];
   584       {
   585         for (InArcIt a(_graph, _source); a != INVALID; ++a) {
   586           if (_tolerance.positive((*_capacity)[a])) {
   587             Node u = _graph.source(a);
   588             (*_flow)[a] = (*_capacity)[a];
   589             (*_excess)[u] += (*_capacity)[a];
   590             if (!(*_active)[u] && u != _source) {
   591               activate(u);
   592             }
   593           }
   594         }
   595         if ((*_active)[target]) {
   596           deactivate(target);
   597         }
   598 
   599         _highest = _sets.back().begin();
   600         while (_highest != _sets.back().end() &&
   601                !(*_active)[_first[*_highest]]) {
   602           ++_highest;
   603         }
   604       }
   605 
   606 
   607       while (true) {
   608         while (_highest != _sets.back().end()) {
   609           Node n = _first[*_highest];
   610           Value excess = (*_excess)[n];
   611           int next_bucket = _node_num;
   612 
   613           int under_bucket;
   614           if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
   615             under_bucket = -1;
   616           } else {
   617             under_bucket = *(++std::list<int>::iterator(_highest));
   618           }
   619 
   620           for (InArcIt a(_graph, n); a != INVALID; ++a) {
   621             Node v = _graph.source(a);
   622             if (_dormant[(*_bucket)[v]]) continue;
   623             Value rem = (*_capacity)[a] - (*_flow)[a];
   624             if (!_tolerance.positive(rem)) continue;
   625             if ((*_bucket)[v] == under_bucket) {
   626               if (!(*_active)[v] && v != target) {
   627                 activate(v);
   628               }
   629               if (!_tolerance.less(rem, excess)) {
   630                 (*_flow)[a] += excess;
   631                 (*_excess)[v] += excess;
   632                 excess = 0;
   633                 goto no_more_push;
   634               } else {
   635                 excess -= rem;
   636                 (*_excess)[v] += rem;
   637                 (*_flow)[a] = (*_capacity)[a];
   638               }
   639             } else if (next_bucket > (*_bucket)[v]) {
   640               next_bucket = (*_bucket)[v];
   641             }
   642           }
   643 
   644           for (OutArcIt a(_graph, n); a != INVALID; ++a) {
   645             Node v = _graph.target(a);
   646             if (_dormant[(*_bucket)[v]]) continue;
   647             Value rem = (*_flow)[a];
   648             if (!_tolerance.positive(rem)) continue;
   649             if ((*_bucket)[v] == under_bucket) {
   650               if (!(*_active)[v] && v != target) {
   651                 activate(v);
   652               }
   653               if (!_tolerance.less(rem, excess)) {
   654                 (*_flow)[a] -= excess;
   655                 (*_excess)[v] += excess;
   656                 excess = 0;
   657                 goto no_more_push;
   658               } else {
   659                 excess -= rem;
   660                 (*_excess)[v] += rem;
   661                 (*_flow)[a] = 0;
   662               }
   663             } else if (next_bucket > (*_bucket)[v]) {
   664               next_bucket = (*_bucket)[v];
   665             }
   666           }
   667 
   668         no_more_push:
   669 
   670           (*_excess)[n] = excess;
   671 
   672           if (excess != 0) {
   673             if ((*_next)[n] == INVALID) {
   674               typename std::list<std::list<int> >::iterator new_set =
   675                 _sets.insert(--_sets.end(), std::list<int>());
   676               new_set->splice(new_set->end(), _sets.back(),
   677                               _sets.back().begin(), ++_highest);
   678               for (std::list<int>::iterator it = new_set->begin();
   679                    it != new_set->end(); ++it) {
   680                 _dormant[*it] = true;
   681               }
   682               while (_highest != _sets.back().end() &&
   683                      !(*_active)[_first[*_highest]]) {
   684                 ++_highest;
   685               }
   686             } else if (next_bucket == _node_num) {
   687               _first[(*_bucket)[n]] = (*_next)[n];
   688               (*_prev)[(*_next)[n]] = INVALID;
   689 
   690               std::list<std::list<int> >::iterator new_set =
   691                 _sets.insert(--_sets.end(), std::list<int>());
   692 
   693               new_set->push_front(bucket_num);
   694               (*_bucket)[n] = bucket_num;
   695               _first[bucket_num] = _last[bucket_num] = n;
   696               (*_next)[n] = INVALID;
   697               (*_prev)[n] = INVALID;
   698               _dormant[bucket_num] = true;
   699               ++bucket_num;
   700 
   701               while (_highest != _sets.back().end() &&
   702                      !(*_active)[_first[*_highest]]) {
   703                 ++_highest;
   704               }
   705             } else {
   706               _first[*_highest] = (*_next)[n];
   707               (*_prev)[(*_next)[n]] = INVALID;
   708 
   709               while (next_bucket != *_highest) {
   710                 --_highest;
   711               }
   712               if (_highest == _sets.back().begin()) {
   713                 _sets.back().push_front(bucket_num);
   714                 _dormant[bucket_num] = false;
   715                 _first[bucket_num] = _last[bucket_num] = INVALID;
   716                 ++bucket_num;
   717               }
   718               --_highest;
   719 
   720               (*_bucket)[n] = *_highest;
   721               (*_next)[n] = _first[*_highest];
   722               if (_first[*_highest] != INVALID) {
   723                 (*_prev)[_first[*_highest]] = n;
   724               } else {
   725                 _last[*_highest] = n;
   726               }
   727               _first[*_highest] = n;
   728             }
   729           } else {
   730 
   731             deactivate(n);
   732             if (!(*_active)[_first[*_highest]]) {
   733               ++_highest;
   734               if (_highest != _sets.back().end() &&
   735                   !(*_active)[_first[*_highest]]) {
   736                 _highest = _sets.back().end();
   737               }
   738             }
   739           }
   740         }
   741 
   742         if ((*_excess)[target] < _min_cut) {
   743           _min_cut = (*_excess)[target];
   744           for (NodeIt i(_graph); i != INVALID; ++i) {
   745             (*_min_cut_map)[i] = false;
   746           }
   747           for (std::list<int>::iterator it = _sets.back().begin();
   748                it != _sets.back().end(); ++it) {
   749             Node n = _first[*it];
   750             while (n != INVALID) {
   751               (*_min_cut_map)[n] = true;
   752               n = (*_next)[n];
   753             }
   754           }
   755         }
   756 
   757         {
   758           Node new_target;
   759           if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
   760             if ((*_next)[target] == INVALID) {
   761               _last[(*_bucket)[target]] = (*_prev)[target];
   762               new_target = (*_prev)[target];
   763             } else {
   764               (*_prev)[(*_next)[target]] = (*_prev)[target];
   765               new_target = (*_next)[target];
   766             }
   767             if ((*_prev)[target] == INVALID) {
   768               _first[(*_bucket)[target]] = (*_next)[target];
   769             } else {
   770               (*_next)[(*_prev)[target]] = (*_next)[target];
   771             }
   772           } else {
   773             _sets.back().pop_back();
   774             if (_sets.back().empty()) {
   775               _sets.pop_back();
   776               if (_sets.empty())
   777                 break;
   778               for (std::list<int>::iterator it = _sets.back().begin();
   779                    it != _sets.back().end(); ++it) {
   780                 _dormant[*it] = false;
   781               }
   782             }
   783             new_target = _last[_sets.back().back()];
   784           }
   785 
   786           (*_bucket)[target] = 0;
   787 
   788           (*_source_set)[target] = true;
   789           for (InArcIt a(_graph, target); a != INVALID; ++a) {
   790             Value rem = (*_capacity)[a] - (*_flow)[a];
   791             if (!_tolerance.positive(rem)) continue;
   792             Node v = _graph.source(a);
   793             if (!(*_active)[v] && !(*_source_set)[v]) {
   794               activate(v);
   795             }
   796             (*_excess)[v] += rem;
   797             (*_flow)[a] = (*_capacity)[a];
   798           }
   799 
   800           for (OutArcIt a(_graph, target); a != INVALID; ++a) {
   801             Value rem = (*_flow)[a];
   802             if (!_tolerance.positive(rem)) continue;
   803             Node v = _graph.target(a);
   804             if (!(*_active)[v] && !(*_source_set)[v]) {
   805               activate(v);
   806             }
   807             (*_excess)[v] += rem;
   808             (*_flow)[a] = 0;
   809           }
   810 
   811           target = new_target;
   812           if ((*_active)[target]) {
   813             deactivate(target);
   814           }
   815 
   816           _highest = _sets.back().begin();
   817           while (_highest != _sets.back().end() &&
   818                  !(*_active)[_first[*_highest]]) {
   819             ++_highest;
   820           }
   821         }
   822       }
   823     }
   824 
   825   public:
   826 
   827     /// \name Execution Control
   828     /// The simplest way to execute the algorithm is to use
   829     /// one of the member functions called \ref run().
   830     /// \n
   831     /// If you need better control on the execution,
   832     /// you have to call one of the \ref init() functions first, then
   833     /// \ref calculateOut() and/or \ref calculateIn().
   834 
   835     /// @{
   836 
   837     /// \brief Initialize the internal data structures.
   838     ///
   839     /// This function initializes the internal data structures. It creates
   840     /// the maps and some bucket structures for the algorithm.
   841     /// The first node is used as the source node for the push-relabel
   842     /// algorithm.
   843     void init() {
   844       init(NodeIt(_graph));
   845     }
   846 
   847     /// \brief Initialize the internal data structures.
   848     ///
   849     /// This function initializes the internal data structures. It creates
   850     /// the maps and some bucket structures for the algorithm. 
   851     /// The given node is used as the source node for the push-relabel
   852     /// algorithm.
   853     void init(const Node& source) {
   854       _source = source;
   855 
   856       _node_num = countNodes(_graph);
   857 
   858       _first.resize(_node_num);
   859       _last.resize(_node_num);
   860 
   861       _dormant.resize(_node_num);
   862 
   863       if (!_flow) {
   864         _flow = new FlowMap(_graph);
   865       }
   866       if (!_next) {
   867         _next = new typename Digraph::template NodeMap<Node>(_graph);
   868       }
   869       if (!_prev) {
   870         _prev = new typename Digraph::template NodeMap<Node>(_graph);
   871       }
   872       if (!_active) {
   873         _active = new typename Digraph::template NodeMap<bool>(_graph);
   874       }
   875       if (!_bucket) {
   876         _bucket = new typename Digraph::template NodeMap<int>(_graph);
   877       }
   878       if (!_excess) {
   879         _excess = new ExcessMap(_graph);
   880       }
   881       if (!_source_set) {
   882         _source_set = new SourceSetMap(_graph);
   883       }
   884       if (!_min_cut_map) {
   885         _min_cut_map = new MinCutMap(_graph);
   886       }
   887 
   888       _min_cut = std::numeric_limits<Value>::max();
   889     }
   890 
   891 
   892     /// \brief Calculate a minimum cut with \f$ source \f$ on the
   893     /// source-side.
   894     ///
   895     /// This function calculates a minimum cut with \f$ source \f$ on the
   896     /// source-side (i.e. a set \f$ X\subsetneq V \f$ with
   897     /// \f$ source \in X \f$ and minimal outgoing capacity).
   898     ///
   899     /// \pre \ref init() must be called before using this function.
   900     void calculateOut() {
   901       findMinCutOut();
   902     }
   903 
   904     /// \brief Calculate a minimum cut with \f$ source \f$ on the
   905     /// sink-side.
   906     ///
   907     /// This function calculates a minimum cut with \f$ source \f$ on the
   908     /// sink-side (i.e. a set \f$ X\subsetneq V \f$ with
   909     /// \f$ source \notin X \f$ and minimal outgoing capacity).
   910     ///
   911     /// \pre \ref init() must be called before using this function.
   912     void calculateIn() {
   913       findMinCutIn();
   914     }
   915 
   916 
   917     /// \brief Run the algorithm.
   918     ///
   919     /// This function runs the algorithm. It finds nodes \c source and
   920     /// \c target arbitrarily and then calls \ref init(), \ref calculateOut()
   921     /// and \ref calculateIn().
   922     void run() {
   923       init();
   924       calculateOut();
   925       calculateIn();
   926     }
   927 
   928     /// \brief Run the algorithm.
   929     ///
   930     /// This function runs the algorithm. It uses the given \c source node, 
   931     /// finds a proper \c target node and then calls the \ref init(),
   932     /// \ref calculateOut() and \ref calculateIn().
   933     void run(const Node& s) {
   934       init(s);
   935       calculateOut();
   936       calculateIn();
   937     }
   938 
   939     /// @}
   940 
   941     /// \name Query Functions
   942     /// The result of the %HaoOrlin algorithm
   943     /// can be obtained using these functions.\n
   944     /// \ref run(), \ref calculateOut() or \ref calculateIn() 
   945     /// should be called before using them.
   946 
   947     /// @{
   948 
   949     /// \brief Return the value of the minimum cut.
   950     ///
   951     /// This function returns the value of the minimum cut.
   952     ///
   953     /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 
   954     /// must be called before using this function.
   955     Value minCutValue() const {
   956       return _min_cut;
   957     }
   958 
   959 
   960     /// \brief Return a minimum cut.
   961     ///
   962     /// This function sets \c cutMap to the characteristic vector of a
   963     /// minimum value cut: it will give a non-empty set \f$ X\subsetneq V \f$
   964     /// with minimal outgoing capacity (i.e. \c cutMap will be \c true exactly
   965     /// for the nodes of \f$ X \f$).
   966     ///
   967     /// \param cutMap A \ref concepts::WriteMap "writable" node map with
   968     /// \c bool (or convertible) value type.
   969     ///
   970     /// \return The value of the minimum cut.
   971     ///
   972     /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 
   973     /// must be called before using this function.
   974     template <typename CutMap>
   975     Value minCutMap(CutMap& cutMap) const {
   976       for (NodeIt it(_graph); it != INVALID; ++it) {
   977         cutMap.set(it, (*_min_cut_map)[it]);
   978       }
   979       return _min_cut;
   980     }
   981 
   982     /// @}
   983 
   984   }; //class HaoOrlin
   985 
   986 } //namespace lemon
   987 
   988 #endif //LEMON_HAO_ORLIN_H