MeshLib C++ Docs
Loading...
Searching...
No Matches
MRUnionFind.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRVector.h"
4#include "MRTimer.h"
5#include <utility>
6
7namespace MR
8{
9
18template <typename I>
20{
21public:
23 using SizeType = typename I::ValueType;
24
25 UnionFind() = default;
26
28 explicit UnionFind( size_t size ) { reset( size ); }
29
31 auto size() const { return parents_.size(); }
32
34 void reset( size_t size )
35 {
37 parents_.clear();
38 parents_.reserve( size );
39 for ( I i{ size_t( 0 ) }; i < size; ++i )
40 parents_.push_back( i );
41 sizes_.clear();
42 sizes_.resize( size, 1 );
43 }
44
47 std::pair<I,bool> unite( I first, I second )
48 {
49 auto firstRoot = updateRoot_( first );
50 auto secondRoot = updateRoot_( second );
51 if ( firstRoot == secondRoot )
52 return { firstRoot, false };
54 if ( sizes_[firstRoot] < sizes_[secondRoot] )
55 {
56 parents_[firstRoot] = secondRoot;
57 sizes_[secondRoot] += sizes_[firstRoot];
58 return { secondRoot, true };
59 }
60 else
61 {
62 parents_[secondRoot] = firstRoot;
63 sizes_[firstRoot] += sizes_[secondRoot];
64 return { firstRoot, true };
65 }
66 }
67
69 bool united( I first, I second )
70 {
71 auto firstRoot = updateRoot_( first );
72 auto secondRoot = updateRoot_( second );
73 return firstRoot == secondRoot;
74 }
75
77 bool isRoot( I a ) const { return parents_[a] == a; }
78
80 I parent( I a ) const { return parents_[a]; }
81
83 I find( I a ) { return updateRoot_( a, findRootNoUpdate_( a ) ); }
84
86 I findUpdateRange( I a, I begin, I end )
87 {
88 return updateRootInRange_( a, findRootNoUpdate_( a ), begin, end );
89 }
90
93 {
94 for ( I i{ size_t( 0 ) }; i < parents_.size(); ++i )
95 updateRoot_( i, findRootNoUpdate_( i ) );
96 return parents_;
97 }
98
100 const Vector<I, I> & parents() const { return parents_; }
101
103 SizeType sizeOfComp( I a ) { return sizes_[ find( a ) ]; }
104
105private:
107 I findRootNoUpdate_( I a ) const
108 {
109 I r = parents_[a];
110 for ( I e = a; e != r; r = parents_[e = r] ) {}
111 return r;
112 }
113
115 I updateRoot_( I a, const I r )
116 {
117 // update parents
118 while ( a != r )
119 {
120 I b = r;
121 std::swap( parents_[a], b );
122 a = b;
123 }
124 return r;
125 }
126
128 I updateRoot_( I a ) { return updateRoot_( a, findRootNoUpdate_( a ) ); }
129
131 I updateRootInRange_( I a, const I r, I begin, I end )
132 {
133 assert( begin < end );
134 // update parents
135 while ( a != r )
136 {
137 if ( a >= begin && a < end )
138 {
139 I b = r;
140 std::swap( parents_[a], b );
141 a = b;
142 }
143 else
144 a = parents_[a];
145 }
146 return r;
147 }
148
150 Vector<I, I> parents_;
151
153 Vector<SizeType, I> sizes_;
154};
155
156} //namespace MR
#define MR_TIMER
Definition MRTimer.h:53
Union-find data structure for representing disjoin sets of elements with few very quick operations: 1...
Definition MRUnionFind.h:20
SizeType sizeOfComp(I a)
returns the number of elements in the set containing given element
Definition MRUnionFind.h:103
std::pair< I, bool > unite(I first, I second)
Definition MRUnionFind.h:47
I find(I a)
finds the root of the set containing given element with optimizing data structure updates
Definition MRUnionFind.h:83
const Vector< I, I > & roots()
sets the root of corresponding set as the parent of each element, then returns the vector
Definition MRUnionFind.h:92
UnionFind(size_t size)
creates union-find with given number of elements, each element is the only one in its disjoint set
Definition MRUnionFind.h:28
UnionFind()=default
void reset(size_t size)
resets union-find to represent given number of elements, each element is the only one in its disjoint...
Definition MRUnionFind.h:34
bool isRoot(I a) const
returns true if given element is the root of some set
Definition MRUnionFind.h:77
bool united(I first, I second)
returns true if given two elements are from one set
Definition MRUnionFind.h:69
I parent(I a) const
return parent element of this element, which is equal to given element only for set's root
Definition MRUnionFind.h:80
auto size() const
returns the number of elements in union-find
Definition MRUnionFind.h:31
I findUpdateRange(I a, I begin, I end)
finds the root of the set containing given element with optimizing data structure in the range [begin...
Definition MRUnionFind.h:86
typename I::ValueType SizeType
the type that can hold the number of elements of the maximal set (e.g. int for FaceId and size_t for ...
Definition MRUnionFind.h:23
const Vector< I, I > & parents() const
gets the parents of all elements as is
Definition MRUnionFind.h:100
std::vector<T>-like container that requires specific indexing type,
Definition MRMesh/MRVector.h:19
void clear()
Definition MRMesh/MRVector.h:38
std::size_t size() const
Definition MRMesh/MRVector.h:41
void reserve(size_t capacity)
Definition MRMesh/MRVector.h:50
void push_back(const T &t)
Definition MRMesh/MRVector.h:108
void resize(size_t newSize)
Definition MRMesh/MRVector.h:43
MR_BIND_IGNORE auto begin(const BitSet &a)
Definition MRMesh/MRBitSet.h:307
MR_BIND_IGNORE auto end(const BitSet &)
Definition MRMesh/MRBitSet.h:309
Definition MRCameraOrientationPlugin.h:8