MinLCA algorithms
outerplanar.hh
Go to the documentation of this file.
1 #ifndef __MINLCA_UTILS_GENERATORS_OUTERPLANAR_HH
2 #define __MINLCA_UTILS_GENERATORS_OUTERPLANAR_HH
3 
4 #include <lemon/smart_graph.h>
5 #include <lemon/random.h>
6 #include "random-graph.hh"
7 #include <utils/graph_utils.hh>
8 
11 
12 namespace minlca
13 {
14 namespace utils
15 {
16 
21 template<typename BaseGraph = lemon::SmartGraph>
22 class RandomOuterplanar : public RandomGraph<BaseGraph>
23 {
24 protected:
27 
28 public:
29  TEMPLATE_GRAPH_TYPEDEFS(Graph);
30 
31 protected:
32  using Base::_r;
33  int _n;
34  int _side_a;
35 
36 public:
39  template<typename Number = int>
40  RandomOuterplanar(Number seed = 0)
41  : Base(seed)
42  {
43  }
44 
47  RandomOuterplanar(lemon::Random &r)
48  : Base(r)
49  {
50  }
51 
53  Graph &init(
54  int n
55  )
56  {
57  _n = n;
58  return *this;
59  }
60 
61  virtual void generate()
62  {
63  using namespace lemon;
64  this->clear();
65  this->reserveNode(_n);
66  this->reserveEdge(2 * _n);
67 
68  _side_a = _r->integer(1, _n / 2);
69 
70  for (int i = 0; i < _n; ++i) {
71  this->addNode();
72  }
73 
74  _crossingChords(0, _side_a - 1, _side_a, _n - 1);
75 
76  for (int i = 0; i < _side_a - 1; ++i)
77  if (findEdge(*this, this->nodeFromId(i), this->nodeFromId(i + 1)) == INVALID) {
78  this->addEdge(this->nodeFromId(i), this->nodeFromId(i + 1));
79  }
80 
81  for (int i = _side_a; i < _n - 1; ++i)
82  if (findEdge(*this, this->nodeFromId(i), this->nodeFromId(i + 1)) == INVALID) {
83  this->addEdge(this->nodeFromId(i), this->nodeFromId(i + 1));
84  }
85 
86  if (findEdge(*this, this->nodeFromId(0),
87  this->nodeFromId(_side_a)) == INVALID) {
88  this->addEdge(this->nodeFromId(0), this->nodeFromId(_side_a));
89  }
90 
91  if (findEdge(*this, this->nodeFromId(_side_a - 1),
92  this->nodeFromId(_n - 1)) == INVALID) {
93  this->addEdge(this->nodeFromId(_side_a - 1), this->nodeFromId(_n - 1));
94  }
95 
96  int bridgeLeft = 0;
97 
98  while (bridgeLeft < _side_a) {
99  while (bridgeLeft < _side_a
100  and degree(*this, this->nodeFromId(bridgeLeft)) > 2) {
101  ++bridgeLeft;
102  }
103 
104  int bridgeRight = bridgeLeft;
105 
106  while (bridgeRight < _side_a
107  and degree(*this, this->nodeFromId(bridgeRight)) == 2) {
108  ++bridgeRight;
109  }
110 
111  if (bridgeRight < _side_a) {
112  _bridges(bridgeLeft, bridgeRight);
113  }
114 
115  bridgeLeft = bridgeRight + 1;
116  }
117 
118  bridgeLeft = _side_a;
119 
120  while (bridgeLeft < _n) {
121  while (bridgeLeft < _n and degree(*this, this->nodeFromId(bridgeLeft)) > 2) {
122  ++bridgeLeft;
123  }
124 
125  int bridgeRight = bridgeLeft;
126 
127  while (bridgeRight < _n
128  and degree(*this, this->nodeFromId(bridgeRight)) == 2) {
129  ++bridgeRight;
130  }
131 
132  if (bridgeRight < _n) {
133  _bridges(bridgeLeft, bridgeRight);
134  }
135 
136  bridgeLeft = bridgeRight + 1;
137  }
138  }
139 
143  int sideA() const
144  {
145  return _side_a;
146  }
147 
148 protected:
150  void _crossingChords(int l1, int r1, int l2, int r2)
151  {
152  if (r1 < l1 or r2 < l2) {
153  return;
154  }
155 
156  int top = _r->integer(l1, r1 + 1);
157  int bottom = _r->integer(l2, r2 + 1);
158  this->addEdge(this->nodeFromId(top), this->nodeFromId(bottom));
159 
160  if (_r->boolean()) {
161  _crossingChords(l1, top, l2, bottom - 1);
162  }
163  else {
164  _crossingChords(l1, top - 1, l2, bottom);
165  }
166 
167  if (_r->boolean()) {
168  _crossingChords(top, r1, bottom + 1, r2);
169  }
170  else {
171  _crossingChords(top + 1, r1, bottom, r2);
172  }
173  }
174 
176  void _bridges(int l, int r)
177  {
178  if (r < l + 2) {
179  return;
180  }
181 
182  if (_r->boolean()) {
183  this->addEdge(this->nodeFromId(l), this->nodeFromId(r));
184  }
185 
186  switch (_r->integer(3)) {
187  case 0:
188  _bridges(l + 1, r - 1);
189  break;
190 
191  case 1:
192  _bridges(l, r - 1);
193  break;
194 
195  default:
196  _bridges(l + 1, r);
197  }
198  }
199 };
200 }
201 }
202 
203 #endif
void _bridges(int l, int r)
Add bridges.
Definition: outerplanar.hh:176
int _n
Number of vertices.
Definition: outerplanar.hh:33
lemon::Random * _r
Random number generator.
Definition: random-graph.hh:19
void seed(Number seed)
Change the random number generator seed.
Definition: random-graph.hh:56
Contains base definitions for defining particular random graphs.
LEMON namespace.
Definition: grb.cc:29
Default namespace Default namespace for MinLCA algorithms.
Definition: base.hh:15
RandomOuterplanar(Number seed=0)
Constructor with seed.
Definition: outerplanar.hh:40
Functions for reading graphs and getting graph properties.
RandomOuterplanar(lemon::Random &r)
Constructor with custom random number generator.
Definition: outerplanar.hh:47
void _crossingChords(int l1, int r1, int l2, int r2)
Add chrossing chords.
Definition: outerplanar.hh:150
int sideA() const
Retrieve number of vertices on side A
Definition: outerplanar.hh:143
int degree(const Graph &g, const typename Graph::Node &v)
Degree of a vertex.
Definition: graph_utils.hh:171
int _side_a
Number of vertices on side A
Definition: outerplanar.hh:34
Class defining random geometric graphs.
Definition: outerplanar.hh:22
virtual void generate()
Generate graph.
Definition: outerplanar.hh:61
Graph & init(int n)
Initialise the generator.
Definition: outerplanar.hh:53
Base class for random graph generators.
Definition: random-graph.hh:16