Loading [MathJax]/extensions/tex2jax.js

Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
RandomPoint.h
Go to the documentation of this file.
1
31#pragma once
32
33#ifdef OGDF_INCLUDE_CGAL
34
39
40namespace ogdf {
41namespace internal {
42namespace gcm {
43namespace graph {
44
45template<typename Kernel>
47private:
49
50 using Point = geometry::Point_t<Kernel>;
51 using Segment = geometry::LineSegment_t<Kernel>;
52 using Polygon = geometry::Polygon_t<Kernel>;
53
54 static std::vector<int> vertex_weights(const BD& bd, const Point& p,
55 const std::vector<int>& left_to_right_cost, std::vector<bool>& visited,
56 datastructure::UnionFind& uf) {
57 typename BD::Node min_node = bd.segm_to_node_range[left_to_right_cost.size() - 4];
58
59 auto rep = geometry::find_representative_node(bd, p);
60
61 int min_weight = 0; // this value becomes negative, if we can improve...
62 int max_weight = 0; // this value becomes negative, if we can improve...
63
64
65 std::vector<typename BD::Node> parent(bd.number_of_nodes());
66 std::vector<typename BD::Edge> parent_edge(bd.number_of_nodes());
67
68 auto f_weight = [&](typename BD::Node v, typename BD::Edge e) {
69 if (bd.is_face_edge(e) || bd.degree(v) == 2) {
70 return 0;
71 } else if (bd.is_left(v)) {
72 return left_to_right_cost[bd.node_to_segment[v]];
73 } else {
74 return -left_to_right_cost[bd.node_to_segment[v]];
75 }
76 };
77
78 auto expand = [&](typename BD::Node w, typename BD::Edge e) {
79 bool bad_edge = w >= min_node && bd.edges[e] >= min_node; //TODO correct??
80 return !bad_edge;
81 };
82
83 parent[rep] = rep;
84
85 std::vector<typename BD::Node> queue;
86 std::vector<int> weight(bd.number_of_nodes(), 0);
87
88
89 queue.push_back(rep);
90 weight[rep] = 0;
91 visited[rep] = true;
92
93 auto handle_edge = [&](typename BD::Node v, typename BD::Edge e) {
94 typename BD::Node w = bd.edges[e];
95 OGDF_ASSERT(!visited[w] || v == w || weight[w] == weight[v] + f_weight(v, e));
96
97 if (!visited[w] && expand(v, e) && v != w) {
98 weight[w] = weight[v] + f_weight(v, e);
99 visited[w] = true;
100 queue.push_back(w);
101 parent[w] = v;
102 parent_edge[w] = e;
103 if (bd.is_face_edge(e)) {
104 uf.merge(v, w);
105 }
106 }
107 };
108
109 while (!queue.empty()) {
110 typename BD::Node current = queue.back();
111 queue.pop_back();
112 min_weight = std::min(min_weight, weight[current]);
113 max_weight = std::max(max_weight, weight[current]);
114
116 handle_edge(current, 3 * current + 1);
117 handle_edge(current, 3 * current + 2);
118 }
119
120 for (auto& w : weight) {
121 w = max_weight - w + 1;
122 }
123
124 return weight;
125 }
126
127public:
128 static std::vector<Point> compute(const BD& bd, const std::vector<int>& left_to_right_cost,
129 const Point& reference, unsigned int nof_points, std::mt19937_64& gen) {
130 datastructure::UnionFind uf(bd.number_of_nodes());
131 uf.all_to_singletons();
132
133 std::vector<bool> visited(bd.number_of_nodes(), false);
134 std::vector<int> weights = vertex_weights(bd, reference, left_to_right_cost, visited, uf);
135
136 std::vector<unsigned int> repr;
137 for (unsigned int u = 0; u < bd.number_of_nodes(); ++u) {
138 if (uf.find(u) == u && visited[u]) {
139 repr.push_back(u);
140 }
141 }
142
143
144 std::vector<double> repr_weights(repr.size(), 0);
145 std::vector<unsigned int> interval;
146
147 for (unsigned int i = 0; i < repr.size(); ++i) {
148 repr_weights[i] = std::pow(2, weights[repr[i]]);
149
150 interval.push_back(i);
151 }
152
153 interval.push_back(repr.size());
154
155 std::piecewise_constant_distribution<double> dist(interval.begin(), interval.end(),
156 repr_weights.begin());
157
158 std::vector<Point> point_set;
159 if (!repr.empty()) {
160 for (unsigned int r = 0; r < nof_points; ++r) {
161 //select a region randomly inverse proportional to its number of crossings
162 unsigned int v_id = std::floor(dist(gen));
163 OGDF_ASSERT(v_id < repr.size());
164 unsigned int v = repr[v_id];
165
166 OGDF_ASSERT(v < bd.number_of_nodes());
167 auto seq = geometry::extract_cell(bd, v);
168 auto region = geometry::extract_polygon(bd.segments, seq);
169 if (CGAL::abs(region.area()) > 1e-5) {
170 auto p = geometry::random_point_in_polygon(region, gen);
171 point_set.push_back(p);
172 }
173 }
174 }
175 return point_set;
176 }
177};
178
179
180}
181}
182}
183}
184
185#endif
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:41
int r[]
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.