Sequoia
Loading...
Searching...
No Matches
DynamicUndirectedGraphWeightedTestingUtilities.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2023. //
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
13
14namespace sequoia::testing
15{
16 namespace undirected_graph{
18 enum weighted_graph_description : std::size_t {
19 // x
20 nodew = graph_description::end,
21
22 // /\
23 // \/
24 // x
25 nodew_0,
26
27 // /\
28 // \/
29 // x
30 node_0w,
31
32 // /\ /\
33 // \/ \/
34 // x
35 node_0w_0w,
36
37 // /\ /\
38 // \/ \/
39 // x
40 node_0_0w,
41
42 // x x
43 node_nodew,
44
45 // x x
46 nodew_node,
47
48 // x ---- x
49 node_1_nodew_0,
50
51 // x ---- x
52 nodew_1_node_0,
53
54 // /\
55 // \/
56 // x --- x
57 node_0w_1_node_0,
58
59 // /\
60 // \/
61 // x --- x
62 node_1_node_0_1w,
63
64 // x ==== x
65 node_1_1w_node_0_0w,
66
67 // x ==== x
68 node_1w_1w_node_0w_0w,
69
70 // ----
71 // x ==== x
72 node_1_1w_1x_node_0_0w_0x,
73
74 // /-\
75 // \ /
76 // x ==== x
77 // ----
78 node_0y_1_1w_1x_node_0_0w_0x,
79 };
80 }
81
82 template
83 <
84 class EdgeWeight,
85 class NodeWeight,
86 class EdgeStorageConfig,
87 class NodeWeightStorage
88 >
90 {
91 public:
93 using edge_t = typename graph_t::edge_init_type;
94 using node_weight_type = typename graph_t::node_weight_type;
95 using edges_equivalent_t = std::initializer_list<std::initializer_list<edge_t>>;
96 using transition_graph = typename transition_checker<graph_t>::transition_graph;
97
98 constexpr static bool has_shared_weight{EdgeStorageConfig::edge_sharing == maths::edge_sharing_preference::shared_weight};
99
100 static void execute_operations(regular_test& t)
101 {
102 auto trg{make_weighted_transition_graph(t)};
103
104 auto checker{
105 [&t](std::string_view description, const graph_t& obtained, const graph_t& prediction, const graph_t& parent, std::size_t host, std::size_t target) {
106 t.check(equality, {description, no_source_location}, obtained, prediction);
107 if(host != target) t.check_semantics({description, no_source_location}, prediction, parent);
108 }
109 };
110
112 }
113
114 [[nodiscard]]
115 static graph_t make_and_check(regular_test& t, std::string_view description, edges_equivalent_t edgeInit, std::initializer_list<node_weight_type> nodeInit)
116 {
117 return graph_initialization_checker<graph_t>::make_and_check(t, description, edgeInit, nodeInit);
118 }
119
120 static void check_initialization_exceptions(regular_test& t)
121 {
122 using nodes = std::initializer_list<node_weight_type>;
123
124 // One node
125 t.check_exception_thrown<std::logic_error>("Mismatched loop weights", [](){ return graph_t{{edge_t{0, 1.0}, edge_t{0, 2.0}}}; });
126
127 // Two nodes
128 t.check_exception_thrown<std::logic_error>("Mismatched weights", [](){ return graph_t{{edge_t{1, 1.0}}, {edge_t{0, 2.0}}}; });
129
130 t.check_exception_thrown<std::logic_error>("Mismatched edge/node initialization", [](){ return graph_t{{}, nodes{1.0}}; });
131 t.check_exception_thrown<std::logic_error>("Mismatched edge/node initialization", [](){ return graph_t{{{}}, nodes{1.0, 2.0}}; });
132 t.check_exception_thrown<std::logic_error>("Mismatched edge/node initialization", [](){ return graph_t{{{edge_t{0, 1.0}, edge_t{0, 1.0}}}, nodes{1.0, 2.0}}; });
133 t.check_exception_thrown<std::logic_error>("Mismatched edge/node initialization", [](){ return graph_t{{{}, {}}, nodes{1.0}}; });
134 t.check_exception_thrown<std::logic_error>("Mismatched edge/node initialization", [](){ return graph_t{{{edge_t{1}}, {edge_t{0}}}, nodes{1.0}}; });
135 }
136
137 [[nodiscard]]
138 static transition_graph make_weighted_transition_graph(regular_test& t)
139 {
141 using namespace undirected_graph;
142
143 auto trg{base_ops::make_transition_graph(t)};
144
145 check_initialization_exceptions(t);
146
147 // 'weighted_graph_description::nodew'
148 trg.add_node(make_and_check(t, t.report(""), {{}}, {1.0}));
149
150 // 'weighted_graph_description::nodew_0'
151 trg.add_node(make_and_check(t, t.report(""), {{{0, 0.0}, {0, 0.0}}}, {1.0}));
152
153 // 'weighted_graph_description::node_0w'
154 trg.add_node(make_and_check(t, t.report(""), {{{0, 1.0}, {0, 1.0}}}, {0.0}));
155
156 // 'weighted_graph_description::node_0w_0w'
157 trg.add_node(make_and_check(t, t.report(""), {{{0, 1.0}, {0, 1.0}, {0, 1.0}, {0, 1.0}}}, {0.0}));
158
159 // 'weighted_graph_description::node_0_0w'
160 trg.add_node(
161 [&t](){
162 auto g{make_and_check(t, t.report(""), {{{0, 0.0}, {0, 0.0}, {0, 1.0}, {0, 1.0}}}, {0.0})};
163 t.check(equality, "Canonical ordering of weighted edges", graph_t{{{{0, 1.0}, {0, 0.0}, {0, 1.0}, {0, 0.0}}}, {0.0}}, g);
164 return g;
165 }());
166
167 // 'weighted_graph_description::node_nodew'
168 trg.add_node(make_and_check(t, t.report(""), {{}, {}}, {0.0, 1.0}));
169
170 // 'weighted_graph_description::nodew_node'
171 trg.add_node(make_and_check(t, t.report(""), {{}, {}}, {1.0, 0.0}));
172
173 // 'weighted_graph_description::node_1_nodew_0'
174 trg.add_node(make_and_check(t, t.report(""), {{{1, 0.0}}, {{0, 0.0}}}, {0.0, 1.0}));
175
176 // 'weighted_graph_description::nodew_1_node_0'
177 trg.add_node(make_and_check(t, t.report(""), {{{1, 0.0}}, {{0, 0.0}}}, {1.0, 0.0}));
178
179 // 'weighted_graph_description::node_0w_1_node_0'
180 trg.add_node(make_and_check(t, t.report(""), {{{0, 1.0}, {0, 1.0}, {1, 0.0}}, {{0, 0.0}}}, {0.0, 0.0})),
181
182 // 'weighted_graph_description::node_1_node_0_1w'
183 trg.add_node(make_and_check(t, t.report(""), {{{1, 0.0}}, {{0, 0.0}, {1, 1.0}, {1, 1.0}}}, {0.0, 0.0})),
184
185 // 'weighted_graph_description::node_1_1w_node_0_0w'
186 trg.add_node(
187 [&t]() {
188 auto g{make_and_check(t, t.report(""), {{{1, 0.0}, {1, 1.0}}, {{0, 0.0}, {0, 1.0}}}, {0.0, 0.0})};
189 t.check(equality, "Canonical ordering of weighted edges", graph_t{{{{1, 1.0}, {1, 0.0}}, {{0, 0.0}, {0, 1.0}}}, {0.0, 0.0}}, g);
190 t.check(equality, "Canonical ordering of weighted edges", graph_t{{{{1, 1.0}, {1, 0.0}}, {{0, 1.0}, {0, 0.0}}}, {0.0, 0.0}}, g);
191 return g;
192 }
193 );
194
195 // 'weighted_graph_description::node_1w_1w_node_0w_0w'
196 trg.add_node(make_and_check(t, t.report(""), {{{1, 1.0}, {1, 1.0}}, {{0, 1.0}, {0, 1.0}}}, {0.0, 0.0}));
197
198 // 'weighted_graph_description::node_1_1w_1x_node_0_0w_0x'
199 trg.add_node(
200 [&t]() {
201 auto g{make_and_check(t, t.report(""), {{{1, 0.0}, {1, 1.0}, {1, 2.0}}, {{0, 0.0}, {0, 1.0}, {0, 2.0}}}, {0.0, 0.0})};
202 t.check(equality, "Canonical ordering of weighted edges", graph_t{{{{1, 2.0}, {1, 0.0}, {1, 1.0}}, {{0, 1.0}, {0, 2.0}, {0, 0.0}}}, {0.0, 0.0}}, g);
203 return g;
204 }
205 );
206
207 // 'weighted_graph_description::node_0y_1_1w_1x_node_0_0w_0x'
208 trg.add_node(make_and_check(t, t.report(""), {{{0, 3.0}, {0, 3.0}, {1, 0.0}, {1, 1.0}, {1, 2.0}}, {{0, 0.0}, {0, 1.0}, {0, 2.0}}}, {0.0, 0.0}));
209
210 // begin 'graph_description::empty'
211
212 trg.join(
213 graph_description::empty,
214 graph_description::empty,
215 t.report(""),
216 [&t](graph_t g) -> graph_t {
217 t.check_exception_thrown<std::out_of_range>("Attempt to set a node weight which does not exist", [&g](){ g.set_node_weight(g.cbegin_node_weights(), 1.0); });
218 return g;
219 }
220 );
221
222 trg.join(
223 graph_description::empty,
224 graph_description::empty,
225 t.report("Attempt to mutate a node weight which does not exist"),
226 [&t](graph_t g) -> graph_t {
227 t.check_exception_thrown<std::out_of_range>("Attempt to mutate a node weight which does not exist", [&g](){ g.mutate_node_weight(g.cbegin_node_weights(), [](double&){}); });
228 return g;
229 }
230 );
231
232 trg.join(
233 graph_description::empty,
234 weighted_graph_description::nodew,
235 t.report("Add weighted node"),
236 [](graph_t g) -> graph_t {
237 g.add_node(1.0);
238 return g;
239 }
240 );
241
242 trg.join(
243 graph_description::empty,
244 weighted_graph_description::nodew,
245 t.report("Insert weighted node"),
246 [](graph_t g) -> graph_t {
247 g.insert_node(0, 1.0);
248 return g;
249 }
250 );
251
252 // end 'graph_description::empty'
253
254 // begin 'graph_description::node'
255
256 trg.join(
257 graph_description::node,
258 graph_description::node,
259 t.report(""),
260 [&t](graph_t g) -> graph_t {
261 t.check_exception_thrown<std::out_of_range>("Attempt to set a node weight which does not exist", [&g](){ g.set_node_weight(g.cend_node_weights(), 1.0); });
262 return g;
263 }
264 );
265
266 trg.join(
267 graph_description::node,
268 graph_description::node,
269 t.report("Attempt to mutate a node weight which does not exist"),
270 [&t](graph_t g) -> graph_t {
271 t.check_exception_thrown<std::out_of_range>("Attempt to mutate a node weight which does not exist", [&g](){ g.mutate_node_weight(g.cend_node_weights(), [](double&){}); });
272 return g;
273 }
274 );
275
276 trg.join(
277 graph_description::node,
278 weighted_graph_description::nodew,
279 t.report("Change node weight"),
280 [](graph_t g) -> graph_t {
281 g.set_node_weight(g.cbegin_node_weights(), 1.0);
282 return g;
283 }
284 );
285
286 trg.join(
287 graph_description::node,
288 weighted_graph_description::nodew,
289 t.report("Mutate node weight"),
290 [](graph_t g) -> graph_t {
291 g.mutate_node_weight(g.cbegin_node_weights(), [](double& x) { x += 1.0; });
292 return g;
293 }
294 );
295
296 trg.join(
297 graph_description::node,
298 weighted_graph_description::nodew_node,
299 t.report("Insert weighted node"),
300 [](graph_t g) -> graph_t {
301 g.insert_node(0, 1.0);
302 return g;
303 }
304 );
305
306 // end 'graph_description::node'
307
308 // begin 'graph_description::node_0'
309
310 trg.join(
311 graph_description::node_0,
312 weighted_graph_description::node_0w,
313 t.report("Set edge weight"),
314 [](graph_t g) -> graph_t {
315 g.set_edge_weight(g.cbegin_edges(0), 1.0);
316 return g;
317 }
318 );
319
320 trg.join(
321 graph_description::node_0,
322 weighted_graph_description::node_0w,
323 t.report("Set edge weight via second insertion"),
324 [](graph_t g) -> graph_t {
325 g.set_edge_weight(++g.cbegin_edges(0), 1.0);
326 return g;
327 }
328 );
329
330 trg.join(
331 graph_description::node_0,
332 weighted_graph_description::node_0w,
333 t.report("Mutate edge weight"),
334 [](graph_t g) -> graph_t {
335 g.mutate_edge_weight(g.cbegin_edges(0), [](double& x){ x += 1.0; });
336 return g;
337 }
338 );
339
340 trg.join(
341 graph_description::node_0,
342 weighted_graph_description::node_0w,
343 t.report("Mutate edge weight via second insertion"),
344 [](graph_t g) -> graph_t {
345 g.mutate_edge_weight(++g.cbegin_edges(0), [](double& x){ x += 1.0; });
346 return g;
347 }
348 );
349
350 trg.join(
351 graph_description::node_0,
352 weighted_graph_description::node_0_0w,
353 t.report("Join {0,0}"),
354 [](graph_t g) -> graph_t {
355 g.join(0, 0, 1.0);
356 return g;
357 }
358 );
359
360 // end 'graph_description::node_0'
361
362 // begin 'graph_description::node_0_0'
363
364 trg.join(
365 graph_description::node_0_0,
366 weighted_graph_description::node_0_0w,
367 t.report("Set edge weight via zeroth partial weight"),
368 [](graph_t g) -> graph_t {
369 g.set_edge_weight(g.cbegin_edges(0), 1.0);
370 g.swap_edges(0, 0, 2);
371 g.swap_edges(0, 1, 3);
372 return g;
373 }
374 );
375
376 trg.join(
377 graph_description::node_0_0,
378 weighted_graph_description::node_0_0w,
379 t.report("Set edge weight via first partial weight"),
380 [](graph_t g) -> graph_t {
381 g.set_edge_weight(g.cbegin_edges(0) + 1, 1.0);
382 g.swap_edges(0, 0, 2);
383 g.swap_edges(0, 1, 3);
384 return g;
385 }
386 );
387
388 trg.join(
389 graph_description::node_0_0,
390 weighted_graph_description::node_0_0w,
391 t.report("Set edge weight via second partial weight"),
392 [](graph_t g) -> graph_t {
393 g.set_edge_weight(g.cbegin_edges(0) + 2, 1.0);
394 if constexpr(!has_shared_weight)
395 g.swap_edges(0, 0, 3);
396
397 return g;
398 }
399 );
400
401 trg.join(
402 graph_description::node_0_0,
403 weighted_graph_description::node_0_0w,
404 t.report("Set edge weight via third partial weight"),
405 [](graph_t g) -> graph_t {
406 g.set_edge_weight(g.cbegin_edges(0) + 3, 1.0);
407 if constexpr(!has_shared_weight)
408 g.swap_edges(0, 0, 2);
409
410 return g;
411 }
412 );
413
414 trg.join(
415 graph_description::node_0_0,
416 weighted_graph_description::node_0_0w,
417 t.report("Mutate edge weight via zeroth partial weight"),
418 [](graph_t g) -> graph_t {
419 g.mutate_edge_weight(g.cbegin_edges(0), [](double& x) { x += 1.0; });
420 g.swap_edges(0, 0, 2);
421 g.swap_edges(0, 1, 3);
422 return g;
423 }
424 );
425
426 trg.join(
427 graph_description::node_0_0,
428 weighted_graph_description::node_0_0w,
429 t.report("Mutate edge weight via first partial weight"),
430 [](graph_t g) -> graph_t {
431 g.mutate_edge_weight(g.cbegin_edges(0)+1, [](double& x) { x += 1.0; });
432 g.swap_edges(0, 0, 2);
433 g.swap_edges(0, 1, 3);
434 return g;
435 }
436 );
437
438 trg.join(
439 graph_description::node_0_0,
440 weighted_graph_description::node_0_0w,
441 t.report("Mutate edge weight via second partial weight"),
442 [](graph_t g) -> graph_t {
443 g.mutate_edge_weight(g.cbegin_edges(0)+2, [](double& x) { x += 1.0; });
444 if constexpr(!has_shared_weight)
445 g.swap_edges(0, 0, 3);
446
447 return g;
448 }
449 );
450
451 trg.join(
452 graph_description::node_0_0,
453 weighted_graph_description::node_0_0w,
454 t.report("Mutate edge weight via third partial weight"),
455 [](graph_t g) -> graph_t {
456 g.mutate_edge_weight(g.cbegin_edges(0)+3, [](double& x) { x += 1.0; });
457 if constexpr(!has_shared_weight)
458 g.swap_edges(0, 0, 2);
459
460 return g;
461 }
462 );
463
464 // end 'graph_description::node_0_0'
465
466 // begin 'graph_description::node_0_1_node_0'
467
468 trg.join(
469 graph_description::node_0_1_node_0,
470 weighted_graph_description::node_0w_1_node_0,
471 t.report("Set loop weight via zeroth partial weight"),
472 [](graph_t g) -> graph_t {
473 g.set_edge_weight(g.cbegin_edges(0), 1.0);
474 return g;
475 }
476 );
477
478 trg.join(
479 graph_description::node_0_1_node_0,
480 weighted_graph_description::node_0w_1_node_0,
481 t.report("Set loop weight via first partial weight"),
482 [](graph_t g) -> graph_t {
483 g.set_edge_weight(++g.cbegin_edges(0), 1.0);
484 return g;
485 }
486 );
487
488 trg.join(
489 graph_description::node_0_1_node_0,
490 weighted_graph_description::node_0w_1_node_0,
491 t.report("Mutate loop weight via zeroth partial weight"),
492 [](graph_t g) -> graph_t {
493 g.mutate_edge_weight(g.cbegin_edges(0), [](double& x) { x += 1.0; });
494 return g;
495 }
496 );
497
498 trg.join(
499 graph_description::node_0_1_node_0,
500 weighted_graph_description::node_0w_1_node_0,
501 t.report("Mutate loop weight via first partial weight"),
502 [](graph_t g) -> graph_t {
503 g.mutate_edge_weight(++g.cbegin_edges(0), [](double& x) { x += 1.0; });
504 return g;
505 }
506 );
507
508 // end 'graph_description::node_0_1_node_0'
509
510 // begin 'graph_description::node_1_node_0_1'
511
512 trg.join(
513 graph_description::node_1_node_0_1,
514 weighted_graph_description::node_1_node_0_1w,
515 t.report("Set loop weight via zeroth partial weight"),
516 [](graph_t g) -> graph_t {
517 g.set_edge_weight(g.cbegin_edges(1)+1, 1.0);
518 return g;
519 }
520 );
521
522 trg.join(
523 graph_description::node_1_node_0_1,
524 weighted_graph_description::node_1_node_0_1w,
525 t.report("Set loop weight via first partial weight"),
526 [](graph_t g) -> graph_t {
527 g.set_edge_weight(g.cbegin_edges(1)+2, 1.0);
528 return g;
529 }
530 );
531
532 trg.join(
533 graph_description::node_1_node_0_1,
534 weighted_graph_description::node_1_node_0_1w,
535 t.report("Mutate loop weight via zeroth partial weight"),
536 [](graph_t g) -> graph_t {
537 g.mutate_edge_weight(g.cbegin_edges(1)+1, [](double& x) { x += 1.0; });
538 return g;
539 }
540 );
541
542 trg.join(
543 graph_description::node_1_node_0_1,
544 weighted_graph_description::node_1_node_0_1w,
545 t.report("Mutate loop weight via first partial weight"),
546 [](graph_t g) -> graph_t {
547 g.mutate_edge_weight(g.cbegin_edges(1)+2, [](double& x) { x += 1.0; });
548 return g;
549 }
550 );
551
552 // end 'graph_description::node_1_node_0_1'
553
554 // begin 'graph_description::node_1_1_node_0_0'
555
556 trg.join(
557 graph_description::node_1_1_node_0_0,
558 weighted_graph_description::node_1_1w_node_0_0w,
559 t.report("Set edge weight via node 0, zeroth partial edge"),
560 [](graph_t g) -> graph_t {
561 g.set_edge_weight(g.cbegin_edges(0), 1.0);
562 g.swap_edges(0, 0, 1);
563 g.swap_edges(1, 0, 1);
564 return g;
565 }
566 );
567
568 trg.join(
569 graph_description::node_1_1_node_0_0,
570 weighted_graph_description::node_1_1w_node_0_0w,
571 t.report("Set edge weight via node 0, first partial edge"),
572 [](graph_t g) -> graph_t {
573 g.set_edge_weight(++g.cbegin_edges(0), 1.0);
574 if constexpr(!has_shared_weight)
575 g.swap_edges(1, 0, 1);
576
577 return g;
578 }
579 );
580
581 trg.join(
582 graph_description::node_1_1_node_0_0,
583 weighted_graph_description::node_1_1w_node_0_0w,
584 t.report("Set edge weight via node 1, zeroth partial edge"),
585 [](graph_t g) -> graph_t {
586 g.set_edge_weight(g.cbegin_edges(1), 1.0);
587 g.swap_edges(0, 0, 1);
588 g.swap_edges(1, 0, 1);
589 return g;
590 }
591 );
592
593 trg.join(
594 graph_description::node_1_1_node_0_0,
595 weighted_graph_description::node_1_1w_node_0_0w,
596 t.report("Set edge weight via node 1, first partial edge"),
597 [](graph_t g) -> graph_t {
598 g.set_edge_weight(++g.cbegin_edges(1), 1.0);
599 if constexpr(!has_shared_weight)
600 g.swap_edges(0, 0, 1);
601
602 return g;
603 }
604 );
605
606 trg.join(
607 graph_description::node_1_1_node_0_0,
608 weighted_graph_description::node_1_1w_node_0_0w,
609 t.report("Mutate edge weight via node 0, zeroth partial edge"),
610 [](graph_t g) -> graph_t {
611 g.mutate_edge_weight(g.cbegin_edges(0), [](double& x) { x += 1.0; });
612 g.swap_edges(0, 0, 1);
613 g.swap_edges(1, 0, 1);
614 return g;
615 }
616 );
617
618 trg.join(
619 graph_description::node_1_1_node_0_0,
620 weighted_graph_description::node_1_1w_node_0_0w,
621 t.report("Mutate edge weight via node 0, first partial edge"),
622 [](graph_t g) -> graph_t {
623 g.mutate_edge_weight(++g.cbegin_edges(0), [](double& x) { x += 1.0; });
624 if constexpr(!has_shared_weight)
625 g.swap_edges(1, 0, 1);
626
627 return g;
628 }
629 );
630
631 trg.join(
632 graph_description::node_1_1_node_0_0,
633 weighted_graph_description::node_1_1w_node_0_0w,
634 t.report("Mutate edge weight via node 1, zeroth partial edge"),
635 [](graph_t g) -> graph_t {
636 g.mutate_edge_weight(g.cbegin_edges(1), [](double& x) { x += 1.0; });
637 g.swap_edges(0, 0, 1);
638 g.swap_edges(1, 0, 1);
639 return g;
640 }
641 );
642
643 trg.join(
644 graph_description::node_1_1_node_0_0,
645 weighted_graph_description::node_1_1w_node_0_0w,
646 t.report("Mutate edge weight via node 1, first partial edge"),
647 [](graph_t g) -> graph_t {
648 g.mutate_edge_weight(++g.cbegin_edges(1), [](double& x) { x += 1.0; });
649 if constexpr(!has_shared_weight)
650 g.swap_edges(0, 0, 1);
651
652 return g;
653 }
654 );
655
656 // end 'graph_description::node_1_1_node_0_0'
657
659
660 // begin 'weighted_graph_description::node_0_0w'
661
662 trg.join(
663 weighted_graph_description::node_0_0w,
664 weighted_graph_description::node_0w,
665 t.report("Remove zeroth partial edge"),
666 [](graph_t g) -> graph_t {
667 g.erase_edge(g.cbegin_edges(0));
668 return g;
669 }
670 );
671
672 trg.join(
673 weighted_graph_description::node_0_0w,
674 weighted_graph_description::node_0w,
675 t.report("Remove first partial edge"),
676 [](graph_t g) -> graph_t {
677 g.erase_edge(++g.cbegin_edges(0));
678 return g;
679 }
680 );
681
682 // end 'weighted_graph_description::node_0_0w'
683
684 // begin 'weighted_graph_description::node_0w_0w'
685
686 trg.join(
687 weighted_graph_description::node_0w_0w,
688 graph_description::node_0,
689 t.report("Ensure edge erasure treats shared weights properly"),
690 [](graph_t g) -> graph_t {
691 g.swap_edges(0, 1, 2);
692 g.erase_edge(g.cbegin_edges(0));
693 g.set_edge_weight(g.cbegin_edges(0), 0.0);
694 return g;
695 }
696 );
697
698 trg.join(
699 weighted_graph_description::node_0w_0w,
700 graph_description::node_0,
701 t.report("Ensure edge erasure treats shared weights properly"),
702 [](graph_t g) -> graph_t {
703 g.erase_edge(g.cbegin_edges(0)+2);
704 g.set_edge_weight(g.cbegin_edges(0), 0.0);
705 return g;
706 }
707 );
708
709 trg.join(
710 weighted_graph_description::node_0w_0w,
711 graph_description::node_0,
712 t.report("Ensure edge erasure treats shared weights properly"),
713 [](graph_t g) -> graph_t {
714 g.erase_edge(g.cbegin_edges(0) + 3);
715 g.set_edge_weight(g.cbegin_edges(0), 0.0);
716 return g;
717 }
718 );
719
720 // end 'weighted_graph_description::node_0w_0w'
721
722 // begin 'weighted_graph_description::node_nodew'
723
724 trg.join(
725 weighted_graph_description::node_nodew,
726 weighted_graph_description::nodew_node,
727 t.report("Swap nodes"),
728 [](graph_t g) -> graph_t {
729 g.swap_nodes(0, 1);
730 return g;
731 }
732 );
733
734 // end 'weighted_graph_description::node_nodew'
735
736 // begin 'weighted_graph_description::nodew_node'
737
738 trg.join(
739 weighted_graph_description::nodew_node,
740 weighted_graph_description::node_nodew,
741 t.report("Swap nodes"),
742 [](graph_t g) -> graph_t {
743 g.swap_nodes(1, 0);
744 return g;
745 }
746 );
747
748 // end 'weighted_graph_description::nodew_node'
749
750 // begin 'weighted_graph_description::node_1_nodew_0'
751
752 trg.join(
753 weighted_graph_description::node_1_nodew_0,
754 weighted_graph_description::nodew_1_node_0,
755 t.report("Swap nodes"),
756 [](graph_t g) -> graph_t {
757 g.swap_nodes(0, 1);
758 return g;
759 }
760 );
761
762 // end 'weighted_graph_description::node_1_nodew_0'
763
764 // begin 'weighted_graph_description::nodew_node_0'
765
766 trg.join(
767 weighted_graph_description::nodew_1_node_0,
768 weighted_graph_description::node_1_nodew_0,
769 t.report("Swap nodes"),
770 [](graph_t g) -> graph_t {
771 g.swap_nodes(1, 0);
772 return g;
773 }
774 );
775
776 // end 'weighted_graph_description::nodew_node_0'
777
778 // begin 'weighted_graph_description::node_1_1w_node_0_0w'
779
780 trg.join(
781 weighted_graph_description::node_1_1w_node_0_0w,
782 weighted_graph_description::node_1w_1w_node_0w_0w,
783 t.report("Set edge weight {0, 1}"),
784 [](graph_t g) -> graph_t {
785 g.set_edge_weight(g.cbegin_edges(0), 1.0);
786 return g;
787 }
788 );
789
790 trg.join(
791 weighted_graph_description::node_1_1w_node_0_0w,
792 weighted_graph_description::node_1w_1w_node_0w_0w,
793 t.report("Set edge weight {1, 0}"),
794 [](graph_t g) -> graph_t {
795 g.set_edge_weight(g.cbegin_edges(1), 1.0);
796 return g;
797 }
798 );
799
800 // end 'weighted_graph_description::node_1_1w_node_0_0w'
801
803
804 trg.join(
805 weighted_graph_description::node_1w_1w_node_0w_0w,
806 weighted_graph_description::node_1_1w_node_0_0w,
807 t.report("Set edge weight {0, 1}"),
808 [](graph_t g) -> graph_t {
809 g.set_edge_weight(g.cbegin_edges(0), 0.0);
810 return g;
811 }
812 );
813
814 trg.join(
815 weighted_graph_description::node_1w_1w_node_0w_0w,
816 weighted_graph_description::node_1_1w_node_0_0w,
817 t.report("Set edge weight {1, 0}"),
818 [](graph_t g) -> graph_t {
819 g.set_edge_weight(g.cbegin_edges(1), 0.0);
820 return g;
821 }
822 );
823
824 trg.join(
825 weighted_graph_description::node_1w_1w_node_0w_0w,
826 weighted_graph_description::node_1_1w_node_0_0w,
827 t.report("Mutate edge weight {0, 1}"),
828 [](graph_t g) -> graph_t {
829 g.mutate_edge_weight(g.cbegin_edges(0), [](double& x){ x -= 1.0; });
830 return g;
831 }
832 );
833
834 trg.join(
835 weighted_graph_description::node_1w_1w_node_0w_0w,
836 weighted_graph_description::node_1_1w_node_0_0w,
837 t.report("Mutate edge weight {1, 0}"),
838 [](graph_t g) -> graph_t {
839 g.mutate_edge_weight(g.cbegin_edges(1), [](double& x){ x -= 1.0; });
840 return g;
841 }
842 );
843
844 trg.join(
845 weighted_graph_description::node_1w_1w_node_0w_0w,
846 graph_description::node_1_node_0,
847 t.report("Ensure edge erasure treats shared weights properly"),
848 [](graph_t g) -> graph_t {
849 g.swap_edges(1, 0, 1);
850 g.erase_edge(g.cbegin_edges(0));
851 g.set_edge_weight(g.cbegin_edges(0), 0.0);
852 return g;
853 }
854 );
855
856 // end 'weighted_graph_description::node_1w_1w_node_0w_0w'
857
858 // begin 'weighted_graph_description::node_1_1w_1x_node_0_0w_0x'
859
860 trg.join(
861 weighted_graph_description::node_1_1w_1x_node_0_0w_0x,
862 weighted_graph_description::node_0y_1_1w_1x_node_0_0w_0x,
863 t.report("Join {0,0} and sort"),
864 [](graph_t g) -> graph_t {
865 g.join(0, 0, 3.0);
866 g.sort_edges(g.cbegin_edges(0),
867 g.cend_edges(0),
868 [](const auto& lhs, const auto& rhs) {
869 return (lhs.target_node() == rhs.target_node()) ? lhs.weight() < rhs.weight() : (lhs.target_node() < rhs.target_node());
870 });
871 return g;
872 }
873 );
874
875 trg.join(
876 weighted_graph_description::node_1_1w_1x_node_0_0w_0x,
877 weighted_graph_description::node_1_1w_1x_node_0_0w_0x,
878 t.report("Set multiple edge weights and sort"),
879 [](graph_t g) -> graph_t {
880 g.set_edge_weight(g.cbegin_edges(0), 1.0);
881 g.set_edge_weight(g.cbegin_edges(0) + 1, 2.0);
882 g.set_edge_weight(g.cbegin_edges(0) + 2 , 0.0);
883
884 for(auto i : std::views::iota(0uz, 2uz))
885 g.sort_edges(g.cbegin_edges(i), g.cend_edges(i), [](const auto& lhs, const auto& rhs) { return lhs.weight() < rhs.weight(); });
886
887 return g;
888 }
889 );
890
891 trg.join(
892 weighted_graph_description::node_1_1w_1x_node_0_0w_0x,
893 weighted_graph_description::node_1_1w_1x_node_0_0w_0x,
894 t.report("Mutate mutliple edge weights and sort"),
895 [](graph_t g) -> graph_t {
896 g.mutate_edge_weight(g.cbegin_edges(0), [](double& x){ x += 1.0; });
897 g.mutate_edge_weight(g.cbegin_edges(0) + 1, [](double& x){ x += 1.0; });
898 g.mutate_edge_weight(g.cbegin_edges(0) + 2, [](double& x){ x -= 2.0; });
899
900 for(auto i : std::views::iota(0uz, 2uz))
901 g.sort_edges(g.cbegin_edges(i), g.cend_edges(i), [](const auto& lhs, const auto& rhs) { return lhs.weight() < rhs.weight(); });
902
903 return g;
904 }
905 );
906
907 // end 'weighted_graph_description::node_1_1w_1x_node_0_0w_0x'
908
909 // begin 'weighted_graph_description::node_0y_1_1w_1x_node_0_0w_0x'
910
911 trg.join(
912 weighted_graph_description::node_0y_1_1w_1x_node_0_0w_0x,
913 weighted_graph_description::node_1_1w_1x_node_0_0w_0x,
914 t.report("Remove zeroth partial edge"),
915 [](graph_t g) -> graph_t {
916 g.erase_edge(g.cbegin_edges(0));
917 return g;
918 }
919 );
920
921 trg.join(
922 weighted_graph_description::node_0y_1_1w_1x_node_0_0w_0x,
923 weighted_graph_description::node_1_1w_1x_node_0_0w_0x,
924 t.report("Remove first partial edge"),
925 [](graph_t g) -> graph_t {
926 g.erase_edge(++g.cbegin_edges(0));
927 return g;
928 }
929 );
930
931 // end'weighted_graph_description::node_0y_1_1w_1x_node_0_0w_0x'
932
933 return trg;
934 }
935 };
936
937
938}
weighted_graph_description
Convention: the indices following 'node' - separated by underscores - give the target node of the ass...
Definition: DynamicUndirectedGraphWeightedTestingUtilities.hpp:18
Definition: DynamicGraph.hpp:303
Definition: DynamicGraph.hpp:360
class template from which all concrete tests should derive.
Definition: FreeTestCore.hpp:144
Exposes elementary check methods, with the option to plug in arbitrary Extenders to compose functiona...
Definition: FreeCheckers.hpp:708
Definition: DynamicUndirectedGraphTestingUtilities.hpp:138
Definition: DynamicUndirectedGraphWeightedTestingUtilities.hpp:90
Definition: DynamicGraphTestingUtilities.hpp:173
Definition: StateTransitionUtilities.hpp:77