SMTK  @SMTK_VERSION@
Simulation Modeling Tool Kit
UnionFind.h
1 //=========================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //=========================================================================
10 
11 #ifndef smtk_common_UnionFind_h
12 #define smtk_common_UnionFind_h
13 
14 #include <map>
15 #include <set>
16 #include <vector>
17 
18 namespace smtk
19 {
20 namespace common
21 {
22 
24 template<typename T>
26 {
27  UnionFindSet(T parent, T rank = 0)
28  {
29  m_parent = parent;
30  m_rank = rank;
31  }
32  UnionFindSet(const UnionFindSet& other)
33  {
34  m_parent = other.m_parent;
35  m_rank = other.m_rank;
36  }
37  T m_parent;
38  T m_rank;
39 };
40 
52 template<typename T>
53 class UnionFind
54 {
55 public:
57  typedef T value_type;
58 
60  T newSet();
62  T mergeSets(T a, T b);
64  T find(T src);
66  std::set<T> roots();
68  void collapseIds(std::map<T, T>& collapsedIds, T startCount);
70  T size() const { return static_cast<T>(m_sets.size()); }
71 
72  std::vector<UnionFindSet<T>> m_sets;
73 };
74 
75 template<typename T>
77 {
78  T setId = this->size();
79  UnionFindSet<T> entry(setId, 0);
80  m_sets.push_back(entry);
81  return setId;
82 }
83 
84 template<typename T>
86 {
87  T aRoot = this->find(a);
88  T bRoot = this->find(b);
89 
90  if (aRoot == bRoot)
91  {
92  return aRoot;
93  }
94 
95  if (aRoot < 0 || bRoot < 0)
96  {
97  return -1;
98  }
99 
100  T aRank = m_sets[aRoot].m_rank;
101  T bRank = m_sets[bRoot].m_rank;
102  if (aRank < bRank)
103  {
104  m_sets[aRoot].m_parent = bRoot;
105  return bRoot;
106  }
107  else if (bRank == aRank)
108  {
109  ++m_sets[aRoot].m_rank;
110  }
111  m_sets[bRoot].m_parent = aRoot;
112  return aRoot;
113 }
114 
115 template<typename T>
117 {
118  if (src < 0 || src >= this->size())
119  {
120  return -1;
121  }
122  T parent = m_sets[src].m_parent;
123  if (parent != src)
124  {
125  m_sets[src].m_parent = this->find(parent);
126  }
127  return m_sets[src].m_parent;
128 }
129 
130 template<typename T>
131 std::set<T> UnionFind<T>::roots()
132 {
133  typename std::set<T> roots;
134  typename std::vector<UnionFindSet<T>>::iterator it;
135  T i = 0;
136  for (it = m_sets.begin(); it != m_sets.end(); ++it, ++i)
137  {
138  if (i == it->m_parent)
139  {
140  roots.insert(i);
141  }
142  }
143  return roots;
144 }
145 
146 template<typename T>
147 void UnionFind<T>::collapseIds(std::map<T, T>& collapsedIds, T startCount)
148 {
149  std::set<T> roots = this->roots();
150  typename std::set<T>::iterator it;
151  for (it = roots.begin(); it != roots.end(); ++it)
152  {
153  // Do not relabel any pre-existing entries in collapsedIds.
154  typename std::map<T, T>::iterator cit = collapsedIds.find(*it);
155  if (cit == collapsedIds.end())
156  {
157  //cout << "Collapse " << *it << " to " << startCount << "\n";
158  collapsedIds[*it] = startCount++;
159  }
160  }
161 }
162 
163 } // namespace common
164 } // namespace smtk
165 
166 #endif // smtk_common_UnionFind_h
smtk
The main namespace for the Simulation Modeling Tool Kit (SMTK).
Definition: doc.h:33
smtk::common::UnionFind::value_type
T value_type
Each value used to identify a set is of this type.
Definition: UnionFind.h:57
smtk::common::UnionFind::collapseIds
void collapseIds(std::map< T, T > &collapsedIds, T startCount)
Popoulate a map with remaining disjoint sets numbered starting at startCount.
Definition: UnionFind.h:147
smtk::common::UnionFind::find
T find(T src)
Find the parent of a set.
Definition: UnionFind.h:116
smtk::common::UnionFindSet
Internal storage for the UnionFind class.
Definition: UnionFind.h:25
smtk::common::UnionFind
A disjoint-set structure for fast union-find operations.
Definition: UnionFind.h:53
smtk::common::UnionFind::size
T size() const
Return the number of sets that have been created.
Definition: UnionFind.h:70
smtk::common::UnionFind::mergeSets
T mergeSets(T a, T b)
Connect two disjoint sets, returning the ID of their union (which may not be a or b).
Definition: UnionFind.h:85
smtk::common::UnionFind::newSet
T newSet()
Add a new set (disjoint from all others).
Definition: UnionFind.h:76
smtk::common::UnionFind::roots
std::set< T > roots()
Get the current root sets (entries in Sets whose parents are themselves)
Definition: UnionFind.h:131