DeSiGNAR  0.5a
Data Structures General Library
buildgraph.H
Go to the documentation of this file.
1 /*
2  This file is part of Designar.
3  Copyright (C) 2017 by Alejandro J. Mujica
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  Any user request of this software, write to
19 
20  Alejandro Mujica
21 
22  aledrums@gmail.com
23 */
24 
25 # ifndef DSGBUILDGRAPH_H
26 # define DSGBUILDGRAPH_H
27 
28 # include <graphalgorithms.H>
29 # include <random.H>
30 
31 namespace Designar
32 {
33  template <class GT, class NodeInit, class ArcInit>
34  GT full_graph(nat_t, NodeInit &, ArcInit &);
35 
36  template <class GT,
37  class NodeInit = DftNodeInit<GT>,
38  class ArcInit = DftArcInit<GT>>
39  GT full_graph(nat_t, NodeInit && node_init = NodeInit(),
40  ArcInit && arc_init = ArcInit());
41 
42  template <class GT, class NodeInit, class ArcInit>
43  GT build_grid(nat_t width, nat_t height, NodeInit & node_init,
44  ArcInit & arc_init, bool with_diagonal = true);
45 
46  template <class GT,
47  class NodeInit = DftGridNodeInit<GT>,
48  class ArcInit = DftGridArcInit<GT>>
49  GT build_grid(nat_t width, nat_t height, NodeInit && node_init = NodeInit(),
50  ArcInit && arc_init = ArcInit(), bool with_diagonal = true);
51 
52  template <class GT, class NodeInit, class ArcInit>
53  GT random_graph(nat_t, nat_t, rng_seed_t, NodeInit &, ArcInit &);
54 
55  template <class GT,
56  class NodeInit = DftNodeInit<GT>,
57  class ArcInit = DftArcInit<GT>>
59  NodeInit && node_init = NodeInit(),
60  ArcInit && arc_init = ArcInit());
61 
62  template <class GT,
63  class NodeInit = DftNodeInit<GT>,
64  class ArcInit = DftArcInit<GT>>
66  NodeInit && node_init = NodeInit(),
67  ArcInit && arc_init = ArcInit());
68 
69  template <class GT, class NodeInit, class ArcInit>
70  GT ps_random_graph(nat_t, real_t, rng_seed_t, bool, NodeInit &, ArcInit &);
71 
72  template <class GT,
73  class NodeInit = DftNodeInit<GT>,
74  class ArcInit = DftArcInit<GT>>
75  GT ps_random_graph(nat_t, real_t, rng_seed_t, bool grant_connectivity = false,
76  NodeInit && node_init = NodeInit(),
77  ArcInit && arc_init = ArcInit());
78 
79  template <class GT, class NodeInit, class ArcInit>
80  GT p_random_graph(nat_t, real_t, bool, NodeInit &, ArcInit &);
81 
82  template <class GT,
83  class NodeInit = DftNodeInit<GT>,
84  class ArcInit = DftArcInit<GT>>
85  GT p_random_graph(nat_t, real_t, bool grant_connectivity = false,
86  NodeInit && node_init = NodeInit(),
87  ArcInit && arc_init = ArcInit());
88 
89  template <class GT, class NodeInit, class ArcInit>
90  GT full_graph(nat_t num_nodes, NodeInit & node_init, ArcInit & arc_init)
91  {
92  GT g;
93 
94  FixedArray<Node<GT> *> nodes(num_nodes);
95 
96  for (nat_t i = 0; i < num_nodes; ++i)
97  {
98  Node<GT> * p = g.insert_node();
99  node_init(p);
100  nodes[i] = p;
101  }
102 
103  for (nat_t i = 0; i < num_nodes - 1; ++i)
104  for (nat_t j = i + 1; j < num_nodes; ++j)
105  {
106  Node<GT> * s = nodes[i];
107  Node<GT> * t = nodes[j];
108  Arc<GT> * fa = g.insert_arc(s, t);
109  arc_init(fa);
110 
111  if (not g.is_digraph())
112  continue;
113 
114  Arc<GT> * ba = g.insert_arc(t, s);
115  arc_init(ba);
116  }
117 
118  return g;
119  }
120 
121  template <class GT, class NodeInit, class ArcInit>
122  GT full_graph(nat_t num_nodes, NodeInit && node_init, ArcInit && arc_init)
123  {
124  return full_graph<GT, NodeInit, ArcInit>(num_nodes, node_init, arc_init);
125  }
126 
127  template <class GT, class NodeInit, class ArcInit>
128  GT build_grid(nat_t width, nat_t height, NodeInit & node_init,
129  ArcInit & arc_init, bool with_diagonal)
130  {
131  if (width < 2 or height < 2)
132  throw std::length_error("The minimun size must be 2 x 2");
133 
134  MultiDimArray<Node<GT> *, 2> mat(height, width);
135 
136  GT g;
137 
138  for (nat_t i = 0; i < height; ++i)
139  for (nat_t j = 0; j < width; ++j)
140  {
141  mat(i, j) = g.insert_node();
142  node_init(mat(i ,j), i, j);
143 
144  if (j > 0)
145  {
146  auto a = g.insert_arc(mat(i, j - 1), mat(i, j));
147  arc_init(a);
148  }
149 
150  if (i > 0)
151  {
152  auto a = g.insert_arc(mat(i - 1, j), mat(i, j));
153  arc_init(a);
154  }
155 
156  if (with_diagonal)
157  {
158  if (i > 0 and j > 0)
159  {
160  auto a = g.insert_arc(mat(i - 1, j - 1), mat(i, j));
161  arc_init(a);
162  }
163 
164  if (i > 0 and j + 1 < width)
165  {
166  auto a = g.insert_arc(mat(i - 1, j + 1), mat(i, j));
167  arc_init(a);
168  }
169  }
170  }
171 
172  return g;
173  }
174 
175  template <class GT, class NodeInit, class ArcInit>
176  GT build_grid(nat_t width, nat_t height, NodeInit && node_init,
177  ArcInit && arc_init, bool with_diagonal)
178  {
179  return build_grid<GT, NodeInit, ArcInit>
180  (width, height, node_init, arc_init, with_diagonal);
181  }
182 
183  template <class GT, class NodeInit, class ArcInit>
184  GT random_graph(nat_t num_nodes, nat_t num_arcs, rng_seed_t seed,
185  NodeInit & node_init, ArcInit & arc_init)
186  {
187  GT g;
188 
189  FixedArray<Node<GT> *> nodes(num_nodes);
190 
191  rng_t rng(seed);
192 
193  for (nat_t i = 0; i < num_nodes; ++i)
194  {
195  Node<GT> * p = g.insert_node();
196  node_init(p);
197  nodes[i] = p;
198  }
199 
200  for (nat_t i = 0; i < num_arcs; ++i)
201  {
202  Node<GT> * s = nodes[random_uniform(rng, nodes.size())];
203  Node<GT> * t = nodes[random_uniform(rng, nodes.size())];
204 
205  if (s == t)
206  continue;
207 
208  if (g.search_arc(s, t) != nullptr)
209  continue;
210 
211  Arc<GT> * a = g.insert_arc(s, t);
212  arc_init(a);
213  }
214 
215  return g;
216  }
217 
218  template <class GT, class NodeInit, class ArcInit>
219  GT random_graph(nat_t num_nodes, nat_t num_arcs, rng_seed_t seed,
220  NodeInit && node_init, ArcInit && arc_init)
221  {
222  return random_graph<GT, NodeInit, ArcInit>
223  (num_nodes, num_arcs, seed, node_init, arc_init);
224  }
225 
226  template <class GT, class NodeInit, class ArcInit>
227  GT random_graph(nat_t num_nodes, nat_t num_arcs,
228  NodeInit && node_init, ArcInit && arc_init)
229  {
230  return random_graph<GT, NodeInit, ArcInit>
231  (num_nodes, num_arcs, get_random_seed(), node_init, arc_init);
232  }
233 
234  template <class GT, class NodeInit, class ArcInit>
235  GT ps_random_graph(nat_t num_nodes, real_t prob_arc, rng_seed_t seed,
236  bool grant_connectivity, NodeInit & node_init,
237  ArcInit & arc_init)
238  {
239  GT g;
240 
241  FixedArray<Node<GT> *> nodes(num_nodes);
242 
243  rng_t rng(seed);
244 
245  for (nat_t i = 0; i < num_nodes; ++i)
246  {
247  Node<GT> * p = g.insert_node();
248  node_init(p);
249  nodes[i] = p;
250  }
251 
252  for (nat_t i = 0; i < num_nodes - 1; ++i)
253  for (nat_t j = i + 1; j < num_nodes; ++j)
254  if (random_Bernoulli(rng, prob_arc))
255  {
256  Arc<GT> * a = g.insert_arc(nodes[i], nodes[j]);
257  arc_init(a);
258  }
259 
260  if (not grant_connectivity)
261  return g;
262 
263  auto l = connected_components_node_list(g);
264 
265  if (l.size() == 1)
266  return g;
267 
268  auto it1 = l.begin();
269  auto it2 = l.begin();
270  it2.next();
271 
272  for ( ; it2.has_current(); it1.next(), it2.next())
273  {
274  auto & l1 = *it1;
275  auto & l2 = *it2;
276 
277  Arc<GT> * a = g.insert_arc(l1.get_first(), l2.get_last());
278  arc_init(a);
279  }
280 
281  return g;
282  }
283 
284  template <class GT, class NodeInit, class ArcInit>
285  GT ps_random_graph(nat_t num_nodes, real_t prob_arc, rng_seed_t seed,
286  bool grant_connectivity, NodeInit && node_init,
287  ArcInit && arc_init)
288  {
289  return ps_random_graph<GT, NodeInit, ArcInit>
290  (num_nodes, prob_arc, seed, grant_connectivity, node_init, arc_init);
291  }
292 
293  template <class GT, class NodeInit, class ArcInit>
294  GT p_random_graph(nat_t num_nodes, real_t prob_arc, bool grant_connectivity,
295  NodeInit & node_init, ArcInit & arc_init)
296  {
297  return ps_random_graph<GT, NodeInit, ArcInit>
298  (num_nodes, prob_arc, get_random_seed(), grant_connectivity,
299  node_init, arc_init);
300  }
301 
302  template <class GT, class NodeInit, class ArcInit>
303  GT p_random_graph(nat_t num_nodes, real_t prob_arc, bool grant_connectivity,
304  NodeInit && node_init, ArcInit && arc_init)
305  {
306  return p_random_graph<GT, NodeInit, ArcInit>
307  (num_nodes, prob_arc, grant_connectivity, node_init, arc_init);
308  }
309 
310 } // end namespace Designar
311 
312 # endif // DSGBUILDGRAPH_H
GT build_grid(nat_t width, nat_t height, NodeInit &node_init, ArcInit &arc_init, bool with_diagonal=true)
Definition: buildgraph.H:128
T random_uniform(rng_t &, T)
Definition: random.H:54
double real_t
Definition: types.H:51
nat_t size() const
Definition: array.H:271
GT full_graph(nat_t, NodeInit &, ArcInit &)
Definition: buildgraph.H:90
GT p_random_graph(nat_t, real_t, bool, NodeInit &, ArcInit &)
Definition: buildgraph.H:294
std::mt19937_64 rng_t
Definition: types.H:52
rng_t::result_type rng_seed_t
Definition: types.H:53
rng_seed_t get_random_seed()
typename GT::Node Node
Definition: graphutilities.H:78
SLList< SLList< Node< GT > * > > connected_components_node_list(const GT &)
Definition: graphalgorithms.H:499
GT ps_random_graph(nat_t, real_t, rng_seed_t, bool, NodeInit &, ArcInit &)
Definition: buildgraph.H:235
Definition: array.H:182
GT random_graph(nat_t, nat_t, rng_seed_t, NodeInit &, ArcInit &)
Definition: buildgraph.H:184
Definition: array.H:32
Definition: array.H:745
unsigned long int nat_t
Definition: types.H:50
bool random_Bernoulli(rng_t &, real_t p=DEFAULT_P)
typename GT::Arc Arc
Definition: graphutilities.H:79