annotate DEPENDENCIES/generic/include/boost/pending/disjoint_sets.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 //
Chris@16 2 //=======================================================================
Chris@16 3 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
Chris@16 4 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
Chris@16 5 //
Chris@16 6 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 7 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 8 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9 //=======================================================================
Chris@16 10 //
Chris@16 11 #ifndef BOOST_DISJOINT_SETS_HPP
Chris@16 12 #define BOOST_DISJOINT_SETS_HPP
Chris@16 13
Chris@16 14 #include <vector>
Chris@16 15 #include <boost/graph/properties.hpp>
Chris@16 16 #include <boost/pending/detail/disjoint_sets.hpp>
Chris@16 17
Chris@16 18 namespace boost {
Chris@16 19
Chris@16 20 struct find_with_path_halving {
Chris@16 21 template <class ParentPA, class Vertex>
Chris@16 22 Vertex operator()(ParentPA p, Vertex v) {
Chris@16 23 return detail::find_representative_with_path_halving(p, v);
Chris@16 24 }
Chris@16 25 };
Chris@16 26
Chris@16 27 struct find_with_full_path_compression {
Chris@16 28 template <class ParentPA, class Vertex>
Chris@16 29 Vertex operator()(ParentPA p, Vertex v){
Chris@16 30 return detail::find_representative_with_full_compression(p, v);
Chris@16 31 }
Chris@16 32 };
Chris@16 33
Chris@16 34 // This is a generalized functor to provide disjoint sets operations
Chris@16 35 // with "union by rank" and "path compression". A disjoint-set data
Chris@16 36 // structure maintains a collection S={S1, S2, ..., Sk} of disjoint
Chris@16 37 // sets. Each set is identified by a representative, which is some
Chris@16 38 // member of of the set. Sets are represented by rooted trees. Two
Chris@16 39 // heuristics: "union by rank" and "path compression" are used to
Chris@16 40 // speed up the operations.
Chris@16 41
Chris@16 42 // Disjoint Set requires two vertex properties for internal use. A
Chris@16 43 // RankPA and a ParentPA. The RankPA must map Vertex to some Integral type
Chris@16 44 // (preferably the size_type associated with Vertex). The ParentPA
Chris@16 45 // must map Vertex to Vertex.
Chris@16 46 template <class RankPA, class ParentPA,
Chris@16 47 class FindCompress = find_with_full_path_compression
Chris@16 48 >
Chris@16 49 class disjoint_sets {
Chris@16 50 typedef disjoint_sets self;
Chris@16 51
Chris@16 52 inline disjoint_sets() {}
Chris@16 53 public:
Chris@16 54 inline disjoint_sets(RankPA r, ParentPA p)
Chris@16 55 : rank(r), parent(p) {}
Chris@16 56
Chris@16 57 inline disjoint_sets(const self& c)
Chris@16 58 : rank(c.rank), parent(c.parent) {}
Chris@16 59
Chris@16 60 // Make Set -- Create a singleton set containing vertex x
Chris@16 61 template <class Element>
Chris@16 62 inline void make_set(Element x)
Chris@16 63 {
Chris@16 64 put(parent, x, x);
Chris@16 65 typedef typename property_traits<RankPA>::value_type R;
Chris@16 66 put(rank, x, R());
Chris@16 67 }
Chris@16 68
Chris@16 69 // Link - union the two sets represented by vertex x and y
Chris@16 70 template <class Element>
Chris@16 71 inline void link(Element x, Element y)
Chris@16 72 {
Chris@16 73 detail::link_sets(parent, rank, x, y, rep);
Chris@16 74 }
Chris@16 75
Chris@16 76 // Union-Set - union the two sets containing vertex x and y
Chris@16 77 template <class Element>
Chris@16 78 inline void union_set(Element x, Element y)
Chris@16 79 {
Chris@16 80 link(find_set(x), find_set(y));
Chris@16 81 }
Chris@16 82
Chris@16 83 // Find-Set - returns the Element representative of the set
Chris@16 84 // containing Element x and applies path compression.
Chris@16 85 template <class Element>
Chris@16 86 inline Element find_set(Element x)
Chris@16 87 {
Chris@16 88 return rep(parent, x);
Chris@16 89 }
Chris@16 90
Chris@16 91 template <class ElementIterator>
Chris@16 92 inline std::size_t count_sets(ElementIterator first, ElementIterator last)
Chris@16 93 {
Chris@16 94 std::size_t count = 0;
Chris@16 95 for ( ; first != last; ++first)
Chris@16 96 if (get(parent, *first) == *first)
Chris@16 97 ++count;
Chris@16 98 return count;
Chris@16 99 }
Chris@16 100
Chris@16 101 template <class ElementIterator>
Chris@16 102 inline void normalize_sets(ElementIterator first, ElementIterator last)
Chris@16 103 {
Chris@16 104 for (; first != last; ++first)
Chris@16 105 detail::normalize_node(parent, *first);
Chris@16 106 }
Chris@16 107
Chris@16 108 template <class ElementIterator>
Chris@16 109 inline void compress_sets(ElementIterator first, ElementIterator last)
Chris@16 110 {
Chris@16 111 for (; first != last; ++first)
Chris@16 112 detail::find_representative_with_full_compression(parent, *first);
Chris@16 113 }
Chris@16 114 protected:
Chris@16 115 RankPA rank;
Chris@16 116 ParentPA parent;
Chris@16 117 FindCompress rep;
Chris@16 118 };
Chris@16 119
Chris@16 120
Chris@16 121
Chris@16 122
Chris@16 123 template <class ID = identity_property_map,
Chris@16 124 class InverseID = identity_property_map,
Chris@16 125 class FindCompress = find_with_full_path_compression
Chris@16 126 >
Chris@16 127 class disjoint_sets_with_storage
Chris@16 128 {
Chris@16 129 typedef typename property_traits<ID>::value_type Index;
Chris@16 130 typedef std::vector<Index> ParentContainer;
Chris@16 131 typedef std::vector<unsigned char> RankContainer;
Chris@16 132 public:
Chris@16 133 typedef typename ParentContainer::size_type size_type;
Chris@16 134
Chris@16 135 disjoint_sets_with_storage(size_type n = 0,
Chris@16 136 ID id_ = ID(),
Chris@16 137 InverseID inv = InverseID())
Chris@16 138 : id(id_), id_to_vertex(inv), rank(n, 0), parent(n)
Chris@16 139 {
Chris@16 140 for (Index i = 0; i < n; ++i)
Chris@16 141 parent[i] = i;
Chris@16 142 }
Chris@16 143 // note this is not normally needed
Chris@16 144 template <class Element>
Chris@16 145 inline void
Chris@16 146 make_set(Element x) {
Chris@16 147 parent[x] = x;
Chris@16 148 rank[x] = 0;
Chris@16 149 }
Chris@16 150 template <class Element>
Chris@16 151 inline void
Chris@16 152 link(Element x, Element y)
Chris@16 153 {
Chris@16 154 extend_sets(x,y);
Chris@16 155 detail::link_sets(&parent[0], &rank[0],
Chris@16 156 get(id,x), get(id,y), rep);
Chris@16 157 }
Chris@16 158 template <class Element>
Chris@16 159 inline void
Chris@16 160 union_set(Element x, Element y) {
Chris@16 161 Element rx = find_set(x);
Chris@16 162 Element ry = find_set(y);
Chris@16 163 link(rx, ry);
Chris@16 164 }
Chris@16 165 template <class Element>
Chris@16 166 inline Element find_set(Element x) {
Chris@16 167 return id_to_vertex[rep(&parent[0], get(id,x))];
Chris@16 168 }
Chris@16 169
Chris@16 170 template <class ElementIterator>
Chris@16 171 inline std::size_t count_sets(ElementIterator first, ElementIterator last)
Chris@16 172 {
Chris@16 173 std::size_t count = 0;
Chris@16 174 for ( ; first != last; ++first)
Chris@16 175 if (parent[*first] == *first)
Chris@16 176 ++count;
Chris@16 177 return count;
Chris@16 178 }
Chris@16 179
Chris@16 180 template <class ElementIterator>
Chris@16 181 inline void normalize_sets(ElementIterator first, ElementIterator last)
Chris@16 182 {
Chris@16 183 for (; first != last; ++first)
Chris@16 184 detail::normalize_node(&parent[0], *first);
Chris@16 185 }
Chris@16 186
Chris@16 187 template <class ElementIterator>
Chris@16 188 inline void compress_sets(ElementIterator first, ElementIterator last)
Chris@16 189 {
Chris@16 190 for (; first != last; ++first)
Chris@16 191 detail::find_representative_with_full_compression(&parent[0],
Chris@16 192 *first);
Chris@16 193 }
Chris@16 194
Chris@16 195 const ParentContainer& parents() { return parent; }
Chris@16 196
Chris@16 197 protected:
Chris@16 198
Chris@16 199 template <class Element>
Chris@16 200 inline void
Chris@16 201 extend_sets(Element x, Element y)
Chris@16 202 {
Chris@16 203 Index needed = get(id,x) > get(id,y) ? get(id,x) + 1 : get(id,y) + 1;
Chris@16 204 if (needed > parent.size()) {
Chris@16 205 rank.insert(rank.end(), needed - rank.size(), 0);
Chris@16 206 for (Index k = parent.size(); k < needed; ++k)
Chris@16 207 parent.push_back(k);
Chris@16 208 }
Chris@16 209 }
Chris@16 210
Chris@16 211 ID id;
Chris@16 212 InverseID id_to_vertex;
Chris@16 213 RankContainer rank;
Chris@16 214 ParentContainer parent;
Chris@16 215 FindCompress rep;
Chris@16 216 };
Chris@16 217
Chris@16 218 } // namespace boost
Chris@16 219
Chris@16 220 #endif // BOOST_DISJOINT_SETS_HPP