OpenGM  2.3.x
Discrete Graphical Model Library
partition.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_PARTITION_HXX
3 #define OPENGM_PARTITION_HXX
4 
5 #include <vector>
6 #include <map>
7 
8 namespace opengm {
9 
12 template<class T = size_t>
13 class Partition {
14 public:
15  typedef T value_type;
16 
17  Partition();
18  Partition(const value_type&);
19 
20  // query
21  value_type find(const value_type&) const; // without path compression
22  value_type find(value_type); // with path compression
23  value_type numberOfElements() const;
24  value_type numberOfSets() const;
25  template<class Iterator> void elementLabeling(Iterator) const;
26  template<class Iterator> void representatives(Iterator) const;
27  void representativeLabeling(std::map<value_type, value_type>&) const;
28 
29  // manipulation
30  void reset(const value_type&);
31  void merge(value_type, value_type);
32  void insert(const value_type&);
33 
34 private:
35  std::vector<value_type> parents_;
36  std::vector<value_type> ranks_;
37  value_type numberOfElements_;
38  value_type numberOfSets_;
39 };
40 
42 template<class T>
44 : parents_(),
45  ranks_(),
46  numberOfElements_(0),
47  numberOfSets_(0)
48 {}
49 
54 template<class T>
55 inline
57 (
58  const value_type& size
59 )
60 : parents_(static_cast<size_t>(size)),
61  ranks_(static_cast<size_t>(size)),
62  numberOfElements_(size),
63  numberOfSets_(size)
64 {
65  for(T j=0; j<size; ++j) {
66  parents_[static_cast<size_t>(j)] = j;
67  }
68 }
69 
74 template<class T>
75 inline void
77 (
78  const value_type& size
79 )
80 {
81  numberOfElements_ = size;
82  numberOfSets_ = size;
83  ranks_.resize(static_cast<size_t>(size));
84  parents_.resize(static_cast<size_t>(size));
85  for(T j=0; j<size; ++j) {
86  ranks_[static_cast<size_t>(j)] = 0;
87  parents_[static_cast<size_t>(j)] = j;
88  }
89 }
90 
97 template<class T>
98 inline typename Partition<T>::value_type
100 (
101  const value_type& element
102 ) const
103 {
104  // find the root
105  value_type root = element;
106  while(parents_[static_cast<size_t>(root)] != root) {
107  root = parents_[static_cast<size_t>(root)];
108  }
109  return root;
110 }
111 
118 template<class T>
119 inline typename Partition<T>::value_type
121 (
122  value_type element // copy to work with
123 )
124 {
125  // find the root
126  value_type root = element;
127  while(parents_[static_cast<size_t>(root)] != root) {
128  root = parents_[static_cast<size_t>(root)];
129  }
130  // path compression
131  while(element != root) {
132  value_type tmp = parents_[static_cast<size_t>(element)];
133  parents_[static_cast<size_t>(element)] = root;
134  element = tmp;
135  }
136  return root;
137 }
138 
144 template<class T>
145 inline void
147 (
148  value_type element1,
149  value_type element2
150 )
151 {
152  // merge by rank
153  element1 = find(element1);
154  element2 = find(element2);
155  if(ranks_[static_cast<size_t>(element1)] < ranks_[static_cast<size_t>(element2)]) {
156  parents_[static_cast<size_t>(element1)] = element2;
157  --numberOfSets_;
158  }
159  else if(ranks_[static_cast<size_t>(element1)] > ranks_[static_cast<size_t>(element2)]) {
160  parents_[static_cast<size_t>(element2)] = element1;
161  --numberOfSets_;
162  }
163  else if(element1 != element2) {
164  parents_[static_cast<size_t>(element2)] = element1;
165  ++ranks_[static_cast<size_t>(element1)];
166  --numberOfSets_;
167  }
168 }
169 
174 template<class T>
175 inline void
177 (
178  const value_type& number
179 )
180 {
181  ranks_.insert(ranks_.end(), static_cast<size_t>(number), T(0));
182  parents_.insert(parents_.end(), static_cast<size_t>(number), T(0));
183  for(value_type j=numberOfElements_; j<numberOfElements_+number; ++j) {
184  parents_[static_cast<size_t>(j)] = j;
185  }
186  numberOfElements_ += number;
187  numberOfSets_ += number;
188 }
189 
194 template<class T>
195 template<class Iterator>
196 inline void
198 (
199  Iterator it
200 ) const
201 {
202  for(value_type j=0; j<numberOfElements(); ++j) {
203  if(parents_[static_cast<size_t>(j)] == j) {
204  *it = j;
205  ++it;
206  }
207  }
208 }
209 
214 template<class T>
215 inline void
217 (
218  std::map<value_type, value_type>& out
219 ) const
220 {
221  out.clear();
222  std::vector<value_type> r(static_cast<size_t>(numberOfSets()));
223  representatives(r.begin());
224  for(T j=0; j<numberOfSets(); ++j) {
225  out[ r[static_cast<size_t>(j)] ] = j;
226  }
227 }
228 
233 template<class T>
234 template<class Iterator>
235 inline void
237 (
238  Iterator out
239 ) const
240 {
241  std::map<value_type, value_type> rl;
242  representativeLabeling(rl);
243  for(value_type j=0; j<numberOfElements(); ++j) {
244  *out = rl[find(j)];
245  ++out;
246  }
247 }
248 
249 template<class T>
250 inline typename Partition<T>::value_type
252 {
253  return numberOfElements_;
254 }
255 
256 template<class T>
257 inline typename Partition<T>::value_type
259 {
260  return numberOfSets_;
261 }
262 
263 } // namespace opengm
264 
265 #endif // #ifndef OPENGM_PARTITION_HXX
The OpenGM namespace.
Definition: config.hxx:43
void elementLabeling(Iterator) const
Output a continuous labeling of all elements.
Definition: partition.hxx:237
void reset(const value_type &)
Reset a partition such that each set contains precisely one element.
Definition: partition.hxx:77
void merge(value_type, value_type)
Merge two sets.
Definition: partition.hxx:147
void representativeLabeling(std::map< value_type, value_type > &) const
Output a continuous labeling of the representative elements.
Definition: partition.hxx:217
value_type numberOfSets() const
Definition: partition.hxx:258
void insert(const value_type &)
Insert new sets.
Definition: partition.hxx:177
value_type find(const value_type &) const
Find the representative element of the set that contains the given element.
Definition: partition.hxx:100
void representatives(Iterator) const
Output all elements which are set representatives.
Definition: partition.hxx:198
Disjoint set data structure with path compression.
Definition: partition.hxx:13
value_type numberOfElements() const
Definition: partition.hxx:251
Partition()
Construct a partition.
Definition: partition.hxx:43