Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

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.