lemon/unionfind.h
author deba
Mon, 03 Apr 2006 09:45:23 +0000
changeset 2031 080d51024ac5
parent 2004 b8f10207e3d6
child 2205 c20b0eb92a33
permissions -rw-r--r--
Correcting the structure of the graph's and adaptor's map.
The template assign operators and map iterators can be used for adaptors also.

Some bugfix in the adaptors

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