lemon/nagamochi_ibaraki.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 936 ddd3c0d3d9bf
child 978 eb252f805431
permissions -rw-r--r--
Implement the scaling Price Refinement heuristic in CostScaling (#417)
instead of Early Termination.

These two heuristics are similar, but the newer one is faster
and not only makes it possible to skip some epsilon phases, but
it can improve the performance of the other phases, as well.
     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-2010
     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_NAGAMOCHI_IBARAKI_H
    20 #define LEMON_NAGAMOCHI_IBARAKI_H
    21 
    22 
    23 /// \ingroup min_cut
    24 /// \file
    25 /// \brief Implementation of the Nagamochi-Ibaraki algorithm.
    26 
    27 #include <lemon/core.h>
    28 #include <lemon/bin_heap.h>
    29 #include <lemon/bucket_heap.h>
    30 #include <lemon/maps.h>
    31 #include <lemon/radix_sort.h>
    32 #include <lemon/unionfind.h>
    33 
    34 #include <cassert>
    35 
    36 namespace lemon {
    37 
    38   /// \brief Default traits class for NagamochiIbaraki class.
    39   ///
    40   /// Default traits class for NagamochiIbaraki class.
    41   /// \param GR The undirected graph type.
    42   /// \param CM Type of capacity map.
    43   template <typename GR, typename CM>
    44   struct NagamochiIbarakiDefaultTraits {
    45     /// The type of the capacity map.
    46     typedef typename CM::Value Value;
    47 
    48     /// The undirected graph type the algorithm runs on.
    49     typedef GR Graph;
    50 
    51     /// \brief The type of the map that stores the edge capacities.
    52     ///
    53     /// The type of the map that stores the edge capacities.
    54     /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
    55     typedef CM CapacityMap;
    56 
    57     /// \brief Instantiates a CapacityMap.
    58     ///
    59     /// This function instantiates a \ref CapacityMap.
    60 #ifdef DOXYGEN
    61     static CapacityMap *createCapacityMap(const Graph& graph)
    62 #else
    63     static CapacityMap *createCapacityMap(const Graph&)
    64 #endif
    65     {
    66         LEMON_ASSERT(false, "CapacityMap is not initialized");
    67         return 0; // ignore warnings
    68     }
    69 
    70     /// \brief The cross reference type used by heap.
    71     ///
    72     /// The cross reference type used by heap.
    73     /// Usually \c Graph::NodeMap<int>.
    74     typedef typename Graph::template NodeMap<int> HeapCrossRef;
    75 
    76     /// \brief Instantiates a HeapCrossRef.
    77     ///
    78     /// This function instantiates a \ref HeapCrossRef.
    79     /// \param g is the graph, to which we would like to define the
    80     /// \ref HeapCrossRef.
    81     static HeapCrossRef *createHeapCrossRef(const Graph& g) {
    82       return new HeapCrossRef(g);
    83     }
    84 
    85     /// \brief The heap type used by NagamochiIbaraki algorithm.
    86     ///
    87     /// The heap type used by NagamochiIbaraki algorithm. It has to
    88     /// maximize the priorities.
    89     ///
    90     /// \sa BinHeap
    91     /// \sa NagamochiIbaraki
    92     typedef BinHeap<Value, HeapCrossRef, std::greater<Value> > Heap;
    93 
    94     /// \brief Instantiates a Heap.
    95     ///
    96     /// This function instantiates a \ref Heap.
    97     /// \param r is the cross reference of the heap.
    98     static Heap *createHeap(HeapCrossRef& r) {
    99       return new Heap(r);
   100     }
   101   };
   102 
   103   /// \ingroup min_cut
   104   ///
   105   /// \brief Calculates the minimum cut in an undirected graph.
   106   ///
   107   /// Calculates the minimum cut in an undirected graph with the
   108   /// Nagamochi-Ibaraki algorithm. The algorithm separates the graph's
   109   /// nodes into two partitions with the minimum sum of edge capacities
   110   /// between the two partitions. The algorithm can be used to test
   111   /// the network reliability, especially to test how many links have
   112   /// to be destroyed in the network to split it to at least two
   113   /// distinict subnetworks.
   114   ///
   115   /// The complexity of the algorithm is \f$ O(nm\log(n)) \f$ but with
   116   /// \ref FibHeap "Fibonacci heap" it can be decreased to
   117   /// \f$ O(nm+n^2\log(n)) \f$.  When the edges have unit capacities,
   118   /// \c BucketHeap can be used which yields \f$ O(nm) \f$ time
   119   /// complexity.
   120   ///
   121   /// \warning The value type of the capacity map should be able to
   122   /// hold any cut value of the graph, otherwise the result can
   123   /// overflow.
   124   /// \note This capacity is supposed to be integer type.
   125 #ifdef DOXYGEN
   126   template <typename GR, typename CM, typename TR>
   127 #else
   128   template <typename GR,
   129             typename CM = typename GR::template EdgeMap<int>,
   130             typename TR = NagamochiIbarakiDefaultTraits<GR, CM> >
   131 #endif
   132   class NagamochiIbaraki {
   133   public:
   134 
   135     typedef TR Traits;
   136     /// The type of the underlying graph.
   137     typedef typename Traits::Graph Graph;
   138 
   139     /// The type of the capacity map.
   140     typedef typename Traits::CapacityMap CapacityMap;
   141     /// The value type of the capacity map.
   142     typedef typename Traits::CapacityMap::Value Value;
   143 
   144     /// The heap type used by the algorithm.
   145     typedef typename Traits::Heap Heap;
   146     /// The cross reference type used for the heap.
   147     typedef typename Traits::HeapCrossRef HeapCrossRef;
   148 
   149     ///\name Named template parameters
   150 
   151     ///@{
   152 
   153     struct SetUnitCapacityTraits : public Traits {
   154       typedef ConstMap<typename Graph::Edge, Const<int, 1> > CapacityMap;
   155       static CapacityMap *createCapacityMap(const Graph&) {
   156         return new CapacityMap();
   157       }
   158     };
   159 
   160     /// \brief \ref named-templ-param "Named parameter" for setting
   161     /// the capacity map to a constMap<Edge, int, 1>() instance
   162     ///
   163     /// \ref named-templ-param "Named parameter" for setting
   164     /// the capacity map to a constMap<Edge, int, 1>() instance
   165     struct SetUnitCapacity
   166       : public NagamochiIbaraki<Graph, CapacityMap,
   167                                 SetUnitCapacityTraits> {
   168       typedef NagamochiIbaraki<Graph, CapacityMap,
   169                                SetUnitCapacityTraits> Create;
   170     };
   171 
   172 
   173     template <class H, class CR>
   174     struct SetHeapTraits : public Traits {
   175       typedef CR HeapCrossRef;
   176       typedef H Heap;
   177       static HeapCrossRef *createHeapCrossRef(int num) {
   178         LEMON_ASSERT(false, "HeapCrossRef is not initialized");
   179         return 0; // ignore warnings
   180       }
   181       static Heap *createHeap(HeapCrossRef &) {
   182         LEMON_ASSERT(false, "Heap is not initialized");
   183         return 0; // ignore warnings
   184       }
   185     };
   186 
   187     /// \brief \ref named-templ-param "Named parameter" for setting
   188     /// heap and cross reference type
   189     ///
   190     /// \ref named-templ-param "Named parameter" for setting heap and
   191     /// cross reference type. The heap has to maximize the priorities.
   192     template <class H, class CR = RangeMap<int> >
   193     struct SetHeap
   194       : public NagamochiIbaraki<Graph, CapacityMap, SetHeapTraits<H, CR> > {
   195       typedef NagamochiIbaraki< Graph, CapacityMap, SetHeapTraits<H, CR> >
   196       Create;
   197     };
   198 
   199     template <class H, class CR>
   200     struct SetStandardHeapTraits : public Traits {
   201       typedef CR HeapCrossRef;
   202       typedef H Heap;
   203       static HeapCrossRef *createHeapCrossRef(int size) {
   204         return new HeapCrossRef(size);
   205       }
   206       static Heap *createHeap(HeapCrossRef &crossref) {
   207         return new Heap(crossref);
   208       }
   209     };
   210 
   211     /// \brief \ref named-templ-param "Named parameter" for setting
   212     /// heap and cross reference type with automatic allocation
   213     ///
   214     /// \ref named-templ-param "Named parameter" for setting heap and
   215     /// cross reference type with automatic allocation. They should
   216     /// have standard constructor interfaces to be able to
   217     /// automatically created by the algorithm (i.e. the graph should
   218     /// be passed to the constructor of the cross reference and the
   219     /// cross reference should be passed to the constructor of the
   220     /// heap). However, external heap and cross reference objects
   221     /// could also be passed to the algorithm using the \ref heap()
   222     /// function before calling \ref run() or \ref init(). The heap
   223     /// has to maximize the priorities.
   224     /// \sa SetHeap
   225     template <class H, class CR = RangeMap<int> >
   226     struct SetStandardHeap
   227       : public NagamochiIbaraki<Graph, CapacityMap,
   228                                 SetStandardHeapTraits<H, CR> > {
   229       typedef NagamochiIbaraki<Graph, CapacityMap,
   230                                SetStandardHeapTraits<H, CR> > Create;
   231     };
   232 
   233     ///@}
   234 
   235 
   236   private:
   237 
   238     const Graph &_graph;
   239     const CapacityMap *_capacity;
   240     bool _local_capacity; // unit capacity
   241 
   242     struct ArcData {
   243       typename Graph::Node target;
   244       int prev, next;
   245     };
   246     struct EdgeData {
   247       Value capacity;
   248       Value cut;
   249     };
   250 
   251     struct NodeData {
   252       int first_arc;
   253       typename Graph::Node prev, next;
   254       int curr_arc;
   255       typename Graph::Node last_rep;
   256       Value sum;
   257     };
   258 
   259     typename Graph::template NodeMap<NodeData> *_nodes;
   260     std::vector<ArcData> _arcs;
   261     std::vector<EdgeData> _edges;
   262 
   263     typename Graph::Node _first_node;
   264     int _node_num;
   265 
   266     Value _min_cut;
   267 
   268     HeapCrossRef *_heap_cross_ref;
   269     bool _local_heap_cross_ref;
   270     Heap *_heap;
   271     bool _local_heap;
   272 
   273     typedef typename Graph::template NodeMap<typename Graph::Node> NodeList;
   274     NodeList *_next_rep;
   275 
   276     typedef typename Graph::template NodeMap<bool> MinCutMap;
   277     MinCutMap *_cut_map;
   278 
   279     void createStructures() {
   280       if (!_nodes) {
   281         _nodes = new (typename Graph::template NodeMap<NodeData>)(_graph);
   282       }
   283       if (!_capacity) {
   284         _local_capacity = true;
   285         _capacity = Traits::createCapacityMap(_graph);
   286       }
   287       if (!_heap_cross_ref) {
   288         _local_heap_cross_ref = true;
   289         _heap_cross_ref = Traits::createHeapCrossRef(_graph);
   290       }
   291       if (!_heap) {
   292         _local_heap = true;
   293         _heap = Traits::createHeap(*_heap_cross_ref);
   294       }
   295       if (!_next_rep) {
   296         _next_rep = new NodeList(_graph);
   297       }
   298       if (!_cut_map) {
   299         _cut_map = new MinCutMap(_graph);
   300       }
   301     }
   302 
   303   public :
   304 
   305     typedef NagamochiIbaraki Create;
   306 
   307 
   308     /// \brief Constructor.
   309     ///
   310     /// \param graph The graph the algorithm runs on.
   311     /// \param capacity The capacity map used by the algorithm.
   312     NagamochiIbaraki(const Graph& graph, const CapacityMap& capacity)
   313       : _graph(graph), _capacity(&capacity), _local_capacity(false),
   314         _nodes(0), _arcs(), _edges(), _min_cut(),
   315         _heap_cross_ref(0), _local_heap_cross_ref(false),
   316         _heap(0), _local_heap(false),
   317         _next_rep(0), _cut_map(0) {}
   318 
   319     /// \brief Constructor.
   320     ///
   321     /// This constructor can be used only when the Traits class
   322     /// defines how can the local capacity map be instantiated.
   323     /// If the SetUnitCapacity used the algorithm automatically
   324     /// constructs the capacity map.
   325     ///
   326     ///\param graph The graph the algorithm runs on.
   327     NagamochiIbaraki(const Graph& graph)
   328       : _graph(graph), _capacity(0), _local_capacity(false),
   329         _nodes(0), _arcs(), _edges(), _min_cut(),
   330         _heap_cross_ref(0), _local_heap_cross_ref(false),
   331         _heap(0), _local_heap(false),
   332         _next_rep(0), _cut_map(0) {}
   333 
   334     /// \brief Destructor.
   335     ///
   336     /// Destructor.
   337     ~NagamochiIbaraki() {
   338       if (_local_capacity) delete _capacity;
   339       if (_nodes) delete _nodes;
   340       if (_local_heap) delete _heap;
   341       if (_local_heap_cross_ref) delete _heap_cross_ref;
   342       if (_next_rep) delete _next_rep;
   343       if (_cut_map) delete _cut_map;
   344     }
   345 
   346     /// \brief Sets the heap and the cross reference used by algorithm.
   347     ///
   348     /// Sets the heap and the cross reference used by algorithm.
   349     /// If you don't use this function before calling \ref run(),
   350     /// it will allocate one. The destuctor deallocates this
   351     /// automatically allocated heap and cross reference, of course.
   352     /// \return <tt> (*this) </tt>
   353     NagamochiIbaraki &heap(Heap& hp, HeapCrossRef &cr)
   354     {
   355       if (_local_heap_cross_ref) {
   356         delete _heap_cross_ref;
   357         _local_heap_cross_ref = false;
   358       }
   359       _heap_cross_ref = &cr;
   360       if (_local_heap) {
   361         delete _heap;
   362         _local_heap = false;
   363       }
   364       _heap = &hp;
   365       return *this;
   366     }
   367 
   368     /// \name Execution control
   369     /// The simplest way to execute the algorithm is to use
   370     /// one of the member functions called \c run().
   371     /// \n
   372     /// If you need more control on the execution,
   373     /// first you must call \ref init() and then call the start()
   374     /// or proper times the processNextPhase() member functions.
   375 
   376     ///@{
   377 
   378     /// \brief Initializes the internal data structures.
   379     ///
   380     /// Initializes the internal data structures.
   381     void init() {
   382       createStructures();
   383 
   384       int edge_num = countEdges(_graph);
   385       _edges.resize(edge_num);
   386       _arcs.resize(2 * edge_num);
   387 
   388       typename Graph::Node prev = INVALID;
   389       _node_num = 0;
   390       for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
   391         (*_cut_map)[n] = false;
   392         (*_next_rep)[n] = INVALID;
   393         (*_nodes)[n].last_rep = n;
   394         (*_nodes)[n].first_arc = -1;
   395         (*_nodes)[n].curr_arc = -1;
   396         (*_nodes)[n].prev = prev;
   397         if (prev != INVALID) {
   398           (*_nodes)[prev].next = n;
   399         }
   400         (*_nodes)[n].next = INVALID;
   401         (*_nodes)[n].sum = 0;
   402         prev = n;
   403         ++_node_num;
   404       }
   405 
   406       _first_node = typename Graph::NodeIt(_graph);
   407 
   408       int index = 0;
   409       for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
   410         for (typename Graph::OutArcIt a(_graph, n); a != INVALID; ++a) {
   411           typename Graph::Node m = _graph.target(a);
   412           
   413           if (!(n < m)) continue;
   414 
   415           (*_nodes)[n].sum += (*_capacity)[a];
   416           (*_nodes)[m].sum += (*_capacity)[a];
   417           
   418           int c = (*_nodes)[m].curr_arc;
   419           if (c != -1 && _arcs[c ^ 1].target == n) {
   420             _edges[c >> 1].capacity += (*_capacity)[a];
   421           } else {
   422             _edges[index].capacity = (*_capacity)[a];
   423             
   424             _arcs[index << 1].prev = -1;
   425             if ((*_nodes)[n].first_arc != -1) {
   426               _arcs[(*_nodes)[n].first_arc].prev = (index << 1);
   427             }
   428             _arcs[index << 1].next = (*_nodes)[n].first_arc;
   429             (*_nodes)[n].first_arc = (index << 1);
   430             _arcs[index << 1].target = m;
   431 
   432             (*_nodes)[m].curr_arc = (index << 1);
   433             
   434             _arcs[(index << 1) | 1].prev = -1;
   435             if ((*_nodes)[m].first_arc != -1) {
   436               _arcs[(*_nodes)[m].first_arc].prev = ((index << 1) | 1);
   437             }
   438             _arcs[(index << 1) | 1].next = (*_nodes)[m].first_arc;
   439             (*_nodes)[m].first_arc = ((index << 1) | 1);
   440             _arcs[(index << 1) | 1].target = n;
   441             
   442             ++index;
   443           }
   444         }
   445       }
   446 
   447       typename Graph::Node cut_node = INVALID;
   448       _min_cut = std::numeric_limits<Value>::max();
   449 
   450       for (typename Graph::Node n = _first_node; 
   451            n != INVALID; n = (*_nodes)[n].next) {
   452         if ((*_nodes)[n].sum < _min_cut) {
   453           cut_node = n;
   454           _min_cut = (*_nodes)[n].sum;
   455         }
   456       }
   457       (*_cut_map)[cut_node] = true;
   458       if (_min_cut == 0) {
   459         _first_node = INVALID;
   460       }
   461     }
   462 
   463   public:
   464 
   465     /// \brief Processes the next phase
   466     ///
   467     /// Processes the next phase in the algorithm. It must be called
   468     /// at most one less the number of the nodes in the graph.
   469     ///
   470     ///\return %True when the algorithm finished.
   471     bool processNextPhase() {
   472       if (_first_node == INVALID) return true;
   473 
   474       _heap->clear();
   475       for (typename Graph::Node n = _first_node; 
   476            n != INVALID; n = (*_nodes)[n].next) {
   477         (*_heap_cross_ref)[n] = Heap::PRE_HEAP;
   478       }
   479 
   480       std::vector<typename Graph::Node> order;
   481       order.reserve(_node_num);
   482       int sep = 0;
   483 
   484       Value alpha = 0;
   485       Value pmc = std::numeric_limits<Value>::max();
   486 
   487       _heap->push(_first_node, static_cast<Value>(0));
   488       while (!_heap->empty()) {
   489         typename Graph::Node n = _heap->top();
   490         Value v = _heap->prio();
   491 
   492         _heap->pop();
   493         for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
   494           switch (_heap->state(_arcs[a].target)) {
   495           case Heap::PRE_HEAP: 
   496             {
   497               Value nv = _edges[a >> 1].capacity;
   498               _heap->push(_arcs[a].target, nv);
   499               _edges[a >> 1].cut = nv;
   500             } break;
   501           case Heap::IN_HEAP:
   502             {
   503               Value nv = _edges[a >> 1].capacity + (*_heap)[_arcs[a].target];
   504               _heap->decrease(_arcs[a].target, nv);
   505               _edges[a >> 1].cut = nv;
   506             } break;
   507           case Heap::POST_HEAP:
   508             break;
   509           }
   510         }
   511 
   512         alpha += (*_nodes)[n].sum;
   513         alpha -= 2 * v;
   514 
   515         order.push_back(n);
   516         if (!_heap->empty()) {
   517           if (alpha < pmc) {
   518             pmc = alpha;
   519             sep = order.size();
   520           }
   521         }
   522       }
   523 
   524       if (static_cast<int>(order.size()) < _node_num) {
   525         _first_node = INVALID;
   526         for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
   527           (*_cut_map)[n] = false;
   528         }
   529         for (int i = 0; i < static_cast<int>(order.size()); ++i) {
   530           typename Graph::Node n = order[i];
   531           while (n != INVALID) {
   532             (*_cut_map)[n] = true;
   533             n = (*_next_rep)[n];
   534           }
   535         }
   536         _min_cut = 0;
   537         return true;
   538       }
   539 
   540       if (pmc < _min_cut) {
   541         for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
   542           (*_cut_map)[n] = false;
   543         }
   544         for (int i = 0; i < sep; ++i) {
   545           typename Graph::Node n = order[i];
   546           while (n != INVALID) {
   547             (*_cut_map)[n] = true;
   548             n = (*_next_rep)[n];
   549           }
   550         }
   551         _min_cut = pmc;
   552       }
   553 
   554       for (typename Graph::Node n = _first_node;
   555            n != INVALID; n = (*_nodes)[n].next) {
   556         bool merged = false;
   557         for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
   558           if (!(_edges[a >> 1].cut < pmc)) {
   559             if (!merged) {
   560               for (int b = (*_nodes)[n].first_arc; b != -1; b = _arcs[b].next) {
   561                 (*_nodes)[_arcs[b].target].curr_arc = b;          
   562               }
   563               merged = true;
   564             }
   565             typename Graph::Node m = _arcs[a].target;
   566             int nb = 0;
   567             for (int b = (*_nodes)[m].first_arc; b != -1; b = nb) {
   568               nb = _arcs[b].next;
   569               if ((b ^ a) == 1) continue;
   570               typename Graph::Node o = _arcs[b].target;
   571               int c = (*_nodes)[o].curr_arc; 
   572               if (c != -1 && _arcs[c ^ 1].target == n) {
   573                 _edges[c >> 1].capacity += _edges[b >> 1].capacity;
   574                 (*_nodes)[n].sum += _edges[b >> 1].capacity;
   575                 if (_edges[b >> 1].cut < _edges[c >> 1].cut) {
   576                   _edges[b >> 1].cut = _edges[c >> 1].cut;
   577                 }
   578                 if (_arcs[b ^ 1].prev != -1) {
   579                   _arcs[_arcs[b ^ 1].prev].next = _arcs[b ^ 1].next;
   580                 } else {
   581                   (*_nodes)[o].first_arc = _arcs[b ^ 1].next;
   582                 }
   583                 if (_arcs[b ^ 1].next != -1) {
   584                   _arcs[_arcs[b ^ 1].next].prev = _arcs[b ^ 1].prev;
   585                 }
   586               } else {
   587                 if (_arcs[a].next != -1) {
   588                   _arcs[_arcs[a].next].prev = b;
   589                 }
   590                 _arcs[b].next = _arcs[a].next;
   591                 _arcs[b].prev = a;
   592                 _arcs[a].next = b;
   593                 _arcs[b ^ 1].target = n;
   594 
   595                 (*_nodes)[n].sum += _edges[b >> 1].capacity;
   596                 (*_nodes)[o].curr_arc = b;
   597               }
   598             }
   599 
   600             if (_arcs[a].prev != -1) {
   601               _arcs[_arcs[a].prev].next = _arcs[a].next;
   602             } else {
   603               (*_nodes)[n].first_arc = _arcs[a].next;
   604             }            
   605             if (_arcs[a].next != -1) {
   606               _arcs[_arcs[a].next].prev = _arcs[a].prev;
   607             }
   608 
   609             (*_nodes)[n].sum -= _edges[a >> 1].capacity;
   610             (*_next_rep)[(*_nodes)[n].last_rep] = m;
   611             (*_nodes)[n].last_rep = (*_nodes)[m].last_rep;
   612             
   613             if ((*_nodes)[m].prev != INVALID) {
   614               (*_nodes)[(*_nodes)[m].prev].next = (*_nodes)[m].next;
   615             } else{
   616               _first_node = (*_nodes)[m].next;
   617             }
   618             if ((*_nodes)[m].next != INVALID) {
   619               (*_nodes)[(*_nodes)[m].next].prev = (*_nodes)[m].prev;
   620             }
   621             --_node_num;
   622           }
   623         }
   624       }
   625 
   626       if (_node_num == 1) {
   627         _first_node = INVALID;
   628         return true;
   629       }
   630 
   631       return false;
   632     }
   633 
   634     /// \brief Executes the algorithm.
   635     ///
   636     /// Executes the algorithm.
   637     ///
   638     /// \pre init() must be called
   639     void start() {
   640       while (!processNextPhase()) {}
   641     }
   642 
   643 
   644     /// \brief Runs %NagamochiIbaraki algorithm.
   645     ///
   646     /// This method runs the %Min cut algorithm
   647     ///
   648     /// \note mc.run(s) is just a shortcut of the following code.
   649     ///\code
   650     ///  mc.init();
   651     ///  mc.start();
   652     ///\endcode
   653     void run() {
   654       init();
   655       start();
   656     }
   657 
   658     ///@}
   659 
   660     /// \name Query Functions
   661     ///
   662     /// The result of the %NagamochiIbaraki
   663     /// algorithm can be obtained using these functions.\n
   664     /// Before the use of these functions, either run() or start()
   665     /// must be called.
   666 
   667     ///@{
   668 
   669     /// \brief Returns the min cut value.
   670     ///
   671     /// Returns the min cut value if the algorithm finished.
   672     /// After the first processNextPhase() it is a value of a
   673     /// valid cut in the graph.
   674     Value minCutValue() const {
   675       return _min_cut;
   676     }
   677 
   678     /// \brief Returns a min cut in a NodeMap.
   679     ///
   680     /// It sets the nodes of one of the two partitions to true and
   681     /// the other partition to false.
   682     /// \param cutMap A \ref concepts::WriteMap "writable" node map with
   683     /// \c bool (or convertible) value type.
   684     template <typename CutMap>
   685     Value minCutMap(CutMap& cutMap) const {
   686       for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
   687         cutMap.set(n, (*_cut_map)[n]);
   688       }
   689       return minCutValue();
   690     }
   691 
   692     ///@}
   693 
   694   };
   695 }
   696 
   697 #endif