src/work/johanna/unionfind.h
changeset 478 8c74de352f80
parent 394 3a34c5626e52
child 481 54d8feda437b
equal deleted inserted replaced
3:bcbd2365ccca 4:9164eefa975a
     1 // -*- c++ -*- //
     1 // -*- c++ -*- //
     2 #ifndef HUGO_UNION_FIND_H
     2 #ifndef HUGO_UNION_FIND_H
     3 #define HUGO_UNION_FIND_H
     3 #define HUGO_UNION_FIND_H
       
     4 
       
     5 //!ingroup auxdat
       
     6 //!\file
       
     7 //!\brief Union-Find data structures.
       
     8 
     4 
     9 
     5 #include <vector>
    10 #include <vector>
     6 #include <list>
    11 #include <list>
     7 #include <utility>
    12 #include <utility>
     8 #include <algorithm>
    13 #include <algorithm>
     9 
    14 
    10 #include <invalid.h>
    15 #include <invalid.h>
    11 
    16 
    12 namespace hugo {
    17 namespace hugo {
       
    18 
       
    19   //! \addtogroup auxdat
       
    20   //! @{
       
    21 
       
    22   /**
       
    23    * \brief A \e Union-Find data structure implementation
       
    24    *
       
    25    * The class implements the \e Union-Find data structure. 
       
    26    * The union operation uses rank heuristic, while
       
    27    * the find operation uses path compresson.
       
    28    * This is a very simple but efficient implementation, providing 
       
    29    * only four methods: join (union), find, insert and size.
       
    30    * For more features see the \ref UnionFindEnum class.
       
    31    *
       
    32    * \pre The elements are automatically added only if the map 
       
    33    * given to the constructor was filled with -1's. Otherwise you
       
    34    * need to add all the elements by the \ref insert() method.
       
    35    */
    13 
    36 
    14   template <typename T, typename TIntMap>
    37   template <typename T, typename TIntMap>
    15   class UnionFind {
    38   class UnionFind {
    16     
    39     
    17   public:
    40   public:
    23     TIntMap& map;
    46     TIntMap& map;
    24 
    47 
    25   public:
    48   public:
    26     UnionFind(TIntMap& m) : map(m) {}
    49     UnionFind(TIntMap& m) : map(m) {}
    27 
    50 
       
    51     /**
       
    52      * \brief Returns the index of the element's component.
       
    53      *
       
    54      * The method returns the index of the element's component.
       
    55      * This is an integer between zero and the number of inserted elements.
       
    56      */
    28 
    57 
    29     int find(T a)
    58     int find(T a)
    30     {
    59     {
    31       int comp0 = map[a];
    60       int comp0 = map[a];
    32       if (comp0 < 0) {
    61       if (comp0 < 0) {
    42 	comp0 = next;
    71 	comp0 = next;
    43       }
    72       }
    44 
    73 
    45       return comp;
    74       return comp;
    46     }
    75     }
       
    76 
       
    77     /**
       
    78      * \brief Insert a new element into the structure.
       
    79      *
       
    80      * This method inserts a new element into the data structure. 
       
    81      *
       
    82      * It is not required to use this method:
       
    83      * if the map given to the constructor was filled 
       
    84      * with -1's then it is called automatically
       
    85      * on the first \ref find or \ref join.
       
    86      *
       
    87      * The method returns the index of the new component.
       
    88      */
    47 
    89 
    48     int insert(T a)
    90     int insert(T a)
    49     {
    91     {
    50       int n = data.size();
    92       int n = data.size();
    51       data.push_back(std::make_pair(n, 1));
    93       data.push_back(std::make_pair(n, 1));
    52       map.set(a,n);
    94       map.set(a,n);
    53       return n;
    95       return n;
    54     }
    96     }
    55 
    97 
       
    98     /**
       
    99      * \brief Joining the components of element \e a and element \e b.
       
   100      *
       
   101      * This is the \e union operation of the Union-Find structure. 
       
   102      * Joins the component of elemenent \e a and component of
       
   103      * element \e b. If \e a and \e b are in the same component then
       
   104      * it returns false otherwise it returns true.
       
   105      */
       
   106 
    56     bool join(T a, T b)
   107     bool join(T a, T b)
    57     {
   108     {
    58       int ca = find(a);
   109       int ca = find(a);
    59       int cb = find(b);
   110       int cb = find(b);
    60 
   111 
    70 	data[cb].second += data[ca].second;
   121 	data[cb].second += data[ca].second;
    71       }
   122       }
    72       return true;
   123       return true;
    73     }
   124     }
    74 
   125 
       
   126     /**
       
   127      * \brief Returns the size of the component of element \e a.
       
   128      *
       
   129      * Returns the size of the component of element \e a.
       
   130      */
       
   131 
    75     int size(T a)
   132     int size(T a)
    76     {
   133     {
    77       int ca = find(a);
   134       int ca = find(a);
    78       return data[ca].second;
   135       return data[ca].second;
    79     }
   136     }
    84 
   141 
    85 
   142 
    86   /*******************************************************/
   143   /*******************************************************/
    87 
   144 
    88 
   145 
       
   146 #ifdef DEVELOPMENT_DOCS
       
   147 
       
   148   /**
       
   149    * \brief The auxiliary class for the \ref UnionFindEnum class.
       
   150    *
       
   151    * In the \ref UnionFindEnum class all components are represented as
       
   152    * a std::list. 
       
   153    * Items of these lists are UnionFindEnumItem structures.
       
   154    *
       
   155    * The class has four fields:
       
   156    *  - T me - the actual element 
       
   157    *  - IIter parent - the parent of the element in the union-find structure
       
   158    *  - int size - the size of the component of the element. 
       
   159    *            Only valid if the element
       
   160    *            is the leader of the component.
       
   161    *  - CIter my_class - pointer into the list of components 
       
   162    *            pointing to the component of the element.
       
   163    *            Only valid if the element is the leader of the component.
       
   164    */
       
   165 
       
   166 #endif
    89 
   167 
    90   template <typename T>
   168   template <typename T>
    91   struct UnionFindEnumItem {
   169   struct UnionFindEnumItem {
    92 
   170 
    93     typedef std::list<UnionFindEnumItem> ItemList;
   171     typedef std::list<UnionFindEnumItem> ItemList;
   102 
   180 
   103     UnionFindEnumItem() {}
   181     UnionFindEnumItem() {}
   104     UnionFindEnumItem(const T &_me, CIter _my_class): 
   182     UnionFindEnumItem(const T &_me, CIter _my_class): 
   105       me(_me), size(1), my_class(_my_class) {}
   183       me(_me), size(1), my_class(_my_class) {}
   106   };
   184   };
       
   185 
       
   186 
       
   187   /**
       
   188    * \brief A \e Union-Find data structure implementation which
       
   189    * is able to enumerate the components.
       
   190    *
       
   191    * The class implements an \e Union-Find data structure
       
   192    * which is able to enumerate the components and the items in
       
   193    * a component. If you don't need this feature then perhaps it's
       
   194    * better to use the \ref UnionFind class which is more efficient.
       
   195    *
       
   196    * The union operation uses rank heuristic, while
       
   197    * the find operation uses path compresson.
       
   198    *
       
   199    * \pre You
       
   200    * need to add all the elements by the \ref insert() method.
       
   201    */
       
   202 
   107 
   203 
   108   template <typename T, template <typename Item> class Map>
   204   template <typename T, template <typename Item> class Map>
   109   class UnionFindEnum {
   205   class UnionFindEnum {
   110 
   206 
   111     typedef std::list<UnionFindEnumItem<T> > ItemList;
   207     typedef std::list<UnionFindEnumItem<T> > ItemList;
   122 
   218 
   123   private:
   219   private:
   124     MapType& m;
   220     MapType& m;
   125     ClassList classes;
   221     ClassList classes;
   126 
   222 
   127     //    IIter where(const T &a) { return m[a]; }
       
   128     //    IIter parent(IIter a) { return a->parent; }
       
   129     //    P sibling(P a) { return &m[a->sibling]; }
       
   130 
       
   131     IIter _find(IIter a) const {
   223     IIter _find(IIter a) const {
   132       IIter comp = a;
   224       IIter comp = a;
   133       IIter next;
   225       IIter next;
   134       while( (next = comp->parent) != comp ) {
   226       while( (next = comp->parent) != comp ) {
   135 	comp = next;
   227 	comp = next;
   144     }
   236     }
   145 
   237 
   146   public:
   238   public:
   147     UnionFindEnum(MapType& _m) : m(_m) {}
   239     UnionFindEnum(MapType& _m) : m(_m) {}
   148 
   240 
       
   241 
       
   242     /**
       
   243      * \brief Insert the given element into a new component.
       
   244      *
       
   245      * This method creates a new component consisting only of the
       
   246      * given element.
       
   247      */
       
   248 
   149     void insert(const T &a)
   249     void insert(const T &a)
   150     {
   250     {
   151 
   251 
   152 
   252 
   153       classes.push_back(ItemList());
   253       classes.push_back(ItemList());
   161       ai->parent = ai;
   261       ai->parent = ai;
   162       m.set(a, ai);
   262       m.set(a, ai);
   163 
   263 
   164     }
   264     }
   165 
   265 
       
   266     /**
       
   267      * \brief Find the leader of the component of the given element.
       
   268      *
       
   269      * The method returns the leader of the component of the given element.
       
   270      */
       
   271 
   166     T find(const T &a) const {
   272     T find(const T &a) const {
   167       return _find(m[a])->me;
   273       return _find(m[a])->me;
   168     }
   274     }
       
   275 
       
   276 
       
   277     /**
       
   278      * \brief Joining the component of element \e a and element \e b.
       
   279      *
       
   280      * This is the \e union operation of the Union-Find structure. 
       
   281      * Joins the component of elemenent \e a and component of
       
   282      * element \e b. If \e a and \e b are in the same component then
       
   283      * returns false else returns true.
       
   284      */
   169 
   285 
   170     bool join(T a, T b) {
   286     bool join(T a, T b) {
   171 
   287 
   172       IIter ca = _find(m[a]);
   288       IIter ca = _find(m[a]);
   173       IIter cb = _find(m[b]);
   289       IIter cb = _find(m[b]);
   200       }
   316       }
   201 
   317 
   202       return true;
   318       return true;
   203     }
   319     }
   204 
   320 
       
   321 
       
   322     /**
       
   323      * \brief Returns the size of the component of element \e a.
       
   324      *
       
   325      * Returns the size of the component of element \e a.
       
   326      */
       
   327 
   205     int size(const T &a) const {
   328     int size(const T &a) const {
   206       return _find(m[a])->size;
   329       return _find(m[a])->size;
   207     }
   330     }
   208 
   331 
   209     
   332 
       
   333     /**
       
   334      * \brief Split up the component of the element. 
       
   335      *
       
   336      * Splitting the component of the element into sigleton
       
   337      * components (component of size one).
       
   338      */
       
   339 
   210     void split(const T &a) {
   340     void split(const T &a) {
   211 
   341 
   212       IIter ca = _find(m[a]);
   342       IIter ca = _find(m[a]);
   213  
   343  
   214       if ( ca->size == 1 )
   344       if ( ca->size == 1 )
   228 
   358 
   229       ca->size=1;
   359       ca->size=1;
   230       return;
   360       return;
   231     }
   361     }
   232 
   362 
       
   363 
       
   364     /**
       
   365      * \brief Set the given element to the leader element of its component.
       
   366      *
       
   367      * Set the given element to the leader element of its component.
       
   368      */
       
   369 
       
   370     void makeRep(const T &a) {
       
   371 
       
   372       IIter ia = m[a];
       
   373       IIter la = _find(ia);
       
   374       if (la == ia) return;
       
   375 
       
   376       ia->my_class = la->my_class;
       
   377       la->my_class = 0;
       
   378 
       
   379       ia->size = la->size;
       
   380 
       
   381       CIter l = ia->my_class;
       
   382       l->splice(l->begin(),*l,ia);
       
   383 
       
   384       ia->parent = ia;
       
   385       la->parent = ia;
       
   386     }
       
   387 
       
   388 
       
   389     /**
       
   390      * \brief Remove the given element from the structure.
       
   391      *
       
   392      * Remove the given element from the structure.
       
   393      *
       
   394      * Removes the element from its component and if the component becomes
       
   395      * empty then removes that component from the component list.
       
   396      */
   233     void erase(const T &a) {
   397     void erase(const T &a) {
   234 
   398 
   235       IIter ma = m[a];
   399       IIter ma = m[a];
   236       if (ma == 0) return;
   400       if (ma == 0) return;
   237 
   401 
   241 	  classes.erase(ma->my_class);
   405 	  classes.erase(ma->my_class);
   242 	  m.set(a,0);
   406 	  m.set(a,0);
   243 	  return;
   407 	  return;
   244 	}
   408 	}
   245 	++la;
   409 	++la;
   246 	la->size = ma->size - 1; 
   410 	la->size = ma->size; 
   247 	la->my_class = ma->my_class;	
   411 	la->my_class = ma->my_class;	
   248       }
   412       }
   249 
   413 
   250       for (IIter i = la; i != la->my_class->end(); ++i) {
   414       for (IIter i = la; i != la->my_class->end(); ++i) {
   251 	i->parent = la;
   415 	i->parent = la;
   252       }
   416       }
   253 
   417 
       
   418       la->size--;
   254       la->my_class->erase(ma);
   419       la->my_class->erase(ma);
   255       m.set(a,0);
   420       m.set(a,0);
   256     }
   421     }
       
   422 
       
   423     /**
       
   424      * \brief Removes the component of the given element from the structure.
       
   425      *
       
   426      * Removes the component of the given element from the structure.
       
   427      */
   257 
   428 
   258     void eraseClass(const T &a) {
   429     void eraseClass(const T &a) {
   259       IIter ma = m[a];
   430       IIter ma = m[a];
   260       if (ma == 0) return;
   431       if (ma == 0) return;
   261 #     ifdef DEBUG
   432 #     ifdef DEBUG
   299 	if ( i == l.end() ) 
   470 	if ( i == l.end() ) 
   300 	  i = 0;
   471 	  i = 0;
   301       }
   472       }
   302     };
   473     };
   303 
   474 
       
   475     /**
       
   476      * \brief Sets the iterator to point to the first component.
       
   477      * 
       
   478      * Sets the iterator to point to the first component.
       
   479      *
       
   480      * With the \ref first, \ref valid and \ref next methods you can
       
   481      * iterate through the components. For example:
       
   482      * \code
       
   483      * UnionFindEnum<Graph::Node, Graph::NodeMap>::MapType map(G);
       
   484      * UnionFindEnum<Graph::Node, Graph::NodeMap> U(map);
       
   485      * UnionFindEnum<Graph::Node, Graph::NodeMap>::ClassIt iter;
       
   486      *  for (U.first(iter); U.valid(iter); U.next(iter)) {
       
   487      *    // iter is convertible to Graph::Node
       
   488      *    cout << iter << endl;
       
   489      *  }
       
   490      * \endcode
       
   491      */
   304 
   492 
   305     ClassIt& first(ClassIt& it) const {
   493     ClassIt& first(ClassIt& it) const {
   306       it.first(classes);
   494       it.first(classes);
   307       return it;
   495       return it;
   308     }
   496     }
   309 
   497 
       
   498     /**
       
   499      * \brief Returns whether the iterator is valid.
       
   500      *
       
   501      * Returns whether the iterator is valid.
       
   502      *
       
   503      * With the \ref first, \ref valid and \ref next methods you can
       
   504      * iterate through the components. See the example here: \ref first.
       
   505      */
       
   506 
   310     bool valid(ClassIt const &it) const {
   507     bool valid(ClassIt const &it) const {
   311       return it.valid(); 
   508       return it.valid(); 
   312     }
   509     }
       
   510 
       
   511     /**
       
   512      * \brief Steps the iterator to the next component. 
       
   513      *
       
   514      * Steps the iterator to the next component.
       
   515      *
       
   516      * With the \ref first, \ref valid and \ref next methods you can
       
   517      * iterate through the components. See the example here: \ref first.
       
   518      */
   313 
   519 
   314     ClassIt& next(ClassIt& it) const {
   520     ClassIt& next(ClassIt& it) const {
   315       it.next(classes);
   521       it.next(classes);
   316       return it;
   522       return it;
   317     }
   523     }
   349 	  i = 0;
   555 	  i = 0;
   350       }
   556       }
   351     };
   557     };
   352 
   558 
   353 
   559 
       
   560 
       
   561     /**
       
   562      * \brief Sets the iterator to point to the first element of the component.
       
   563      * 
       
   564      * \anchor first2 
       
   565      * Sets the iterator to point to the first element of the component.
       
   566      *
       
   567      * With the \ref first2 "first", \ref valid2 "valid" 
       
   568      * and \ref next2 "next" methods you can
       
   569      * iterate through the elements of a component. For example
       
   570      * (iterating through the component of the node \e node):
       
   571      * \code
       
   572      * Graph::Node node = ...;
       
   573      * UnionFindEnum<Graph::Node, Graph::NodeMap>::MapType map(G);
       
   574      * UnionFindEnum<Graph::Node, Graph::NodeMap> U(map);
       
   575      * UnionFindEnum<Graph::Node, Graph::NodeMap>::ItemIt iiter;
       
   576      *   for (U.first(iiter, node); U.valid(iiter); U.next(iiter)) {
       
   577      *     // iiter is convertible to Graph::Node
       
   578      *     cout << iiter << endl;
       
   579      *   }
       
   580      * \endcode
       
   581      */
       
   582     
   354     ItemIt& first(ItemIt& it, const T& a) const {
   583     ItemIt& first(ItemIt& it, const T& a) const {
   355       it.first( * _find(m[a])->my_class );
   584       it.first( * _find(m[a])->my_class );
   356       return it;
   585       return it;
   357     }
   586     }
   358 
   587 
       
   588     /**
       
   589      * \brief Returns whether the iterator is valid.
       
   590      *
       
   591      * \anchor valid2
       
   592      * Returns whether the iterator is valid.
       
   593      *
       
   594      * With the \ref first2 "first", \ref valid2 "valid" 
       
   595      * and \ref next2 "next" methods you can
       
   596      * iterate through the elements of a component.
       
   597      * See the example here: \ref first2 "first".
       
   598      */
       
   599 
   359     bool valid(ItemIt const &it) const {
   600     bool valid(ItemIt const &it) const {
   360       return it.valid(); 
   601       return it.valid(); 
   361     }
   602     }
       
   603 
       
   604     /**
       
   605      * \brief Steps the iterator to the next component. 
       
   606      *
       
   607      * \anchor next2
       
   608      * Steps the iterator to the next component.
       
   609      *
       
   610      * With the \ref first2 "first", \ref valid2 "valid" 
       
   611      * and \ref next2 "next" methods you can
       
   612      * iterate through the elements of a component.
       
   613      * See the example here: \ref first2 "first".
       
   614      */
   362 
   615 
   363     ItemIt& next(ItemIt& it) const {
   616     ItemIt& next(ItemIt& it) const {
   364       it.next();
   617       it.next();
   365       return it;
   618       return it;
   366     }
   619     }
   367     
   620     
   368 
       
   369 
       
   370   };
   621   };
   371 
   622 
       
   623 
       
   624   //! @}
       
   625 
   372 } //namespace hugo
   626 } //namespace hugo
   373 
   627 
   374 #endif //HUGO_UNION_FIND_H
   628 #endif //HUGO_UNION_FIND_H