Quetzal-CoaTL
The Coalescence Template Library
Loading...
Searching...
No Matches
graph.hpp
1// Copyright 2021 Arnaud Becheler <abechele@umich.edu>
2
10
11#pragma once
12
13#include <boost/range/adaptor/transformed.hpp>
14#include <boost/range/iterator_range.hpp>
15
16#include <boost/graph/connected_components.hpp>
17#include <boost/graph/isomorphism.hpp>
18#include <boost/graph/random.hpp>
19#include <boost/graph/topological_sort.hpp>
20
21#include "detail/adl_resolution.hpp"
22#include "detail/concepts.hpp"
23
24#include <algorithm>
25#include <iostream>
26#include <optional>
27#include <type_traits>
28#include <ranges>
29
30namespace quetzal::geography
31{
32
33namespace detail
34{
35
36// Base class and common implementation
37template <class CRTP, class VertexProperty, class EdgeProperty, connectedness Representation, directional Directed>
39{
40
41 protected:
43 using base_type = typename Representation::rebind<Directed, VertexProperty, EdgeProperty>;
44 base_type _graph;
45
46 public:
48 explicit graph_common() : _graph()
49 {
50 }
51
53 explicit graph_common(size_t n) : _graph(n)
54 {
55 }
56
58 using vertex_property = VertexProperty;
59
61 using edge_property = EdgeProperty;
62
64 using directed_category = Directed;
65
67 using vertex_descriptor = typename base_type::vertex_descriptor;
68
70 using edge_descriptor = typename base_type::edge_descriptor;
71
73 using degree_size_type = typename base_type::degree_size_type;
74
76 using traversal_category = typename base_type::traversal_category;
77
79 using in_edge_iterator = typename base_type::in_edge_iterator;
80
82 using out_edge_iterator = typename base_type::out_edge_iterator;
83
84 using edge_parallel_category = typename base_type::edge_parallel_category;
85
88
91 int num_vertices() const
92 {
93 return boost::num_vertices(_graph);
94 }
95
98 int num_edges() const
99 {
100 return boost::num_edges(_graph);
101 }
102
107 bool is_isomorphic(graph_common const &other) const
108 {
109 return boost::isomorphism(_graph, other._graph);
110 }
111
116 {
117 return boost::degree(u, _graph);
118 }
119
124 {
125 return boost::in_degree(u, _graph);
126 }
127
130 {
131 return boost::out_degree(v, _graph);
132 }
133
138 std::optional<edge_descriptor> edge(vertex_descriptor u, vertex_descriptor v) const
139 {
140 auto p = boost::edge(u, v, _graph);
141 return p.second ? std::make_optional(p.first) : std::nullopt;
142 }
143
148 {
149 return boost::source(e, _graph);
150 }
151
156 {
157 return boost::target(e, _graph);
158 }
159
161
164
166 vertex_descriptor add_vertex()
167 {
168 return boost::add_vertex(_graph);
169 }
170
174 {
175 return boost::clear_vertex(u, _graph);
176 }
177
181 {
182 clear_vertex(u);
183 return boost::remove_vertex(u, _graph);
184 }
185
191 {
192 return boost::add_edge(u, v, _graph).first;
193 }
194
199 {
200 return boost::remove_edge(u, v, _graph);
201 }
202
206 {
207 return boost::remove_edge(e, _graph);
208 }
209
211
214
219 {
220 return boost::make_iterator_range(boost::in_edges(u, _graph));
221 }
222
227 {
228 return boost::make_iterator_range(boost::out_edges(u, _graph));
229 }
230
233 auto vertices() const
234 {
235 return boost::make_iterator_range(boost::vertices(_graph));
236 }
237
240 auto edges() const
241 {
242 auto [first, last] = boost::edges(_graph);
243 return std::ranges::subrange(first, last);
244 }
245
247
250 static constexpr inline vertex_descriptor null_vertex()
251 {
252 return base_type::null_vertex();
253 }
254
255}; // end class graph_common
256
257} // end namespace detail
258
259// Base for template partial specialization
260template <class VertexProperty, class EdgeProperty, connectedness Representation, directional Directed>
261class graph
262{
263};
264
270template < connectedness Representation, directional Directed>
271class graph<no_property, no_property, Representation, Directed> :
272public detail::graph_common<graph<no_property, no_property, Representation, Directed>, no_property, no_property, Representation, Directed>
273{
274 private:
277
278 public:
281
283 explicit graph() : base_type()
284 {
285 }
286
288 explicit graph(size_t n) : base_type(n)
289 {
290 }
292
293}; // end specialization graph<boost::no::property, boost::no_property>
294
301template <class VertexProperty, connectedness Representation, directional Directed>
302 requires(!std::is_same_v<VertexProperty, no_property>)
304 : public detail::graph_common<graph<VertexProperty, no_property, Representation, Directed>, VertexProperty,
305 no_property, Representation, Directed>
306{
307 private:
310
311 public:
314
317
320
322 explicit graph() : base_type()
323 {
324 }
325
327 explicit graph(size_t n) : base_type(n)
328 {
329 }
330
332
335
337 auto add_vertex(const VertexProperty &p)
338 {
339 return boost::add_vertex(p, this->_graph);
340 }
341
343
346
348 const VertexProperty &operator[](vertex_descriptor v) const
349 {
350 return this->_graph[v];
351 }
352
354 VertexProperty &operator[](vertex_descriptor v)
355 {
356 return this->_graph[v];
357 }
358
360
361}; // end specialization graph<Vertex, no_property>
362
369template <class EdgeProperty, connectedness Representation, directional Directed>
370 requires(!std::is_same_v<EdgeProperty, no_property>)
372 : public detail::graph_common<graph<no_property, EdgeProperty, Representation, Directed>, no_property, EdgeProperty,
373 Representation, Directed>
374{
375 private:
378
379 public:
382
385
388
390 explicit graph() : base_type()
391 {
392 }
393
395 explicit graph(size_t n) : base_type(n)
396 {
397 }
398
400
403
408 edge_descriptor add_edge(vertex_descriptor u, vertex_descriptor v, const EdgeProperty &p)
409 {
410 return boost::add_edge(u, v, p, this->_graph).first;
411 }
412
414
417
419 const EdgeProperty &operator[](const edge_descriptor &edge) const
420 {
421 return this->_graph[edge];
422 }
423
425 EdgeProperty &operator[](const edge_descriptor &edge)
426 {
427 return this->_graph[edge];
428 }
429
431
432}; // end specialization graph<boost::no_property, Edge>
433
441template <class VertexProperty, class EdgeProperty, connectedness Representation, directional Directed>
442 requires(!std::is_same_v<VertexProperty, no_property> and !std::is_same_v<EdgeProperty, no_property>)
444 : public detail::graph_common<graph<VertexProperty, EdgeProperty, Representation, Directed>, VertexProperty,
445 EdgeProperty, Representation, Directed>
446{
447 private:
450
451 public:
454
457
460
462
463 explicit graph() : base_type()
464 {
465 }
466
468 explicit graph(size_t n) : base_type(n)
469 {
470 }
471
473
476
478 auto add_vertex(const VertexProperty &p)
479 {
480 return boost::add_vertex(p, this->_graph);
481 }
482
489 {
490 return boost::add_edge(u, v, p, this->_graph).first;
491 }
492
494
497
499 const VertexProperty &operator[](vertex_descriptor v) const
500 {
501 return this->_graph[v];
502 }
503
505 VertexProperty &operator[](vertex_descriptor v)
506 {
507 return this->_graph[v];
508 }
509
511 const EdgeProperty &operator[](const edge_descriptor &edge) const
512 {
513 return this->_graph[edge];
514 }
515
517 EdgeProperty &operator[](const edge_descriptor &edge)
518 {
519 return this->_graph[edge];
520 }
521
523};
524
525} // end namespace quetzal::geography
VertexProperty vertex_property
Vertex information.
Definition graph.hpp:58
degree_size_type degree(vertex_descriptor u) const
Returns the number of in-edges plus out-edges.
Definition graph.hpp:115
Directed directed_category
Is the graph directed or not.
Definition graph.hpp:64
vertex_descriptor source(edge_descriptor e) const
Returns the source vertex of a directed edge.
Definition graph.hpp:147
typename base_type::vertex_descriptor vertex_descriptor
Vertex descriptor ("node ID" in other words).
Definition graph.hpp:67
degree_size_type in_degree(vertex_descriptor u) const
Returns the number of in-edges of vertex .
Definition graph.hpp:123
static constexpr vertex_descriptor null_vertex()
Null vertex identifier.
Definition graph.hpp:250
typename base_type::out_edge_iterator out_edge_iterator
Iterate through the out-edges.
Definition graph.hpp:82
typename base_type::traversal_category traversal_category
The ways in which the vertices in the graph can be traversed.
Definition graph.hpp:76
auto vertices() const
Provides a range to iterate over the vertices of the graph.
Definition graph.hpp:233
degree_size_type out_degree(vertex_descriptor v) const
Returns the number of out-edges of vertex .
Definition graph.hpp:129
int num_vertices() const
Number of vertices in the graph.
Definition graph.hpp:91
bool is_isomorphic(graph_common const &other) const
Detects if there is a 1-to-1 mapping of the vertices in one graph to the vertices of another graph su...
Definition graph.hpp:107
typename base_type::degree_size_type degree_size_type
Degree size type.
Definition graph.hpp:73
typename base_type::in_edge_iterator in_edge_iterator
Iterate through the in-edges.
Definition graph.hpp:79
auto out_edges(vertex_descriptor u) const
Provides a range to iterate over the out-going edges of vertex .
Definition graph.hpp:226
typename Representation::rebind< Directed, VertexProperty, EdgeProperty > base_type
The type of graph hold by the graph class - disallow parallel edges.
Definition graph.hpp:43
auto in_edges(vertex_descriptor u) const
Provides a range to iterate over the in-going edges of vertex .
Definition graph.hpp:218
graph_common(size_t n)
Constructs a graph with vertices.
Definition graph.hpp:53
void clear_vertex(vertex_descriptor u)
Remove all edges to and from vertex from the graph.
Definition graph.hpp:173
std::optional< edge_descriptor > edge(vertex_descriptor u, vertex_descriptor v) const
Returns the edge between two vertices of the graph if the edge exists.
Definition graph.hpp:138
int num_edges() const
Number of edges in the graph.
Definition graph.hpp:98
typename base_type::edge_descriptor edge_descriptor
Edge descriptor.
Definition graph.hpp:70
vertex_descriptor target(edge_descriptor e) const
Returns the target vertex of a directed edge.
Definition graph.hpp:155
graph_common()
Default constructor.
Definition graph.hpp:48
EdgeProperty edge_property
Edge information.
Definition graph.hpp:61
auto edges() const
Provides a range to iterate over the edges of the graph.
Definition graph.hpp:240
void remove_edge(vertex_descriptor u, vertex_descriptor v)
Remove the edge from the graph.
Definition graph.hpp:198
edge_descriptor add_edge(vertex_descriptor u, vertex_descriptor v)
Inserts the edge into the graph if it does not exist, and returns an edge descriptor pointing to the...
Definition graph.hpp:190
void remove_vertex(vertex_descriptor u)
Remove vertex u from the graph, also removing all edges to and from vertex .
Definition graph.hpp:180
void remove_edge(edge_descriptor e)
Remove the edge from the graph.
Definition graph.hpp:205
A graph class with information attached to vertices.
Definition graph.hpp:446
typename base_type::edge_descriptor edge_descriptor
Edge descriptor.
Definition graph.hpp:453
typename base_type::vertex_descriptor vertex_descriptor
Vertex descriptor.
Definition graph.hpp:456
graph(size_t n)
Construct graph with vertices.
Definition graph.hpp:468
graph()
Default constructor. Initializes a graph with 0 vertices.
Definition graph.hpp:463
EdgeProperty & operator[](const edge_descriptor &edge)
Read and write access to the edge property.
Definition graph.hpp:517
const VertexProperty & operator[](vertex_descriptor v) const
Read only access to the vertex property.
Definition graph.hpp:499
auto add_vertex(const VertexProperty &p)
Add a vertex and its properties to the graph.
Definition graph.hpp:478
const EdgeProperty & operator[](const edge_descriptor &edge) const
Read only access to the edge property.
Definition graph.hpp:511
edge_descriptor add_edge(vertex_descriptor u, vertex_descriptor v, const EdgeProperty &p)
Inserts the edge into the graph if it does not exist, and returns an edge descriptor pointing to the...
Definition graph.hpp:488
VertexProperty & operator[](vertex_descriptor v)
Read and write access to the vertex property.
Definition graph.hpp:505
A graph class with information attached to vertices.
Definition graph.hpp:306
auto add_vertex(const VertexProperty &p)
Add a vertex and its properties to the graph.
Definition graph.hpp:337
typename base_type::edge_descriptor edge_descriptor
Edge descriptor.
Definition graph.hpp:313
VertexProperty & operator[](vertex_descriptor v)
Read and write access to the vertex property.
Definition graph.hpp:354
graph(size_t n)
Construct graph with vertices.
Definition graph.hpp:327
const VertexProperty & operator[](vertex_descriptor v) const
Read only access to the vertex property.
Definition graph.hpp:348
graph()
Default constructor. Initializes a graph with 0 vertices.
Definition graph.hpp:322
typename base_type::vertex_descriptor vertex_descriptor
Vertex descriptor.
Definition graph.hpp:316
A graph class with information attached to edges.
Definition graph.hpp:374
typename base_type::edge_descriptor edge_descriptor
Edge descriptor.
Definition graph.hpp:381
graph()
Default constructor. Initializses a graph with 0 vertices.
Definition graph.hpp:390
const EdgeProperty & operator[](const edge_descriptor &edge) const
Read only access to the edge property.
Definition graph.hpp:419
typename base_type::vertex_descriptor vertex_descriptor
Vertex descriptor.
Definition graph.hpp:384
EdgeProperty & operator[](const edge_descriptor &edge)
Read and write access to the edge property.
Definition graph.hpp:425
graph(size_t n)
Construct graph with vertices.
Definition graph.hpp:395
A graph class with no information attached to either vertices nor edges.
Definition graph.hpp:273
graph()
Default constructor. Initializes a graph with 0 vertices.
Definition graph.hpp:283
graph(size_t n)
Construct graph with vertices.
Definition graph.hpp:288
Definition graph.hpp:262
bool isomorphism(binary_tree< false, Vertex0 > const &g, binary_tree< false, Vertex1 > const &h)
Detects if there is a 1-to-1 mapping of the vertices in one graph to the vertices of another graph su...
Definition cardinal_k_ary_tree.hpp:616
Geospatial data formatting and processing.
Definition geography.hpp:17
boost::no_property no_property
Represents no information carried by vertices or edges of a graph.
Definition concepts.hpp:71