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{
11
12
21template <typename I>
23{
24public:
26 using SizeType = typename I::ValueType;
27
28 UnionFind() = default;
29
31 explicit UnionFind( size_t size ) { reset( size ); }
32
34 auto size() const { return parents_.size(); }
35
37 void reset( size_t size )
38 {
40 parents_.clear();
41 parents_.reserve( size );
42 for ( I i{ size_t( 0 ) }; i < size; ++i )
43 parents_.push_back( i );
44 sizes_.clear();
45 sizes_.resize( size, 1 );
46 }
47
50 std::pair<I,bool> unite( I first, I second )
51 {
52 auto firstRoot = updateRoot_( first );
53 auto secondRoot = updateRoot_( second );
54 if ( firstRoot == secondRoot )
55 return { firstRoot, false };
57 if ( sizes_[firstRoot] < sizes_[secondRoot] )
58 {
59 parents_[firstRoot] = secondRoot;
60 sizes_[secondRoot] += sizes_[firstRoot];
61 return { secondRoot, true };
62 }
63 else
64 {
65 parents_[secondRoot] = firstRoot;
66 sizes_[firstRoot] += sizes_[secondRoot];
67 return { firstRoot, true };
68 }
69 }
70
72 bool united( I first, I second )
73 {
74 auto firstRoot = updateRoot_( first );
75 auto secondRoot = updateRoot_( second );
76 return firstRoot == secondRoot;
77 }
78
80 bool isRoot( I a ) const { return parents_[a] == a; }
81
83 I parent( I a ) const { return parents_[a]; }
84
86 I find( I a ) { return updateRoot_( a ); }
87
89 I findUpdateRange( I a, I begin, I end )
90 {
91 return updateRootInRange_( a, findRootNoUpdate_( a ), begin, end );
92 }
93
96 {
97 for ( I i{ size_t( 0 ) }; i < parents_.size(); ++i )
98 updateRoot_( i, findRootNoUpdate_( i ) );
99 return parents_;
100 }
101
103 const Vector<I, I> & parents() const { return parents_; }
104
106 SizeType sizeOfComp( I a ) { return sizes_[ find( a ) ]; }
107
108private:
110 I findRootNoUpdate_( I a ) const
111 {
112 I r = parents_[a];
113 for ( I e = a; e != r; r = parents_[e = r] ) {}
114 return r;
115 }
116
118 I updateRoot_( I a, const I r )
119 {
121 while ( a != r )
122 {
123 I b = r;
124 std::swap( parents_[a], b );
125 a = b;
126 }
127 return r;
128 }
129
131 I updateRoot_( I a ) { return updateRoot_( a, findRootNoUpdate_( a ) ); }
132
134 I updateRootInRange_( I a, const I r, I begin, I end )
135 {
136 assert( begin < end );
138 while ( a != r )
139 {
140 if ( a >= begin && a < end )
141 {
142 I b = r;
143 std::swap( parents_[a], b );
144 a = b;
145 }
146 else
147 a = parents_[a];
148 }
149 return r;
150 }
151
153 Vector<I, I> parents_;
154
156 Vector<SizeType, I> sizes_;
157};
158
159}
#define MR_TIMER
namespace MR
Definition MRTimer.h:56
Union-find data structure for representing disjoin sets of elements with few very quick operations: 1...
Definition MRUnionFind.h:23
std::vector<T>-like container that requires specific indexing type,
Definition MRVector.h:23
MR_BIND_IGNORE_PY auto end(const BitSet &)
Definition MRBitSet.h:397
MR_BIND_IGNORE_PY auto begin(const BitSet &a)
Definition MRBitSet.h:395
SizeType sizeOfComp(I a)
returns the number of elements in the set containing given element
Definition MRUnionFind.h:106
std::pair< I, bool > unite(I first, I second)
Definition MRUnionFind.h:50
void clear()
Definition MRVector.h:51
I find(I a)
finds the root of the set containing given element with optimizing data structure updates
Definition MRUnionFind.h:86
std::size_t size() const
Definition MRVector.h:55
void resize(size_t newSize) MR_REQUIRES_IF_SUPPORTED(sizeof(T)>0 &&std
Definition MRVector.h:57
const Vector< I, I > & roots()
sets the root of corresponding set as the parent of each element, then returns the vector
Definition MRUnionFind.h:95
void push_back(const T &t MR_LIFETIME_CAPTURE_BY_NESTED(this))
Definition MRVector.h:132
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:31
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:37
void reserve(size_t capacity)
Definition MRVector.h:65
bool isRoot(I a) const
returns true if given element is the root of some set
Definition MRUnionFind.h:80
bool united(I first, I second)
returns true if given two elements are from one set
Definition MRUnionFind.h:72
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:83
auto size() const
returns the number of elements in union-find
Definition MRUnionFind.h:34
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:89
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:26
const Vector< I, I > & parents() const
gets the parents of all elements as is
Definition MRUnionFind.h:103
only for bindings generation
Definition MRCameraOrientationPlugin.h:8