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    // query
00021    value_type find(const value_type&) const; // without path compression
00022    value_type find(value_type); // with path compression
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    // manipulation
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    // find the root
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 // copy to work with
00123 )
00124 {
00125    // find the root
00126    value_type root = element;
00127    while(parents_[static_cast<size_t>(root)] != root) {
00128       root = parents_[static_cast<size_t>(root)];
00129    }
00130    // path compression
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    // merge by rank
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 } // namespace opengm
00264 
00265 #endif // #ifndef OPENGM_PARTITION_HXX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:05 2013 for OpenGM by  doxygen 1.6.3