15 #ifndef PAAL_VORONOI_HPP
16 #define PAAL_VORONOI_HPP
23 #include <boost/range/as_array.hpp>
24 #include <boost/range/adaptor/map.hpp>
25 #include <boost/functional/hash.hpp>
27 #include <unordered_set>
28 #include <unordered_map>
34 namespace data_structures {
42 template <
typename Metric>
class voronoi {
44 typedef typename metric_traits<Metric>::VertexType VertexType;
45 typedef std::multimap<VertexType, VertexType> GeneratorsToVertices;
46 typedef std::unordered_set<VertexType, boost::hash<VertexType>>
50 typedef GeneratorsSet Vertices;
52 typedef std::unordered_map<VertexType,
53 typename GeneratorsToVertices::iterator,
54 boost::hash<VertexType>> VerticesToGenerators;
56 VerticesToGenerators m_vertices_to_generators;
57 GeneratorsToVertices m_generators_to_vertices;
59 GeneratorsSet m_generators;
61 const Metric &m_metric;
62 const Dist m_cost_of_no_generator;
73 voronoi(
const GeneratorsSet &generators, Vertices vertices,
const Metric &m,
74 Dist costOfNoGenerator = std::numeric_limits<Dist>::max())
75 : m_vertices(std::move(vertices)), m_metric(m),
76 m_cost_of_no_generator(costOfNoGenerator) {
77 for (VertexType f : generators) {
88 : m_generators_to_vertices(v.m_generators_to_vertices),
89 m_vertices(v.m_vertices), m_generators(v.m_generators),
91 m_cost_of_no_generator(v.m_cost_of_no_generator) {
92 auto b = m_generators_to_vertices.begin();
93 auto e = m_generators_to_vertices.end();
95 m_vertices_to_generators.insert(std::make_pair(b->second, b));
105 : m_vertices_to_generators(std::move(v.m_vertices_to_generators)),
106 m_generators_to_vertices(std::move(v.m_generators_to_vertices)),
107 m_vertices(std::move(v.m_vertices)),
108 m_generators(std::move(v.m_generators)), m_metric(v.m_metric),
109 m_cost_of_no_generator(v.m_cost_of_no_generator) {}
114 m_generators.insert(f);
117 if (m_generators.size() == 1) {
118 m_vertices_to_generators.clear();
119 m_generators_to_vertices.clear();
120 for (VertexType v : m_vertices) {
121 m_vertices_to_generators[v] =
122 m_generators_to_vertices.insert(std::make_pair(f, v));
123 cost += m_metric(v, f);
126 cost = cost - m_cost_of_no_generator;
129 for (VertexType v : m_vertices) {
130 Dist d = m_metric(v, f) - dist(v);
143 if (m_generators.size() == 1) {
144 cost = m_cost_of_no_generator;
145 for (VertexType v : m_vertices) {
148 m_vertices_to_generators.clear();
149 m_generators_to_vertices.clear();
153 auto begin = m_generators_to_vertices.lower_bound(f);
154 auto end = m_generators_to_vertices.upper_bound(f);
155 for (; begin != end;) {
156 auto v = begin->second;
162 cost += adjust_vertex(v, op);
165 m_generators.erase(f);
189 decltype(boost::as_array(m_generators_to_vertices.equal_range(g) |
190 boost::adaptors::map_values))
192 return boost::as_array(m_generators_to_vertices.equal_range(g) |
193 boost::adaptors::map_values);
198 return boost::equal(m_generators_to_vertices, vor.m_generators_to_vertices) &&
199 m_cost_of_no_generator == vor.m_cost_of_no_generator &&
200 m_metric == vor.m_metric;
212 Dist dist(VertexType v) {
return m_metric(v, vertex_to_generators(v)); }
224 template <
typename Filter = utils::always_true>
225 Dist adjust_vertex(VertexType v, Filter filter = Filter()) {
228 VertexType f_best = VertexType();
229 for (VertexType f : m_generators) {
231 Dist td = m_metric(v, f);
232 if (init || td < d) {
251 VertexType vertex_to_generators(VertexType v)
const {
252 auto i = m_vertices_to_generators.find(v);
253 assert(i != m_vertices_to_generators.end());
254 return i->second->first;
263 void assign(VertexType v, VertexType f) {
264 auto prev = m_vertices_to_generators.at(v);
265 m_generators_to_vertices.erase(prev);
266 m_vertices_to_generators[v] =
267 m_generators_to_vertices.insert(std::make_pair(f, v));
274 template <
typename Metric>
275 using v_t =
typename metric_traits<Metric>::VertexType;
277 template <
typename Metric>
278 using generators_set_t = std::unordered_set<v_t<Metric>, boost::hash<v_t<Metric>>>;
280 template <
typename Metric>
281 using dist_t =
typename metric_traits<Metric>::DistanceType;
285 template <
typename Metric>
287 const detail::generators_set_t<Metric> & generators,
288 detail::generators_set_t<Metric> vertices,
289 const Metric & metric,
290 detail::dist_t<Metric> costOfNoGenerator = std::numeric_limits<detail::dist_t<Metric>>::max())
292 return voronoi<Metric>(generators, std::move(vertices), metric, costOfNoGenerator);
300 template <
typename Metric>
302 voronoi<Metric>, typename metric_traits<Metric>::VertexType> {};
306 #endif // PAAL_VORONOI_HPP
voronoi(voronoi &&v)
Move constructor.
voronoi< Metric > make_voronoi(const detail::generators_set_t< Metric > &generators, detail::generators_set_t< Metric > vertices, const Metric &metric, detail::dist_t< Metric > costOfNoGenerator=std::numeric_limits< detail::dist_t< Metric >>::max())
make for voronoi
Dist add_generator(VertexType f)
returns diff between new cost and old cost
const GeneratorsSet & get_generators() const
getter for generators
default VertexType is int.
auto get_vertices_for_generator(VertexType g) const -> decltype(boost::as_array(m_generators_to_vertices.equal_range(g)|boost::adaptors::map_values))
getter for vertices assigned to specific generator
bool operator==(const voronoi &vor) const
operator==
voronoi(const voronoi &v)
Copy constructor.
const Vertices & get_vertices() const
getter for vertices
This file contains set of simple useful functors or functor adapters.
Dist rem_generator(VertexType f)
returns diff between new cost and old cost
simple implementation of the Voronoi concept.
voronoi(const GeneratorsSet &generators, Vertices vertices, const Metric &m, Dist costOfNoGenerator=std::numeric_limits< Dist >::max())
Constructor.
puretype(std::declval< Metric >()(std::declval< VertexType >(), std::declval< VertexType >())) DistanceType
Distance type.