Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

CrossingMinimalPositionRnd.h
Go to the documentation of this file.
1 
31 #pragma once
32 
33 #ifdef OGDF_INCLUDE_CGAL
34 
39 
40 namespace ogdf {
41 namespace internal {
42 namespace gcm {
43 namespace graph {
44 
45 template<typename Kernel, typename Graph, typename CRegion = CrossingMinimalRegion<Kernel, Graph>>
46 class CrossingMinimalPositionRnd {
47 private:
48  using Point = geometry::Point_t<Kernel>;
49  using Segment = geometry::LineSegment_t<Kernel>;
50  using Polygon = geometry::Polygon_t<Kernel>;
51  using Drawing = graph::GeometricDrawing<Kernel, Graph>;
52  using Node = typename Graph::Node;
53  using Edge = typename Graph::Edge;
54 
55 public:
56  static Point compute(const Drawing& d, const Node& v, const std::vector<Edge>& sample,
57  const unsigned int random_draws, const unsigned int neighbor_threshold,
58  geometry::Rectangle_t<Kernel>& rect_box,
59  bool use_min_region //otherwise select with probability to cr. number
60  ,
61  std::mt19937_64& rnd) {
62  unsigned int dump_a, dump_b;
63 
64  std::vector<Node> neighbors;
65  for (Node u : d.get_graph().neighbors(v)) {
66  neighbors.push_back(u);
67  }
68 
69  std::shuffle(neighbors.begin(), neighbors.end(), rnd);
70 
71  std::vector<Node> current;
72 
73 
74  Point p = d.get_point(v);
75  auto count = [&](Point p_v) {
76  unsigned int n_cr = 0;
77  for (auto edge : d.get_graph().edges()) {
78  if (!edge->isIncident(v)) {
79  Segment s = d.get_segment(edge);
80  for (auto u : d.get_graph().neighbors(v)) {
81  if (!edge->isIncident(u)) {
82  Segment s_f(p_v, d.get_point(u));
83  n_cr += CGAL::do_intersect(s, s_f);
84  }
85  }
86  }
87  }
88  return n_cr;
89  };
90 
91  unsigned int min_cr = count(p);
92 
93  for (size_t i = 0; i < neighbors.size(); i = i + neighbor_threshold) {
94  current.clear();
95  std::copy(neighbors.begin() + i,
96  neighbors.begin() + std::min(i + neighbor_threshold, neighbors.size()),
97  std::back_inserter(current));
98  if (use_min_region) {
99  CRegion cr;
100 
101  auto region = cr.compute(d, v, current, sample, rect_box, dump_a, dump_b);
102 
103  OGDF_ASSERT(!CGAL::is_zero(CGAL::abs(region.area())));
104 
105  if (geometry::is_clockwise(region)) {
106  region = geometry::reverse(region);
107  }
108 
109  if (region.size() > 2) {
110  for (unsigned int x = 0; x < random_draws; ++x) {
111  Point p_v = geometry::random_point_in_polygon(region, rnd);
112  unsigned int n_cr = count(p_v);
113  if (n_cr < min_cr) {
114  min_cr = n_cr;
115  p = p_v;
116  }
117  }
118  }
119  } else {
120  CRegion cr;
121 
122  cr.build_bd(d, v, current, sample, rect_box, dump_a, dump_b);
123 
124  auto rnd_points = RandomPointsInCell<Kernel>::compute(cr.bd, cr.left_to_right_cost,
125  d.get_point(v), random_draws, rnd);
126 
127  for (auto p_v : rnd_points) {
128  unsigned int n_cr = count(p_v);
129  if (n_cr < min_cr) {
130  min_cr = n_cr;
131  p = p_v;
132  }
133  }
134  }
135  }
136 
137  //round
138  OGDF_ASSERT(rect_box.has_on_bounded_side(p));
139  p = Point(CGAL::to_double(p.x()), CGAL::to_double(p.y()));
140  OGDF_ASSERT(rect_box.has_on_bounded_side(p));
141  return p;
142  }
143 };
144 
145 }
146 }
147 }
148 }
149 
150 #endif
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
CrossingMinimalRegion.h
ogdf::gml::Key::Node
@ Node
ogdf::gml::Key::Edge
@ Edge
CollinearTriple.h
ogdf::reverse
Reverse< T > reverse(T &container)
Provides iterators for container to make it easily iterable in reverse.
Definition: Reverse.h:74
ogdf::edge
EdgeElement * edge
The type of edges.
Definition: Graph_d.h:74
Minisat::Internal::copy
static void copy(const T &from, T &to)
Definition: Alg.h:61
ogdf::gml::Key::Point
@ Point
ogdf::EdgeElement::isIncident
bool isIncident(node v) const
Returns true iff v is incident to the edge.
Definition: Graph_d.h:444
RandomPointInPolygon.h
RandomPoint.h