/usr/include/opengm/datastructures/partition.hxx is in libopengm-dev 2.3.6+20160905-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | #pragma once
#ifndef OPENGM_PARTITION_HXX
#define OPENGM_PARTITION_HXX
#include <vector>
#include <map>
namespace opengm {
/// Disjoint set data structure with path compression.
/// \ingroup datastructures
template<class T = size_t>
class Partition {
public:
typedef T value_type;
Partition();
Partition(const value_type&);
// query
value_type find(const value_type&) const; // without path compression
value_type find(value_type); // with path compression
value_type numberOfElements() const;
value_type numberOfSets() const;
template<class Iterator> void elementLabeling(Iterator) const;
template<class Iterator> void representatives(Iterator) const;
void representativeLabeling(std::map<value_type, value_type>&) const;
// manipulation
void reset(const value_type&);
void merge(value_type, value_type);
void insert(const value_type&);
private:
std::vector<value_type> parents_;
std::vector<value_type> ranks_;
value_type numberOfElements_;
value_type numberOfSets_;
};
/// Construct a partition.
template<class T>
Partition<T>::Partition()
: parents_(),
ranks_(),
numberOfElements_(0),
numberOfSets_(0)
{}
/// Construct a partition.
///
/// \param size Number of distinct sets.
///
template<class T>
inline
Partition<T>::Partition
(
const value_type& size
)
: parents_(static_cast<size_t>(size)),
ranks_(static_cast<size_t>(size)),
numberOfElements_(size),
numberOfSets_(size)
{
for(T j=0; j<size; ++j) {
parents_[static_cast<size_t>(j)] = j;
}
}
/// Reset a partition such that each set contains precisely one element
///
/// \param size Number of distinct sets.
///
template<class T>
inline void
Partition<T>::reset
(
const value_type& size
)
{
numberOfElements_ = size;
numberOfSets_ = size;
ranks_.resize(static_cast<size_t>(size));
parents_.resize(static_cast<size_t>(size));
for(T j=0; j<size; ++j) {
ranks_[static_cast<size_t>(j)] = 0;
parents_[static_cast<size_t>(j)] = j;
}
}
/// Find the representative element of the set that contains the given element.
///
/// This constant function does not compress the search path.
///
/// \param element Element.
///
template<class T>
inline typename Partition<T>::value_type
Partition<T>::find
(
const value_type& element
) const
{
// find the root
value_type root = element;
while(parents_[static_cast<size_t>(root)] != root) {
root = parents_[static_cast<size_t>(root)];
}
return root;
}
/// Find the representative element of the set that contains the given element.
///
/// This mutable function compresses the search path.
///
/// \param element Element.
///
template<class T>
inline typename Partition<T>::value_type
Partition<T>::find
(
value_type element // copy to work with
)
{
// find the root
value_type root = element;
while(parents_[static_cast<size_t>(root)] != root) {
root = parents_[static_cast<size_t>(root)];
}
// path compression
while(element != root) {
value_type tmp = parents_[static_cast<size_t>(element)];
parents_[static_cast<size_t>(element)] = root;
element = tmp;
}
return root;
}
/// Merge two sets.
///
/// \param element1 Element in the first set.
/// \param element2 Element in the second set.
///
template<class T>
inline void
Partition<T>::merge
(
value_type element1,
value_type element2
)
{
// merge by rank
element1 = find(element1);
element2 = find(element2);
if(ranks_[static_cast<size_t>(element1)] < ranks_[static_cast<size_t>(element2)]) {
parents_[static_cast<size_t>(element1)] = element2;
--numberOfSets_;
}
else if(ranks_[static_cast<size_t>(element1)] > ranks_[static_cast<size_t>(element2)]) {
parents_[static_cast<size_t>(element2)] = element1;
--numberOfSets_;
}
else if(element1 != element2) {
parents_[static_cast<size_t>(element2)] = element1;
++ranks_[static_cast<size_t>(element1)];
--numberOfSets_;
}
}
/// Insert new sets.
///
/// \param number Number of sets to insert.
///
template<class T>
inline void
Partition<T>::insert
(
const value_type& number
)
{
ranks_.insert(ranks_.end(), static_cast<size_t>(number), T(0));
parents_.insert(parents_.end(), static_cast<size_t>(number), T(0));
for(value_type j=numberOfElements_; j<numberOfElements_+number; ++j) {
parents_[static_cast<size_t>(j)] = j;
}
numberOfElements_ += number;
numberOfSets_ += number;
}
/// Output all elements which are set representatives.
///
/// \param it (Output) Iterator into a container.
///
template<class T>
template<class Iterator>
inline void
Partition<T>::representatives
(
Iterator it
) const
{
for(value_type j=0; j<numberOfElements(); ++j) {
if(parents_[static_cast<size_t>(j)] == j) {
*it = j;
++it;
}
}
}
/// Output a continuous labeling of the representative elements.
///
/// \param out (Output) A map that assigns each representative element to its label.
///
template<class T>
inline void
Partition<T>::representativeLabeling
(
std::map<value_type, value_type>& out
) const
{
out.clear();
std::vector<value_type> r(static_cast<size_t>(numberOfSets()));
representatives(r.begin());
for(T j=0; j<numberOfSets(); ++j) {
out[ r[static_cast<size_t>(j)] ] = j;
}
}
/// Output a continuous labeling of all elements.
///
/// \param out (Output) Iterator into a container in which the j-th entry is the label of the element j.
///
template<class T>
template<class Iterator>
inline void
Partition<T>::elementLabeling
(
Iterator out
) const
{
std::map<value_type, value_type> rl;
representativeLabeling(rl);
for(value_type j=0; j<numberOfElements(); ++j) {
*out = rl[find(j)];
++out;
}
}
template<class T>
inline typename Partition<T>::value_type
Partition<T>::numberOfElements() const
{
return numberOfElements_;
}
template<class T>
inline typename Partition<T>::value_type
Partition<T>::numberOfSets() const
{
return numberOfSets_;
}
} // namespace opengm
#endif // #ifndef OPENGM_PARTITION_HXX
|