Sequoia
Loading...
Searching...
No Matches
DynamicGraph.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2018. //
3// Distributed under the GNU GENERAL PUBLIC LICENSE, Version 3.0. //
4// (See accompanying file LICENSE.md or copy at //
5// https://www.gnu.org/licenses/gpl-3.0.en.html) //
7
8#pragma once
9
18
19namespace sequoia::maths
20{
22 {
24
25 constexpr static edge_sharing_preference edge_sharing{edge_sharing_preference::agnostic};
26 };
27
29 {
30 template <class T> using storage_type = data_structures::bucketed_sequence<T>;
31
32 constexpr static edge_sharing_preference edge_sharing{edge_sharing_preference::agnostic};
33 };
34
35
36 template<class Storage>
37 concept allocatable_partitions = requires{
38 typename Storage::partitions_allocator_type;
39 };
40
41 template
42 <
43 graph_flavour GraphFlavour,
44 class EdgeWeight,
45 class NodeWeight,
46 class EdgeMetaData,
47 class EdgeStorageConfig,
48 class NodeWeightStorage
49 >
50 class graph_base : public
52 <
53 connectivity<GraphFlavour, graph_impl::edge_storage_generator_t<GraphFlavour, EdgeWeight, EdgeMetaData, std::size_t, EdgeStorageConfig>>,
54 NodeWeightStorage
55 >
56 {
57 public:
59 using node_storage_type = NodeWeightStorage;
61
62 using node_weight_type = NodeWeight;
63 using size_type = typename primitive_type::size_type;
64 using edges_initializer = typename primitive_type::edges_initializer;
65 using edge_storage_type = typename connectivity_type::edge_storage_type;
66 using edge_allocator_type = typename edge_storage_type::allocator_type;
67
68 graph_base() = default;
69
70 explicit graph_base(const edge_allocator_type& edgeAllocator)
71 : primitive_type(edgeAllocator)
72 {}
73
74 template<alloc EdgePartitionsAllocator>
76 graph_base(const edge_allocator_type& edgeAllocator, const EdgePartitionsAllocator& edgePartitionsAllocator)
77 : primitive_type(edgeAllocator, edgePartitionsAllocator)
78 {}
79
80 graph_base(edges_initializer edges) : primitive_type{edges} {}
81
82 graph_base(edges_initializer edges, const edge_allocator_type& edgeAllocator)
83 : primitive_type{edges, edgeAllocator}
84 {}
85
86 template<alloc EdgePartitionsAllocator>
88 graph_base(edges_initializer edges, const edge_allocator_type& edgeAllocator, const EdgePartitionsAllocator& edgePartitionsAllocator)
89 : primitive_type{edges, edgeAllocator, edgePartitionsAllocator}
90 {}
91
92 template<tree_link_direction dir>
93 requires ( !heterogeneous_nodes<graph_base>
94 && ((dir == tree_link_direction::symmetric) || is_directed(primitive_type::connectivity::flavour)))
96 : primitive_type{forest, tdc}
97 {}
98
99 template<tree_link_direction dir>
100 requires ( !heterogeneous_nodes<graph_base>
101 && ((dir == tree_link_direction::symmetric) || is_directed(primitive_type::connectivity::flavour)))
103 : primitive_type{tree, tdc}
104 {}
105
106 graph_base(const graph_base&) = default;
107
108 graph_base(const graph_base& in, const edge_allocator_type& edgeAllocator)
109 : primitive_type{in, edgeAllocator}
110 {}
111
112 template<alloc EdgePartitionsAllocator>
114 graph_base(const graph_base& in, const edge_allocator_type& edgeAllocator, const EdgePartitionsAllocator& edgePartitionsAllocator)
115 : primitive_type{in, edgeAllocator, edgePartitionsAllocator}
116 {}
117
118 graph_base(graph_base&&) noexcept = default;
119
120 graph_base(graph_base&& in, const edge_allocator_type& edgeAllocator)
121 : primitive_type{std::move(in), edgeAllocator}
122 {}
123
124 template<alloc EdgePartitionsAllocator>
126 graph_base(graph_base&& in, const edge_allocator_type& edgeAllocator, const EdgePartitionsAllocator& edgePartitionsAllocator)
127 : primitive_type{std::move(in), edgeAllocator, edgePartitionsAllocator}
128 {}
129
130 graph_base& operator=(const graph_base&) = default;
131
132 graph_base& operator=(graph_base&&) noexcept = default;
133
134 using primitive_type::swap;
135 using primitive_type::clear;
136
137 using primitive_type::get_edge_allocator;
138 using primitive_type::reserve_edges;
139 using primitive_type::edges_capacity;
140 using primitive_type::reserve_nodes;
141 using primitive_type::node_capacity;
142 using primitive_type::shrink_to_fit;
143
144 constexpr static graph_flavour flavour{GraphFlavour};
145 protected:
146 ~graph_base() = default;
147 };
148
149 template
150 <
151 graph_flavour GraphFlavour,
152 class EdgeWeight,
153 class NodeWeight,
154 class EdgeMetaData,
155 class EdgeStorageConfig,
156 class NodeWeightStorage
157 >
158 requires (!std::is_empty_v<NodeWeight>)
160 GraphFlavour,
161 EdgeWeight,
162 NodeWeight,
163 EdgeMetaData,
164 EdgeStorageConfig,
165 NodeWeightStorage
166 > : public
168 <
169 connectivity<GraphFlavour, graph_impl::edge_storage_generator_t<GraphFlavour, EdgeWeight, EdgeMetaData, std::size_t, EdgeStorageConfig>>,
170 NodeWeightStorage
171 >
172 {
173 public:
175 using node_storage_type = NodeWeightStorage;
177
178 using node_weight_type = NodeWeight;
179 using size_type = typename primitive_type::size_type;
180 using edges_initializer = typename primitive_type::edges_initializer;
181 using edge_storage_type = typename connectivity_type::edge_storage_type;
182 using edge_allocator_type = typename edge_storage_type::allocator_type;
183 using node_weight_allocator_type = typename node_storage_type::node_weight_container_type::allocator_type;
184
185 graph_base() = default;
186
187 graph_base(edges_initializer edges) : primitive_type{edges} {}
188
189 graph_base(const edge_allocator_type& edgeAllocator, const node_weight_allocator_type& nodeWeightAllocator)
190 : primitive_type(edgeAllocator, nodeWeightAllocator)
191 {}
192
193 template<alloc EdgePartitionsAllocator>
195 graph_base(const edge_allocator_type& edgeAllocator, const EdgePartitionsAllocator& edgePartitionsAllocator, const node_weight_allocator_type& nodeWeightAllocator)
196 : primitive_type(edgeAllocator, edgePartitionsAllocator, nodeWeightAllocator)
197 {}
198
199 graph_base(edges_initializer edges, const edge_allocator_type& edgeAllocator, const node_weight_allocator_type& nodeWeightAllocator)
200 : primitive_type{edges, edgeAllocator, nodeWeightAllocator}
201 {}
202
203 template<alloc EdgePartitionsAllocator>
205 graph_base(edges_initializer edges, const edge_allocator_type& edgeAllocator, const EdgePartitionsAllocator& edgePartitionsAllocator, const node_weight_allocator_type& nodeWeightAllocator)
206 : primitive_type{edges, edgeAllocator, edgePartitionsAllocator, nodeWeightAllocator}
207 {}
208
209 graph_base(edges_initializer edges, std::initializer_list<node_weight_type> nodeWeights)
210 : primitive_type{edges, nodeWeights}
211 {}
212
213 graph_base(edges_initializer edges, const edge_allocator_type& edgeAllocator, std::initializer_list<node_weight_type> nodeWeights, const node_weight_allocator_type& nodeWeightAllocator)
214 : primitive_type{edges, edgeAllocator, nodeWeights, nodeWeightAllocator}
215 {}
216
217 template<alloc EdgePartitionsAllocator>
219 graph_base(edges_initializer edges, const edge_allocator_type& edgeAllocator, const EdgePartitionsAllocator& edgePartitionsAllocator, std::initializer_list<node_weight_type> nodeWeights, const node_weight_allocator_type& nodeWeightAllocator)
220 : primitive_type{edges, edgeAllocator, edgePartitionsAllocator, nodeWeights, nodeWeightAllocator}
221 {}
222
223 template<tree_link_direction dir>
224 requires ((dir == tree_link_direction::symmetric) || is_directed(primitive_type::connectivity::flavour))
226 : primitive_type{forest, tdc}
227 {}
228
229 template<tree_link_direction dir>
230 requires ( !std::is_empty_v<node_weight_type> && !heterogeneous_nodes<graph_base>
231 && ((dir == tree_link_direction::symmetric) || is_directed(primitive_type::connectivity::flavour)))
233 : primitive_type{tree, tdc}
234 {}
235
236 graph_base(const graph_base& in, const edge_allocator_type& edgeAllocator, const node_weight_allocator_type& nodeWeightAllocator)
237 : primitive_type{in, edgeAllocator, nodeWeightAllocator}
238 {}
239
240 template<alloc EdgePartitionsAllocator>
242 graph_base(const graph_base& in, const edge_allocator_type& edgeAllocator, const EdgePartitionsAllocator& edgePartitionsAllocator, const node_weight_allocator_type& nodeWeightAllocator)
243 : primitive_type{in, edgeAllocator, edgePartitionsAllocator, nodeWeightAllocator}
244 {}
245
246
247 graph_base(graph_base&& in, const edge_allocator_type& edgeAllocator, const node_weight_allocator_type& nodeWeightAllocator)
248 : primitive_type{std::move(in), edgeAllocator, nodeWeightAllocator}
249 {}
250
251 template<alloc EdgePartitionsAllocator>
253 graph_base(graph_base&& in, const edge_allocator_type& edgeAllocator, const EdgePartitionsAllocator& edgePartitionsAllocator, const node_weight_allocator_type& nodeWeightAllocator)
254 : primitive_type{std::move(in), edgeAllocator, edgePartitionsAllocator, nodeWeightAllocator}
255 {}
256
257 graph_base(const graph_base&) = default;
258 graph_base(graph_base&&) noexcept = default;
259
260 graph_base& operator=(const graph_base&) = default;
261 graph_base& operator=(graph_base&&) noexcept = default;
262
263 constexpr static graph_flavour flavour{GraphFlavour};
264
265 using primitive_type::clear;
266
267 using primitive_type::get_edge_allocator;
268 using primitive_type::reserve_edges;
269 using primitive_type::edges_capacity;
270 using primitive_type::reserve_nodes;
271 using primitive_type::node_capacity;
272 using primitive_type::shrink_to_fit;
273
274 using primitive_type::get_node_allocator;
275
276 using primitive_type::swap;
277
278 friend void swap(graph_base& lhs, graph_base& rhs) noexcept(noexcept(lhs.swap(rhs)))
279 {
280 lhs.swap(rhs);
281 }
282 protected:
283 ~graph_base() = default;
284 };
285
286 template
287 <
288 class EdgeWeight,
289 class NodeWeight,
290 class EdgeStorageConfig = bucketed_edge_storage_config,
291 class NodeWeightStorage = node_storage<NodeWeight>
292 >
293 class directed_graph final : public
295 <
296 graph_flavour::directed,
297 EdgeWeight,
298 NodeWeight,
299 null_meta_data,
300 EdgeStorageConfig,
301 NodeWeightStorage
302 >
303 {
304 public:
305 using node_weight_type = NodeWeight;
306
307 using
309 <
310 graph_flavour::directed,
311 EdgeWeight,
312 NodeWeight,
314 EdgeStorageConfig,
315 NodeWeightStorage
316 >::graph_base;
317
318 using base_type =
320 <
321 graph_flavour::directed,
322 EdgeWeight,
323 NodeWeight,
325 EdgeStorageConfig,
326 NodeWeightStorage
327 >;
328
329 using base_type::swap_nodes;
330 using base_type::add_node;
331 using base_type::insert_node;
332 using base_type::erase_node;
333
334 using base_type::join;
335 using base_type::erase_edge;
336
337 using base_type::sort_edges;
338 using base_type::stable_sort_edges;
339 using base_type::swap_edges;
340 };
341
342 template
343 <
344 class EdgeWeight,
345 class NodeWeight,
346 class EdgeMetaData = null_meta_data,
347 class EdgeStorageConfig = bucketed_edge_storage_config,
348 class NodeWeightStorage = node_storage<NodeWeight>
349 >
350 class undirected_graph final : public
352 <
353 graph_flavour::undirected,
354 EdgeWeight,
355 NodeWeight,
356 EdgeMetaData,
357 EdgeStorageConfig,
358 NodeWeightStorage
359 >
360 {
361 public:
362 using node_weight_type = NodeWeight;
363
364 using
366 <
367 graph_flavour::undirected,
368 EdgeWeight,
369 NodeWeight,
370 EdgeMetaData,
371 EdgeStorageConfig,
372 NodeWeightStorage
373 >::graph_base;
374
375 using base_type =
377 <
378 graph_flavour::undirected,
379 EdgeWeight,
380 NodeWeight,
381 EdgeMetaData,
382 EdgeStorageConfig,
383 NodeWeightStorage
384 >;
385
386 using base_type::swap_nodes;
387 using base_type::add_node;
388 using base_type::insert_node;
389 using base_type::erase_node;
390
391 using base_type::join;
392 using base_type::erase_edge;
393
394 using base_type::sort_edges;
395 using base_type::stable_sort_edges;
396 using base_type::swap_edges;
397 };
398
399 template
400 <
401 class EdgeWeight,
402 class NodeWeight,
403 class EdgeMetaData,
404 class EdgeStorageConfig,
405 class NodeWeightStorage
406 >
407 requires (!std::is_empty_v<EdgeMetaData>)
410 <
411 graph_flavour::undirected,
412 EdgeWeight,
413 NodeWeight,
414 EdgeMetaData,
415 EdgeStorageConfig,
416 NodeWeightStorage
417 >
418 {
419 public:
420 using node_weight_type = NodeWeight;
421
422 using
424 <
425 graph_flavour::undirected,
426 EdgeWeight,
427 NodeWeight,
428 EdgeMetaData,
429 EdgeStorageConfig,
430 NodeWeightStorage
431 >::graph_base;
432
433 using base_type =
435 <
436 graph_flavour::undirected,
437 EdgeWeight,
438 NodeWeight,
439 EdgeMetaData,
440 EdgeStorageConfig,
441 NodeWeightStorage
442 >;
443
444 using base_type::swap_nodes;
445 using base_type::add_node;
446 using base_type::insert_node;
447 using base_type::erase_node;
448
449 using base_type::join;
450
451 // TO DO: reinstate this, but implementation needs to be changed
452 // using base_type::erase_edge;
453 };
454
455 template
456 <
457 class EdgeWeight,
458 class NodeWeight,
459 class EdgeMetaData = null_meta_data,
460 class EdgeStorageConfig = bucketed_edge_storage_config,
461 class NodeWeightStorage = node_storage<NodeWeight>
462 >
463 class embedded_graph final : public
465 <
466 graph_flavour::undirected_embedded,
467 EdgeWeight,
468 NodeWeight,
469 EdgeMetaData,
470 EdgeStorageConfig,
471 NodeWeightStorage
472 >
473 {
474 public:
475 using node_weight_type = NodeWeight;
476
477 using
479 <
480 graph_flavour::undirected_embedded,
481 EdgeWeight,
482 NodeWeight,
483 EdgeMetaData,
484 EdgeStorageConfig,
485 NodeWeightStorage
486 >::graph_base;
487
488 using base_type =
490 <
491 graph_flavour::undirected_embedded,
492 EdgeWeight,
493 NodeWeight,
494 EdgeMetaData,
495 EdgeStorageConfig,
496 NodeWeightStorage
497 >;
498
499 using base_type::swap_nodes;
500 using base_type::add_node;
501 using base_type::insert_node;
502 using base_type::erase_node;
503
504 using base_type::join;
505 using base_type::erase_edge;
506
507 using base_type::primitive_type::insert_join;
508 };
509}
Underlying class for the various different graph flavour.
Classes to allow homogeneous treatment of graphs with empty/non-empty node weights.
Classes implementing the concept of a sequence of data which is divided into partitions.
Storage for partitioned data such that data within each partition is contiguous.
Definition: PartitionedData.hpp:63
Definition: PartitionedData.hpp:991
Definition: Connectivity.hpp:1641
Definition: DynamicGraph.hpp:303
Definition: DynamicGraph.hpp:473
Definition: DynamicGraph.hpp:56
Definition: GraphPrimitive.hpp:107
Definition: NodeStorage.hpp:272
Definition: DynamicGraph.hpp:360
Definition: DynamicGraph.hpp:37
Definition: DynamicGraph.hpp:29
Definition: DynamicGraph.hpp:22
Definition: Edge.hpp:287
Definition: GraphPrimitive.hpp:84