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: |
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 |
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; |
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 |