partition.hxx
Go to the documentation of this file.00001 #pragma once
00002 #ifndef OPENGM_PARTITION_HXX
00003 #define OPENGM_PARTITION_HXX
00004
00005 #include <vector>
00006 #include <map>
00007
00008 namespace opengm {
00009
00012 template<class T = size_t>
00013 class Partition {
00014 public:
00015 typedef T value_type;
00016
00017 Partition();
00018 Partition(const value_type&);
00019
00020
00021 value_type find(const value_type&) const;
00022 value_type find(value_type);
00023 value_type numberOfElements() const;
00024 value_type numberOfSets() const;
00025 template<class Iterator> void elementLabeling(Iterator) const;
00026 template<class Iterator> void representatives(Iterator) const;
00027 void representativeLabeling(std::map<value_type, value_type>&) const;
00028
00029
00030 void reset(const value_type&);
00031 void merge(value_type, value_type);
00032 void insert(const value_type&);
00033
00034 private:
00035 std::vector<value_type> parents_;
00036 std::vector<value_type> ranks_;
00037 value_type numberOfElements_;
00038 value_type numberOfSets_;
00039 };
00040
00042 template<class T>
00043 Partition<T>::Partition()
00044 : parents_(),
00045 ranks_(),
00046 numberOfElements_(0),
00047 numberOfSets_(0)
00048 {}
00049
00054 template<class T>
00055 inline
00056 Partition<T>::Partition
00057 (
00058 const value_type& size
00059 )
00060 : parents_(static_cast<size_t>(size)),
00061 ranks_(static_cast<size_t>(size)),
00062 numberOfElements_(size),
00063 numberOfSets_(size)
00064 {
00065 for(T j=0; j<size; ++j) {
00066 parents_[static_cast<size_t>(j)] = j;
00067 }
00068 }
00069
00074 template<class T>
00075 inline void
00076 Partition<T>::reset
00077 (
00078 const value_type& size
00079 )
00080 {
00081 numberOfElements_ = size;
00082 numberOfSets_ = size;
00083 ranks_.resize(static_cast<size_t>(size));
00084 parents_.resize(static_cast<size_t>(size));
00085 for(T j=0; j<size; ++j) {
00086 ranks_[static_cast<size_t>(j)] = 0;
00087 parents_[static_cast<size_t>(j)] = j;
00088 }
00089 }
00090
00097 template<class T>
00098 inline typename Partition<T>::value_type
00099 Partition<T>::find
00100 (
00101 const value_type& element
00102 ) const
00103 {
00104
00105 value_type root = element;
00106 while(parents_[static_cast<size_t>(root)] != root) {
00107 root = parents_[static_cast<size_t>(root)];
00108 }
00109 return root;
00110 }
00111
00118 template<class T>
00119 inline typename Partition<T>::value_type
00120 Partition<T>::find
00121 (
00122 value_type element
00123 )
00124 {
00125
00126 value_type root = element;
00127 while(parents_[static_cast<size_t>(root)] != root) {
00128 root = parents_[static_cast<size_t>(root)];
00129 }
00130
00131 while(element != root) {
00132 value_type tmp = parents_[static_cast<size_t>(element)];
00133 parents_[static_cast<size_t>(element)] = root;
00134 element = tmp;
00135 }
00136 return root;
00137 }
00138
00144 template<class T>
00145 inline void
00146 Partition<T>::merge
00147 (
00148 value_type element1,
00149 value_type element2
00150 )
00151 {
00152
00153 element1 = find(element1);
00154 element2 = find(element2);
00155 if(ranks_[static_cast<size_t>(element1)] < ranks_[static_cast<size_t>(element2)]) {
00156 parents_[static_cast<size_t>(element1)] = element2;
00157 --numberOfSets_;
00158 }
00159 else if(ranks_[static_cast<size_t>(element1)] > ranks_[static_cast<size_t>(element2)]) {
00160 parents_[static_cast<size_t>(element2)] = element1;
00161 --numberOfSets_;
00162 }
00163 else if(element1 != element2) {
00164 parents_[static_cast<size_t>(element2)] = element1;
00165 ++ranks_[static_cast<size_t>(element1)];
00166 --numberOfSets_;
00167 }
00168 }
00169
00174 template<class T>
00175 inline void
00176 Partition<T>::insert
00177 (
00178 const value_type& number
00179 )
00180 {
00181 ranks_.insert(ranks_.end(), static_cast<size_t>(number), T(0));
00182 parents_.insert(parents_.end(), static_cast<size_t>(number), T(0));
00183 for(value_type j=numberOfElements_; j<numberOfElements_+number; ++j) {
00184 parents_[static_cast<size_t>(j)] = j;
00185 }
00186 numberOfElements_ += number;
00187 numberOfSets_ += number;
00188 }
00189
00194 template<class T>
00195 template<class Iterator>
00196 inline void
00197 Partition<T>::representatives
00198 (
00199 Iterator it
00200 ) const
00201 {
00202 for(value_type j=0; j<numberOfElements(); ++j) {
00203 if(parents_[static_cast<size_t>(j)] == j) {
00204 *it = j;
00205 ++it;
00206 }
00207 }
00208 }
00209
00214 template<class T>
00215 inline void
00216 Partition<T>::representativeLabeling
00217 (
00218 std::map<value_type, value_type>& out
00219 ) const
00220 {
00221 out.clear();
00222 std::vector<value_type> r(static_cast<size_t>(numberOfSets()));
00223 representatives(r.begin());
00224 for(T j=0; j<numberOfSets(); ++j) {
00225 out[ r[static_cast<size_t>(j)] ] = j;
00226 }
00227 }
00228
00233 template<class T>
00234 template<class Iterator>
00235 inline void
00236 Partition<T>::elementLabeling
00237 (
00238 Iterator out
00239 ) const
00240 {
00241 std::map<value_type, value_type> rl;
00242 representativeLabeling(rl);
00243 for(value_type j=0; j<numberOfElements(); ++j) {
00244 *out = rl[find(j)];
00245 ++out;
00246 }
00247 }
00248
00249 template<class T>
00250 inline typename Partition<T>::value_type
00251 Partition<T>::numberOfElements() const
00252 {
00253 return numberOfElements_;
00254 }
00255
00256 template<class T>
00257 inline typename Partition<T>::value_type
00258 Partition<T>::numberOfSets() const
00259 {
00260 return numberOfSets_;
00261 }
00262
00263 }
00264
00265 #endif // #ifndef OPENGM_PARTITION_HXX