lemon/unionfind.h
author alpar
Thu, 02 Feb 2006 15:53:01 +0000
changeset 1944 89d5cf6e6abb
parent 1779 f6cafba4dbf2
child 1956 a055123339d5
permissions -rw-r--r--
Use short icpc paths
     1 /* -*- C++ -*-
     2  * lemon/unionfind.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2006 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 
    17 #ifndef LEMON_UNION_FIND_H
    18 #define LEMON_UNION_FIND_H
    19 
    20 //!\ingroup auxdat
    21 //!\file
    22 //!\brief Union-Find data structures.
    23 //!
    24 
    25 #include <vector>
    26 #include <list>
    27 #include <utility>
    28 #include <algorithm>
    29 
    30 #include <lemon/invalid.h>
    31 
    32 namespace lemon {
    33 
    34   //! \addtogroup auxdat
    35   //! @{
    36 
    37   /**
    38    * \brief A \e Union-Find data structure implementation
    39    *
    40    * The class implements the \e Union-Find data structure. 
    41    * The union operation uses rank heuristic, while
    42    * the find operation uses path compression.
    43    * This is a very simple but efficient implementation, providing 
    44    * only four methods: join (union), find, insert and size.
    45    * For more features see the \ref UnionFindEnum class.
    46    *
    47    * It is primarily used in Kruskal algorithm for finding minimal
    48    * cost spanning tree in a graph.
    49    * \sa kruskal()
    50    *
    51    * \pre The elements are automatically added only if the map 
    52    * given to the constructor was filled with -1's. Otherwise you
    53    * need to add all the elements by the \ref insert() method.
    54    * \bug It is not clear what the constructor parameter is used for.
    55    */
    56 
    57   template <typename T, typename TIntMap>
    58   class UnionFind {
    59     
    60   public:
    61     typedef T ElementType;
    62     typedef std::pair<int,int> PairType;
    63 
    64   private:
    65     std::vector<PairType> data;
    66     TIntMap& map;
    67 
    68   public:
    69     UnionFind(TIntMap& m) : map(m) {}
    70 
    71     /**
    72      * \brief Returns the index of the element's component.
    73      *
    74      * The method returns the index of the element's component.
    75      * This is an integer between zero and the number of inserted elements.
    76      */
    77 
    78     int find(T a)
    79     {
    80       int comp0 = map[a];
    81       if (comp0 < 0) {
    82 	return insert(a);
    83       }
    84       int comp = comp0;
    85       int next;
    86       while ( (next = data[comp].first) != comp) {
    87 	comp = next;
    88       }
    89       while ( (next = data[comp0].first) != comp) {
    90 	data[comp0].first = comp;
    91 	comp0 = next;
    92       }
    93 
    94       return comp;
    95     }
    96 
    97     /**
    98      * \brief Inserts a new element into the structure.
    99      *
   100      * This method inserts a new element into the data structure. 
   101      *
   102      * It is not required to use this method:
   103      * if the map given to the constructor was filled 
   104      * with -1's then it is called automatically
   105      * on the first \ref find or \ref join.
   106      *
   107      * The method returns the index of the new component.
   108      */
   109 
   110     int insert(T a)
   111     {
   112       int n = data.size();
   113       data.push_back(std::make_pair(n, 1));
   114       map.set(a,n);
   115       return n;
   116     }
   117 
   118     /**
   119      * \brief Joining the components of element \e a and element \e b.
   120      *
   121      * This is the \e union operation of the Union-Find structure. 
   122      * Joins the component of element \e a and component of
   123      * element \e b. If \e a and \e b are in the same component then
   124      * it returns false otherwise it returns true.
   125      */
   126 
   127     bool join(T a, T b)
   128     {
   129       int ca = find(a);
   130       int cb = find(b);
   131 
   132       if ( ca == cb ) 
   133 	return false;
   134 
   135       if ( data[ca].second > data[cb].second ) {
   136 	data[cb].first = ca;
   137 	data[ca].second += data[cb].second;
   138       }
   139       else {
   140 	data[ca].first = cb;
   141 	data[cb].second += data[ca].second;
   142       }
   143       return true;
   144     }
   145 
   146     /**
   147      * \brief Returns the size of the component of element \e a.
   148      *
   149      * Returns the size of the component of element \e a.
   150      */
   151 
   152     int size(T a)
   153     {
   154       int ca = find(a);
   155       return data[ca].second;
   156     }
   157 
   158   };
   159 
   160 
   161 
   162 
   163   /*******************************************************/
   164 
   165 
   166 #ifdef DEVELOPMENT_DOCS
   167 
   168   /**
   169    * \brief The auxiliary class for the \ref UnionFindEnum class.
   170    *
   171    * In the \ref UnionFindEnum class all components are represented as
   172    * a std::list. 
   173    * Items of these lists are UnionFindEnumItem structures.
   174    *
   175    * The class has four fields:
   176    *  - T me - the actual element 
   177    *  - IIter parent - the parent of the element in the union-find structure
   178    *  - int size - the size of the component of the element. 
   179    *            Only valid if the element
   180    *            is the leader of the component.
   181    *  - CIter my_class - pointer into the list of components 
   182    *            pointing to the component of the element.
   183    *            Only valid if the element is the leader of the component.
   184    */
   185 
   186 #endif
   187 
   188   template <typename T>
   189   struct UnionFindEnumItem {
   190 
   191     typedef std::list<UnionFindEnumItem> ItemList;
   192     typedef std::list<ItemList> ClassList;
   193     typedef typename ItemList::iterator IIter;
   194     typedef typename ClassList::iterator CIter;
   195 
   196     T me;
   197     IIter parent;
   198     int size;
   199     CIter my_class;
   200 
   201     UnionFindEnumItem() {}
   202     UnionFindEnumItem(const T &_me, CIter _my_class): 
   203       me(_me), size(1), my_class(_my_class) {}
   204   };
   205 
   206 
   207   /**
   208    * \brief A \e Union-Find data structure implementation which
   209    * is able to enumerate the components.
   210    *
   211    * The class implements a \e Union-Find data structure
   212    * which is able to enumerate the components and the items in
   213    * a component. If you don't need this feature then perhaps it's
   214    * better to use the \ref UnionFind class which is more efficient.
   215    *
   216    * The union operation uses rank heuristic, while
   217    * the find operation uses path compression.
   218    *
   219    * \pre You
   220    * need to add all the elements by the \ref insert() method.
   221    */
   222 
   223 
   224   template <typename T, template <typename Item> class Map>
   225   class UnionFindEnum {
   226 
   227     typedef std::list<UnionFindEnumItem<T> > ItemList;
   228     typedef std::list<ItemList> ClassList;
   229     typedef typename ItemList::iterator IIter;
   230     typedef typename ItemList::const_iterator IcIter;
   231     typedef typename ClassList::iterator CIter;
   232     typedef typename ClassList::const_iterator CcIter;
   233 
   234   public:
   235     typedef T ElementType;
   236     typedef UnionFindEnumItem<T> ItemType;
   237     typedef Map< IIter > MapType;
   238 
   239   private:
   240     MapType& m;
   241     ClassList classes;
   242 
   243     IIter _find(IIter a) const {
   244       IIter comp = a;
   245       IIter next;
   246       while( (next = comp->parent) != comp ) {
   247 	comp = next;
   248       }
   249 
   250       IIter comp1 = a;
   251       while( (next = comp1->parent) != comp ) {
   252 	comp1->parent = comp->parent;
   253 	comp1 = next;
   254       }
   255       return comp;
   256     }
   257 
   258   public:
   259     UnionFindEnum(MapType& _m) : m(_m) {}
   260 
   261 
   262     /**
   263      * \brief Inserts the given element into a new component.
   264      *
   265      * This method creates a new component consisting only of the
   266      * given element.
   267      */
   268 
   269     void insert(const T &a)
   270     {
   271 
   272 
   273       classes.push_back(ItemList());
   274       CIter aclass = classes.end();
   275       --aclass;
   276 
   277       ItemList &alist = *aclass;
   278       alist.push_back(ItemType(a, aclass));
   279       IIter ai = alist.begin();
   280 
   281       ai->parent = ai;
   282       m.set(a, ai);
   283 
   284     }
   285 
   286     /**
   287      * \brief Inserts the given element into the component of the others.
   288      *
   289      * This methods inserts the element \e a into the component of the
   290      * element \e comp. 
   291      */
   292 
   293     void insert(const T &a, const T &comp) {
   294       
   295       IIter clit = _find(m[comp]);
   296       ItemList &c = *clit->my_class;
   297       c.push_back(ItemType(a,0));
   298       IIter ai = c.end();
   299       --ai;
   300       ai->parent = clit;
   301       m.set(a, ai);
   302       ++clit->size;
   303     }
   304 
   305 
   306     /**
   307      * \brief Finds the leader of the component of the given element.
   308      *
   309      * The method returns the leader of the component of the given element.
   310      */
   311 
   312     T find(const T &a) const {
   313       return _find(m[a])->me;
   314     }
   315 
   316 
   317     /**
   318      * \brief Joining the component of element \e a and element \e b.
   319      *
   320      * This is the \e union operation of the Union-Find structure. 
   321      * Joins the component of element \e a and component of
   322      * element \e b. If \e a and \e b are in the same component then
   323      * returns false else returns true.
   324      */
   325 
   326     bool join(T a, T b) {
   327 
   328       IIter ca = _find(m[a]);
   329       IIter cb = _find(m[b]);
   330 
   331       if ( ca == cb ) {
   332 	return false;
   333       }
   334 
   335       if ( ca->size > cb->size ) {
   336 
   337 	cb->parent = ca->parent;
   338 	ca->size += cb->size;
   339 	
   340 	ItemList &alist = *ca->my_class;
   341 	alist.splice(alist.end(),*cb->my_class);
   342 
   343 	classes.erase(cb->my_class);
   344 	cb->my_class = 0;
   345       }
   346       else {
   347 
   348 	ca->parent = cb->parent;
   349 	cb->size += ca->size;
   350 	
   351 	ItemList &blist = *cb->my_class;
   352 	blist.splice(blist.end(),*ca->my_class);
   353 
   354 	classes.erase(ca->my_class);
   355 	ca->my_class = 0;
   356       }
   357 
   358       return true;
   359     }
   360 
   361 
   362     /**
   363      * \brief Returns the size of the component of element \e a.
   364      *
   365      * Returns the size of the component of element \e a.
   366      */
   367 
   368     int size(const T &a) const {
   369       return _find(m[a])->size;
   370     }
   371 
   372 
   373     /**
   374      * \brief Splits up the component of the element. 
   375      *
   376      * Splitting the component of the element into sigleton
   377      * components (component of size one).
   378      */
   379 
   380     void split(const T &a) {
   381 
   382       IIter ca = _find(m[a]);
   383  
   384       if ( ca->size == 1 )
   385 	return;
   386       
   387       CIter aclass = ca->my_class;
   388 
   389       for(IIter curr = ca; ++curr != aclass->end(); curr=ca) {
   390 	classes.push_back(ItemList());
   391 	CIter nl = --classes.end();
   392 	nl->splice(nl->end(), *aclass, curr);
   393 
   394 	curr->size=1;
   395 	curr->parent=curr;
   396 	curr->my_class = nl;
   397       }
   398 
   399       ca->size=1;
   400       return;
   401     }
   402 
   403 
   404     /**
   405      * \brief Sets the given element to the leader element of its component.
   406      *
   407      * Sets the given element to the leader element of its component.
   408      */
   409 
   410     void makeRep(const T &a) {
   411 
   412       IIter ia = m[a];
   413       IIter la = _find(ia);
   414       if (la == ia) return;
   415 
   416       ia->my_class = la->my_class;
   417       la->my_class = 0;
   418 
   419       ia->size = la->size;
   420 
   421       CIter l = ia->my_class;
   422       l->splice(l->begin(),*l,ia);
   423 
   424       ia->parent = ia;
   425       la->parent = ia;
   426     }
   427 
   428     /**
   429      * \brief Moves the given element to an other component.
   430      *
   431      * This method moves the element \e a from its component
   432      * to the component of \e comp.
   433      * If \e a and \e comp are in the same component then
   434      * it returns false otherwise it returns true.
   435      */
   436 
   437     bool move(const T &a, const T &comp) {
   438 
   439       IIter ai = m[a];
   440       IIter lai = _find(ai);
   441       IIter clit = _find(m[comp]);
   442 
   443       if (lai == clit)
   444 	return false;
   445 
   446       ItemList &cl = *clit->my_class,
   447 	&al = *lai->my_class;
   448 
   449       bool is_leader = (lai == ai);
   450       bool singleton = false;
   451 
   452       if (is_leader) {
   453 	++lai;
   454       }
   455 
   456       cl.splice(cl.end(), al, ai);
   457 
   458       if (is_leader) {
   459 	if (ai->size == 1) {
   460 	  classes.erase(ai->my_class);
   461 	  singleton = true;
   462 	}
   463 	else {
   464 	  lai->size = ai->size; 
   465 	  lai->my_class = ai->my_class;	
   466 	}
   467       }
   468       if (!singleton) {
   469 	for (IIter i = lai; i != al.end(); ++i)
   470 	  i->parent = lai;
   471 	--lai->size;
   472       }
   473 
   474       ai->parent = clit;
   475       ai->my_class = 0;
   476       ++clit->size;
   477 
   478       return true;
   479     }
   480 
   481 
   482     /**
   483      * \brief Removes the given element from the structure.
   484      *
   485      * Removes the given element from the structure.
   486      *
   487      * Removes the element from its component and if the component becomes
   488      * empty then removes that component from the component list.
   489      */
   490     void erase(const T &a) {
   491 
   492       IIter ma = m[a];
   493       if (ma == 0) return;
   494 
   495       IIter la = _find(ma);
   496       if (la == ma) {
   497 	if (ma -> size == 1){
   498 	  classes.erase(ma->my_class);
   499 	  m.set(a,0);
   500 	  return;
   501 	}
   502 	++la;
   503 	la->size = ma->size; 
   504 	la->my_class = ma->my_class;	
   505       }
   506 
   507       for (IIter i = la; i != la->my_class->end(); ++i) {
   508 	i->parent = la;
   509       }
   510 
   511       la->size--;
   512       la->my_class->erase(ma);
   513       m.set(a,0);
   514     }
   515 
   516     /**
   517      * \brief Removes the component of the given element from the structure.
   518      *
   519      * Removes the component of the given element from the structure.
   520      */
   521 
   522     void eraseClass(const T &a) {
   523       IIter ma = m[a];
   524       if (ma == 0) return;
   525 #     ifdef DEBUG
   526       CIter c = _find(ma)->my_class;
   527       for (IIter i=c->begin(); i!=c->end(); ++i)
   528 	m.set(i->me, 0);
   529 #     endif
   530       classes.erase(_find(ma)->my_class);
   531     }
   532 
   533 
   534     class ClassIt {
   535       friend class UnionFindEnum;
   536 
   537       CcIter i;
   538     public:
   539       ClassIt(Invalid): i(0) {}
   540       ClassIt() {}
   541       
   542       operator const T& () const { 
   543 	ItemList const &ll = *i;
   544 	return (ll.begin())->me; }
   545       bool operator == (ClassIt it) const {
   546 	return (i == it.i);
   547       }
   548       bool operator != (ClassIt it) const {
   549 	return (i != it.i);
   550       }
   551       bool operator < (ClassIt it) const {
   552 	return (i < it.i);
   553       }
   554 
   555       bool valid() const { return i != 0; }
   556     private:
   557       void first(const ClassList &l) { i = l.begin(); validate(l); }
   558       void next(const ClassList &l) {
   559 	++i; 
   560 	validate(l);
   561       }
   562       void validate(const ClassList &l) {
   563 	if ( i == l.end() ) 
   564 	  i = 0;
   565       }
   566     };
   567 
   568     /**
   569      * \brief Sets the iterator to point to the first component.
   570      * 
   571      * Sets the iterator to point to the first component.
   572      *
   573      * With the \ref first, \ref valid and \ref next methods you can
   574      * iterate through the components. For example:
   575      * \code
   576      * UnionFindEnum<Graph::Node, Graph::NodeMap>::MapType map(G);
   577      * UnionFindEnum<Graph::Node, Graph::NodeMap> U(map);
   578      * UnionFindEnum<Graph::Node, Graph::NodeMap>::ClassIt iter;
   579      *  for (U.first(iter); U.valid(iter); U.next(iter)) {
   580      *    // iter is convertible to Graph::Node
   581      *    cout << iter << endl;
   582      *  }
   583      * \endcode
   584      */
   585 
   586     ClassIt& first(ClassIt& it) const {
   587       it.first(classes);
   588       return it;
   589     }
   590 
   591     /**
   592      * \brief Returns whether the iterator is valid.
   593      *
   594      * Returns whether the iterator is valid.
   595      *
   596      * With the \ref first, \ref valid and \ref next methods you can
   597      * iterate through the components. See the example here: \ref first.
   598      */
   599 
   600     bool valid(ClassIt const &it) const {
   601       return it.valid(); 
   602     }
   603 
   604     /**
   605      * \brief Steps the iterator to the next component. 
   606      *
   607      * Steps the iterator to the next component.
   608      *
   609      * With the \ref first, \ref valid and \ref next methods you can
   610      * iterate through the components. See the example here: \ref first.
   611      */
   612 
   613     ClassIt& next(ClassIt& it) const {
   614       it.next(classes);
   615       return it;
   616     }
   617 
   618 
   619     class ItemIt {
   620       friend class UnionFindEnum;
   621 
   622       IcIter i;
   623       const ItemList *l;
   624     public:
   625       ItemIt(Invalid): i(0) {}
   626       ItemIt() {}
   627       
   628       operator const T& () const { return i->me; }
   629       bool operator == (ItemIt it) const {
   630 	return (i == it.i);
   631       }
   632       bool operator != (ItemIt it) const {
   633 	return (i != it.i);
   634       }
   635       bool operator < (ItemIt it) const {
   636 	return (i < it.i);
   637       }
   638 
   639       bool valid() const { return i != 0; }
   640     private:
   641       void first(const ItemList &il) { l=&il; i = l->begin(); validate(); }
   642       void next() {
   643 	++i; 
   644 	validate();
   645       }
   646       void validate() {
   647 	if ( i == l->end() ) 
   648 	  i = 0;
   649       }
   650     };
   651 
   652 
   653 
   654     /**
   655      * \brief Sets the iterator to point to the first element of the component.
   656      * 
   657      * \anchor first2 
   658      * Sets the iterator to point to the first element of the component.
   659      *
   660      * With the \ref first2 "first", \ref valid2 "valid" 
   661      * and \ref next2 "next" methods you can
   662      * iterate through the elements of a component. For example
   663      * (iterating through the component of the node \e node):
   664      * \code
   665      * Graph::Node node = ...;
   666      * UnionFindEnum<Graph::Node, Graph::NodeMap>::MapType map(G);
   667      * UnionFindEnum<Graph::Node, Graph::NodeMap> U(map);
   668      * UnionFindEnum<Graph::Node, Graph::NodeMap>::ItemIt iiter;
   669      *   for (U.first(iiter, node); U.valid(iiter); U.next(iiter)) {
   670      *     // iiter is convertible to Graph::Node
   671      *     cout << iiter << endl;
   672      *   }
   673      * \endcode
   674      */
   675     
   676     ItemIt& first(ItemIt& it, const T& a) const {
   677       it.first( * _find(m[a])->my_class );
   678       return it;
   679     }
   680 
   681     /**
   682      * \brief Returns whether the iterator is valid.
   683      *
   684      * \anchor valid2
   685      * Returns whether the iterator is valid.
   686      *
   687      * With the \ref first2 "first", \ref valid2 "valid" 
   688      * and \ref next2 "next" methods you can
   689      * iterate through the elements of a component.
   690      * See the example here: \ref first2 "first".
   691      */
   692 
   693     bool valid(ItemIt const &it) const {
   694       return it.valid(); 
   695     }
   696 
   697     /**
   698      * \brief Steps the iterator to the next component. 
   699      *
   700      * \anchor next2
   701      * Steps the iterator to the next component.
   702      *
   703      * With the \ref first2 "first", \ref valid2 "valid" 
   704      * and \ref next2 "next" methods you can
   705      * iterate through the elements of a component.
   706      * See the example here: \ref first2 "first".
   707      */
   708 
   709     ItemIt& next(ItemIt& it) const {
   710       it.next();
   711       return it;
   712     }
   713     
   714   };
   715 
   716 
   717   //! @}
   718 
   719 } //namespace lemon
   720 
   721 #endif //LEMON_UNION_FIND_H