Lagrange
DisjointSets.h
1/*
2 * Copyright 2022 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <lagrange/utils/span.h>
15
16#include <vector>
17
18namespace lagrange {
19
24
30template <typename IndexType>
32{
33public:
37 DisjointSets() = default;
38
44 explicit DisjointSets(size_t n) { init(n); }
45
51 void init(size_t n);
52
56 size_t size() const { return m_parent.size(); }
57
61 void clear() { m_parent.clear(); }
62
70 IndexType find(IndexType i);
71
80 IndexType merge(IndexType i, IndexType j)
81 {
82 const auto root_i = find(i);
83 const auto root_j = find(j);
84 return m_parent[root_j] = root_i;
85 }
86
94 [[deprecated]] std::vector<std::vector<IndexType>> extract_disjoint_sets();
95
104 size_t extract_disjoint_set_indices(std::vector<IndexType>& index_map);
105
115
116protected:
117 std::vector<IndexType> m_parent;
118};
119
120template <typename IndexType>
121class DisjointSetsWithSize : public DisjointSets<IndexType>
122{
124
125public:
126 using DisjointSets<IndexType>::DisjointSets;
127
128 explicit DisjointSetsWithSize(size_t n) { init(n); }
129
130 void init(size_t n)
131 {
132 Super::init(n);
133 m_size.assign(n, 1);
134 }
135
136 void clear()
137 {
138 Super::clear();
139 m_size.clear();
140 }
141
142 IndexType size_of(IndexType i) { return m_size[this->find(i)]; }
143
144 IndexType merge(IndexType i, IndexType j)
145 {
146 auto root_i = this->find(i);
147 auto root_j = this->find(j);
148
149 if (root_i == root_j) {
150 return root_i;
151 }
152
153 // Ensure |I| >= |J|
154 if (size_of(root_i) < size_of(root_j)) {
155 std::swap(root_i, root_j);
156 }
157
158 this->m_parent[root_j] = root_i;
159 m_size[root_i] += m_size[root_j];
160
161 return root_i;
162 }
163
164protected:
165 std::vector<IndexType> m_size;
166};
167
169
170} // namespace lagrange
Disjoint sets computation.
Definition: DisjointSets.h:32
size_t size() const
Get the number of entries in total.
Definition: DisjointSets.h:56
IndexType merge(IndexType i, IndexType j)
Merge the disjoint set containing entry i and the disjoint set containing entry j.
Definition: DisjointSets.h:80
DisjointSets()=default
Initialize an empty disjoint sets.
IndexType find(IndexType i)
Find the root index corresponding to index i.
Definition: DisjointSets.cpp:35
DisjointSets(size_t n)
Initialize disjoint sets that contains n entries.
Definition: DisjointSets.h:44
size_t extract_disjoint_set_indices(std::vector< IndexType > &index_map)
Assign all elements their disjoint set index.
Definition: DisjointSets.cpp:60
void clear()
Clear all entries in the disjoint sets.
Definition: DisjointSets.h:61
void init(size_t n)
Initialize disjoint sets that contains n entries.
Definition: DisjointSets.cpp:28
std::vector< std::vector< IndexType > > extract_disjoint_sets()
Extract disjoint sets.
Definition: DisjointSets.cpp:46
Definition: DisjointSets.h:122
constexpr void swap(function_ref< R(Args...)> &lhs, function_ref< R(Args...)> &rhs) noexcept
Swaps the referred callables of lhs and rhs.
Definition: function_ref.h:114
::nonstd::span< T, Extent > span
A bounds-safe view for sequences of objects.
Definition: span.h:27
Main namespace for Lagrange.
Definition: AABBIGL.h:30