Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_mo_on_trees_test.cc
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
39# include <gtest/gtest.h>
40
41# include <tpl_mo_on_trees.H>
42# include <tpl_graph.H>
43# include <tpl_sgraph.H>
44# include <tpl_agraph.H>
45# include <tpl_dynSetHash.H>
46
47# include <algorithm>
48# include <cstddef>
49# include <random>
50# include <utility>
51# include <vector>
52
53using namespace Aleph;
54using namespace testing;
55
56namespace
57{
58 // ── Brute-force helpers ────────────────────────────────────────
59
60 // Compute parent map via DFS from tree_root
61 template <class GT>
63 compute_parents(const GT & g, typename GT::Node * tree_root)
64 {
65 using Node = typename GT::Node;
67 parent.insert(tree_root, nullptr);
69 stk.push({tree_root, nullptr});
70 while (not stk.is_empty())
71 {
72 auto [cur, par] = stk.pop();
73 for (auto it = typename GT::Node_Arc_Iterator(cur);
74 it.has_curr(); it.next_ne())
75 {
76 auto * a = it.get_curr();
77 auto * nb = g.get_connected_node(a, cur);
78 if (nb != par)
79 {
80 parent.insert(nb, cur);
81 stk.push({nb, cur});
82 }
83 }
84 }
85 return parent;
86 }
87
88 // Brute-force distinct count over subtree of subtree_root
89 template <class GT>
91 const GT & g,
92 DynMapHash<typename GT::Node*,
93 typename GT::Node*> & parent,
94 typename GT::Node * subtree_root)
95 {
96 using Node = typename GT::Node;
100 while (not stk.is_empty())
101 {
102 auto * cur = stk.pop();
103 seen.insert(cur->get_info());
104 for (auto it = typename GT::Node_Arc_Iterator(cur);
105 it.has_curr(); it.next_ne())
106 {
107 auto * a = it.get_curr();
108 auto * nb = g.get_connected_node(a, cur);
109 if (nb != parent.find(cur))
110 stk.push(nb);
111 }
112 }
113 return seen.size();
114 }
115
116 // Brute-force distinct count on path u→v
117 template <class GT>
118 size_t brute_path_distinct(
119 const GT & g,
120 DynMapHash<typename GT::Node*,
121 typename GT::Node*> & parent,
122 typename GT::Node * u, typename GT::Node * v)
123 {
124 (void) g;
125 using Node = typename GT::Node;
126 // Collect ancestors of u
128 for (auto * p = u; p; p = parent.find(p))
129 anc_u.insert(p);
130 // Find LCA
131 Node * lca_node = v;
132 while (!anc_u.has(lca_node))
133 lca_node = parent.find(lca_node);
134 // Collect values on path
136 for (auto * p = u; p != lca_node; p = parent.find(p))
137 vals.insert(p->get_info());
138 for (auto * p = v; p != lca_node; p = parent.find(p))
139 vals.insert(p->get_info());
140 vals.insert(lca_node->get_info());
141 return vals.size();
142 }
143
144 // ── Tree builder helper ────────────────────────────────────────
145
146 // Build a random tree with n nodes, values in [0, max_val)
147 // Returns (graph, root, array_of_all_nodes)
148 template <class GT>
149 struct TreeInfo
150 {
151 GT g;
152 typename GT::Node * root;
154 };
155
156 template <class GT>
157 TreeInfo<GT> build_random_tree(size_t n, int max_val, std::mt19937 & rng)
158 {
160 if (n == 0)
161 {
162 info.root = nullptr;
163 return info;
164 }
165
167 for (size_t i = 0; i < n; ++i)
168 info.nodes[i] = info.g.insert_node(static_cast<int>(rng() % max_val));
169
170 // Build a random tree: for each node i>0, pick a random parent
171 // from [0, i)
172 for (size_t i = 1; i < n; ++i)
173 {
174 size_t parent_idx = rng() % i;
175 info.g.insert_arc(info.nodes[parent_idx], info.nodes[i]);
176 }
177
178 info.root = info.nodes[0];
179 return info;
180 }
181
182 // ── Path-based chain builder (for deterministic tests) ─────────
183
184 // 0 — 1 — 2 — ... — (n-1)
185 // values: v[i]
186 template <class GT>
188 {
191 for (size_t i = 0; i < vals.size(); ++i)
192 info.nodes[i] = info.g.insert_node(vals[i]);
193
194 for (size_t i = 1; i < vals.size(); ++i)
195 info.g.insert_arc(info.nodes[i-1], info.nodes[i]);
196 info.root = info.nodes.is_empty() ? nullptr : info.nodes[0];
197 return info;
198 }
199
200} // namespace
201
202// =================================================================
203// Structural tests
204// =================================================================
205
207{
209 EXPECT_EQ(g.vsize(), 0u);
210 EXPECT_EQ(g.esize(), 0u);
211 GTEST_SKIP() << "Gen_Mo_On_Trees requires a non-null root node; "
212 << "empty-graph constructor semantics are undefined.";
213}
214
216{
218 G g;
219 auto * r = g.insert_node(42);
221
222 EXPECT_EQ(mot.size(), 1u);
223 EXPECT_FALSE(mot.is_empty());
224
225 auto sub = mot.subtree_solve({r});
226 EXPECT_EQ(sub(0), 1u);
227
228 auto path = mot.path_solve({{r, r}});
229 EXPECT_EQ(path(0), 1u);
230}
231
233{
235 G g;
236 auto * a = g.insert_node(10);
237 auto * b = g.insert_node(10);
238 g.insert_arc(a, b);
239
241
242 auto sub = mot.subtree_solve({a, b});
243 EXPECT_EQ(sub(0), 1u); // subtree(a) = {10, 10} → 1 distinct
244 EXPECT_EQ(sub(1), 1u); // subtree(b) = {10} → 1 distinct
245
246 auto path = mot.path_solve({{a, b}});
247 EXPECT_EQ(path(0), 1u); // path a→b = {10, 10} → 1 distinct
248}
249
251{
253 G g;
254 auto * a = g.insert_node(10);
255 auto * b = g.insert_node(20);
256 g.insert_arc(a, b);
257
259
260 auto sub = mot.subtree_solve({a, b});
261 EXPECT_EQ(sub(0), 2u);
262 EXPECT_EQ(sub(1), 1u);
263
264 auto path = mot.path_solve({{a, b}, {a, a}, {b, b}});
265 EXPECT_EQ(path(0), 2u);
266 EXPECT_EQ(path(1), 1u);
267 EXPECT_EQ(path(2), 1u);
268}
269
271{
273 G g;
274 auto * a = g.insert_node(1);
275 auto * b = g.insert_node(2);
276 g.insert_arc(a, b);
277
278 // Create a node NOT in the graph
279 G g2;
280 auto * alien = g2.insert_node(99);
281
283
284 EXPECT_THROW(mot.subtree_solve({alien}), std::domain_error);
285 EXPECT_THROW(mot.path_solve({{a, alien}}), std::domain_error);
286}
287
288// =================================================================
289// Subtree query tests — List_Graph
290// =================================================================
291
293{
294 /* 1 (root)
295 * / \
296 * 2 1
297 * / \
298 * 3 2
299 */
301 G g;
302 auto * r = g.insert_node(1);
303 auto * a = g.insert_node(2);
304 auto * b = g.insert_node(1);
305 auto * c = g.insert_node(3);
306 auto * d = g.insert_node(2);
307 g.insert_arc(r, a);
308 g.insert_arc(r, b);
309 g.insert_arc(a, c);
310 g.insert_arc(a, d);
311
312 auto parent = compute_parents(g, r);
313
315 auto ans = mot.subtree_solve({r, a, b, c, d});
316
317 EXPECT_EQ(ans(0), brute_subtree_distinct(g, parent, r));
318 EXPECT_EQ(ans(1), brute_subtree_distinct(g, parent, a));
319 EXPECT_EQ(ans(2), brute_subtree_distinct(g, parent, b));
320 EXPECT_EQ(ans(3), brute_subtree_distinct(g, parent, c));
321 EXPECT_EQ(ans(4), brute_subtree_distinct(g, parent, d));
322
323 // Manual verification
324 EXPECT_EQ(ans(0), 3u); // {1,2,3}
325 EXPECT_EQ(ans(1), 2u); // {2,3}
326 EXPECT_EQ(ans(2), 1u); // {1}
327 EXPECT_EQ(ans(3), 1u); // {3}
328 EXPECT_EQ(ans(4), 1u); // {2}
329}
330
331// =================================================================
332// Path query tests — List_SGraph
333// =================================================================
334
336{
337 // Chain: 1 — 2 — 3 — 4 — 5
339 auto info = build_chain<G>({1, 2, 3, 4, 5});
340 auto & g = info.g;
341 auto & n = info.nodes;
342 auto parent = compute_parents(g, n[0]);
343
345
346 auto ans = mot.path_solve({
347 {n[0], n[4]}, // 1→2→3→4→5, 5 distinct
348 {n[1], n[3]}, // 2→3→4, 3 distinct
349 {n[0], n[0]}, // just 1, 1 distinct
350 {n[2], n[4]} // 3→4→5, 3 distinct
351 });
352
353 EXPECT_EQ(ans(0), 5u);
354 EXPECT_EQ(ans(1), 3u);
355 EXPECT_EQ(ans(2), 1u);
356 EXPECT_EQ(ans(3), 3u);
357
358 for (size_t i = 0; i < 4; ++i)
359 {
360 auto [u, v] = std::pair{
361 i == 0 ? n[0] : i == 1 ? n[1] : i == 2 ? n[0] : n[2],
362 i == 0 ? n[4] : i == 1 ? n[3] : i == 2 ? n[0] : n[4]};
363 EXPECT_EQ(ans(i), brute_path_distinct(g, parent, u, v))
364 << "query " << i;
365 }
366}
367
369{
370 // Star: center = 1, leaves = 2, 2, 3, 3, 4
372 G g;
373 auto * center = g.insert_node(1);
374 auto * l1 = g.insert_node(2);
375 auto * l2 = g.insert_node(2);
376 auto * l3 = g.insert_node(3);
377 auto * l4 = g.insert_node(3);
378 auto * l5 = g.insert_node(4);
379 g.insert_arc(center, l1);
380 g.insert_arc(center, l2);
381 g.insert_arc(center, l3);
382 g.insert_arc(center, l4);
383 g.insert_arc(center, l5);
384
385 auto parent = compute_parents(g, center);
387
388 auto ans = mot.path_solve({
389 {l1, l2}, // 2→1→2: {1,2} = 2
390 {l1, l5}, // 2→1→4: {1,2,4} = 3
391 {l3, l4}, // 3→1→3: {1,3} = 2
392 {center, l5} // 1→4: {1,4} = 2
393 });
394
395 EXPECT_EQ(ans(0), brute_path_distinct(g, parent, l1, l2));
396 EXPECT_EQ(ans(1), brute_path_distinct(g, parent, l1, l5));
397 EXPECT_EQ(ans(2), brute_path_distinct(g, parent, l3, l4));
398 EXPECT_EQ(ans(3), brute_path_distinct(g, parent, center, l5));
399}
400
401// =================================================================
402// Array_Graph tests
403// =================================================================
404
406{
407 /* 10 (root)
408 * / \
409 * 20 30
410 * / \
411 * 10 20
412 */
414 G g;
415 auto * r = g.insert_node(10);
416 auto * a = g.insert_node(20);
417 auto * b = g.insert_node(30);
418 auto * c = g.insert_node(10);
419 auto * d = g.insert_node(20);
420 g.insert_arc(r, a);
421 g.insert_arc(r, b);
422 g.insert_arc(a, c);
423 g.insert_arc(a, d);
424
425 auto parent = compute_parents(g, r);
426
428 auto sub = mot.subtree_solve({r, a, b});
429 EXPECT_EQ(sub(0), brute_subtree_distinct(g, parent, r));
430 EXPECT_EQ(sub(1), brute_subtree_distinct(g, parent, a));
431 EXPECT_EQ(sub(2), brute_subtree_distinct(g, parent, b));
432
433 EXPECT_EQ(sub(0), 3u); // {10,20,30}
434 EXPECT_EQ(sub(1), 2u); // {10,20}
435 EXPECT_EQ(sub(2), 1u); // {30}
436
437 auto path = mot.path_solve({{c, d}, {c, b}});
438 EXPECT_EQ(path(0), brute_path_distinct(g, parent, c, d));
439 EXPECT_EQ(path(1), brute_path_distinct(g, parent, c, b));
440}
441
442// =================================================================
443// Stress tests (random trees, brute-force verification)
444// =================================================================
445
446template <class GT>
447class MoOnTreesStress : public Test {};
448
453>;
454
456
458{
459 using G = TypeParam;
460 std::mt19937 rng(123);
461 auto info = build_random_tree<G>(50, 10, rng);
462 auto & g = info.g;
463 auto parent = compute_parents(g, info.root);
464
466
467 // Query all nodes
468 auto queries = Array<typename G::Node*>::create(info.nodes.size());
469 for (size_t i = 0; i < info.nodes.size(); ++i)
470 queries(i) = info.nodes[i];
471
472 auto ans = mot.subtree_solve(queries);
473
474 for (size_t i = 0; i < info.nodes.size(); ++i)
475 EXPECT_EQ(ans(i), brute_subtree_distinct(g, parent, info.nodes[i]))
476 << "node " << i;
477}
478
480{
481 using G = TypeParam;
482 std::mt19937 rng(456);
483 auto info = build_random_tree<G>(50, 10, rng);
484 auto & g = info.g;
485 auto parent = compute_parents(g, info.root);
486 const size_t n = info.nodes.size();
487
489
490 // Generate 200 random path queries
491 const size_t Q = 200;
492 auto queries = Array<std::pair<typename G::Node*,
493 typename G::Node*>>::create(Q);
494 for (size_t i = 0; i < Q; ++i)
495 queries(i) = {info.nodes[rng() % n], info.nodes[rng() % n]};
496
497 auto ans = mot.path_solve(queries);
498
499 for (size_t i = 0; i < Q; ++i)
500 EXPECT_EQ(ans(i), brute_path_distinct(g, parent,
501 queries(i).first,
502 queries(i).second))
503 << "query " << i;
504}
505
507{
508 using G = TypeParam;
509 std::mt19937 rng(789);
510 auto info = build_random_tree<G>(500, 20, rng);
511 auto & g = info.g;
512 auto parent = compute_parents(g, info.root);
513 const size_t n = info.nodes.size();
514
516
517 const size_t Q = 500;
519 for (size_t i = 0; i < Q; ++i)
520 queries(i) = info.nodes[rng() % n];
521
522 auto ans = mot.subtree_solve(queries);
523
524 for (size_t i = 0; i < Q; ++i)
525 EXPECT_EQ(ans(i), brute_subtree_distinct(g, parent, queries(i)))
526 << "query " << i;
527}
528
530{
531 using G = TypeParam;
532 std::mt19937 rng(101112);
533 auto info = build_random_tree<G>(500, 20, rng);
534 auto & g = info.g;
535 auto parent = compute_parents(g, info.root);
536 const size_t n = info.nodes.size();
537
539
540 const size_t Q = 1000;
541 auto queries = Array<std::pair<typename G::Node*,
542 typename G::Node*>>::create(Q);
543 for (size_t i = 0; i < Q; ++i)
544 queries(i) = {info.nodes[rng() % n], info.nodes[rng() % n]};
545
546 auto ans = mot.path_solve(queries);
547
548 for (size_t i = 0; i < Q; ++i)
549 EXPECT_EQ(ans(i), brute_path_distinct(g, parent,
550 queries(i).first,
551 queries(i).second))
552 << "query " << i;
553}
554
555// =================================================================
556// Powerful array policy on trees
557// =================================================================
558
560{
561 // Chain: 1 — 2 — 1 — 3
562 // Path (0→3): values {1,2,1,3}, cnt = {1:2, 2:1, 3:1}
563 // power = 4*1 + 1*2 + 1*3 = 9
565 auto info = build_chain<G>({1, 2, 1, 3});
566 auto & n = info.nodes;
567
569
570 auto ans = mot.path_solve({{n[0], n[3]}});
571 EXPECT_EQ(ans(0), 9LL);
572
573 // Subtree of root = whole tree = same answer
574 auto sub = mot.subtree_solve({n[0]});
575 EXPECT_EQ(sub(0), 9LL);
576}
577
578// =================================================================
579// Deep chain (regression: iterative DFS handles deep trees)
580// =================================================================
581
583{
585 const size_t N = 5000;
586 G g;
587 std::vector<typename G::Node*> nodes;
588 for (size_t i = 0; i < N; ++i)
589 nodes.push_back(g.insert_node(static_cast<int>(i % 7)));
590 for (size_t i = 1; i < N; ++i)
591 g.insert_arc(nodes[i-1], nodes[i]);
592
594
595 // Subtree of root = all nodes
596 auto sub = mot.subtree_solve({nodes[0]});
597 EXPECT_EQ(sub(0), 7u); // values 0..6
598
599 // Path from first to last = all nodes
600 auto path = mot.path_solve({{nodes[0], nodes[N-1]}});
601 EXPECT_EQ(path(0), 7u);
602}
603
604// =================================================================
605// No-queries edge case
606// =================================================================
607
609{
611 G g;
612 auto * r = g.insert_node(1);
614
615 auto sub = mot.subtree_solve(Array<typename G::Node*>());
616 EXPECT_EQ(sub.size(), 0u);
617
618 auto path = mot.path_solve(
619 Array<std::pair<typename G::Node*, typename G::Node*>>());
620 EXPECT_EQ(path.size(), 0u);
621}
622
623// =================================================================
624// Tree_Node tests
625// =================================================================
626
628{
629 using TN = Tree_Node<int>;
630 auto * r = new TN(42);
632 EXPECT_EQ(mot.size(), 1u);
633
634 auto sub = mot.subtree_solve({r});
635 EXPECT_EQ(sub(0), 1u);
636
637 auto path = mot.path_solve({{r, r}});
638 EXPECT_EQ(path(0), 1u);
639
641}
642
644{
645 using TN = Tree_Node<int>;
646 // r(1)
647 // / | \ .
648 // a(2) b(1) c(3)
649 // / \ |
650 // d(4) e(2) f(1)
651 // |
652 // g(5)
653 auto * r = new TN(1);
654 auto * a = new TN(2);
655 auto * b = new TN(1);
656 auto * c = new TN(3);
657 auto * d = new TN(4);
658 auto * e = new TN(2);
659 auto * f = new TN(1);
660 auto * g = new TN(5);
661
662 r->insert_rightmost_child(a);
663 r->insert_rightmost_child(b);
664 r->insert_rightmost_child(c);
665 a->insert_rightmost_child(d);
666 a->insert_rightmost_child(e);
667 c->insert_rightmost_child(f);
668 d->insert_rightmost_child(g);
669
671 EXPECT_EQ(mot.size(), 8u);
672
673 auto sub = mot.subtree_solve({r, a, b, c, d, e, f, g});
674 EXPECT_EQ(sub(0), 5u); // root: {1,2,1,3,4,2,1,5} → 5
675 EXPECT_EQ(sub(1), 3u); // a: {2,4,5,2} → 3
676 EXPECT_EQ(sub(2), 1u); // b: {1} → 1
677 EXPECT_EQ(sub(3), 2u); // c: {3,1} → 2
678 EXPECT_EQ(sub(4), 2u); // d: {4,5} → 2
679 EXPECT_EQ(sub(5), 1u); // e: {2} → 1
680 EXPECT_EQ(sub(6), 1u); // f: {1} → 1
681 EXPECT_EQ(sub(7), 1u); // g: {5} → 1
682
684}
685
687{
688 using TN = Tree_Node<int>;
689 // Same tree as above
690 auto * r = new TN(1);
691 auto * a = new TN(2);
692 auto * b = new TN(1);
693 auto * c = new TN(3);
694 auto * d = new TN(4);
695 auto * e = new TN(2);
696 auto * f = new TN(1);
697 auto * g = new TN(5);
698
699 r->insert_rightmost_child(a);
700 r->insert_rightmost_child(b);
701 r->insert_rightmost_child(c);
702 a->insert_rightmost_child(d);
703 a->insert_rightmost_child(e);
704 c->insert_rightmost_child(f);
705 d->insert_rightmost_child(g);
706
708
709 auto path = mot.path_solve({{g, f}, {e, b}, {d, c}, {r, r}, {a, g}});
710 // g→f: g(5)→d(4)→a(2)→r(1)→c(3)→f(1) → {5,4,2,1,3} = 5
711 EXPECT_EQ(path(0), 5u);
712 // e→b: e(2)→a(2)→r(1)→b(1) → {2,1} = 2
713 EXPECT_EQ(path(1), 2u);
714 // d→c: d(4)→a(2)→r(1)→c(3) → {4,2,1,3} = 4
715 EXPECT_EQ(path(2), 4u);
716 // r→r: {1} = 1
717 EXPECT_EQ(path(3), 1u);
718 // a→g: a(2)→d(4)→g(5) → {2,4,5} = 3
719 EXPECT_EQ(path(4), 3u);
720
722}
723
725{
726 using TN = Tree_Node<int>;
727 const size_t N = 200;
728 const int max_val = 10;
729
730 std::mt19937 rng(54321);
731 std::uniform_int_distribution<int> val_dist(0, max_val - 1);
732 std::uniform_int_distribution<size_t> parent_dist;
733
734 // Build random tree
735 std::vector<TN*> nodes(N);
736 nodes[0] = new TN(val_dist(rng));
737 for (size_t i = 1; i < N; ++i)
738 {
739 nodes[i] = new TN(val_dist(rng));
740 size_t par = parent_dist(rng) % i;
741 nodes[par]->insert_rightmost_child(nodes[i]);
742 }
743
745 EXPECT_EQ(mot.size(), N);
746
747 // Brute-force subtree distinct: DFS collecting values
748 auto brute_subtree = [&](TN * sub_root) -> size_t
749 {
751 std::vector<TN*> stk;
752 stk.push_back(sub_root);
753 while (!stk.empty())
754 {
755 auto * cur = stk.back();
756 stk.pop_back();
757 seen.insert(cur->get_key());
758 for (auto * ch = cur->get_left_child(); ch != nullptr;
759 ch = ch->get_right_sibling())
760 stk.push_back(ch);
761 }
762 return seen.size();
763 };
764
765 // Query every node
767 for (size_t i = 0; i < N; ++i)
768 qroots(i) = nodes[i];
769
770 auto ans = mot.subtree_solve(qroots);
771 for (size_t i = 0; i < N; ++i)
773 << "Mismatch at subtree node " << i;
774
776}
777
779{
782 std::domain_error);
783}
784
786{
787 using TN = Tree_Node<int>;
788 auto * r = new TN(1);
790
791 auto sub = mot.subtree_solve(Array<TN*>());
792 EXPECT_EQ(sub.size(), 0u);
793
794 auto path = mot.path_solve(Array<std::pair<TN*, TN*>>());
795 EXPECT_EQ(path.size(), 0u);
796
798}
WeightedDigraph::Node Node
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:139
static Array create(size_t n)
Create an array with n logical elements.
Definition tpl_array.H:194
Self-adjusting dynamic hash table.
Key * insert(const Key &key)
Inserts key into the hash set.
Dynamic stack of elements of generic type T based on a singly linked list.
T & push(const T &data)
Push an item by copy onto the top of the stack.
Pair * insert(const Key &key, const Data &data)
Inserts into the hash map the pair (key, record) indexed by key.
Data & find(const Key &key)
Finds and returns a reference to the value associated with key.
Offline subtree and path queries on N-ary trees (Tree_Node).
Offline subtree and path queries on trees via Mo's algorithm.
Arc for graphs implemented with simple adjacency lists.
Definition tpl_sgraph.H:197
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Definition tpl_graph.H:524
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Definition tpl_graph.H:604
Graph class implemented with singly-linked adjacency lists.
Definition tpl_sgraph.H:274
Generic m-ary trees.
Node * get_connected_node(Arc *arc, Node *node) const noexcept
Return the adjacent node to node through arc.
Definition graph-dry.H:778
constexpr size_t vsize() const noexcept
Definition graph-dry.H:704
size_t esize() const noexcept
Return the total of arcs of graph.
Definition graph-dry.H:798
Container< Node * > nodes() const
Return a container with all the nodes of the graph.
Definition graph-dry.H:2726
#define TEST(name)
static mt19937 rng
#define N
Definition fib.C:294
__gmp_expr< T, __gmp_binary_expr< __gmp_expr< T, U >, unsigned long int, __gmp_root_function > > root(const __gmp_expr< T, U > &expr, unsigned long int l)
Definition gmpfrxx.h:4060
DynArray< Graph::Node * > nodes
Definition graphpic.C:406
void destroy_tree(Node *root)
Destroys (frees memory) the tree whose root is root.
static size_t brute_subtree_distinct(const GT &g, typename GT::Node *tree_root, typename GT::Node *subtree_root)
static size_t brute_path_distinct(const GT &g, typename GT::Node *root, typename GT::Node *u, typename GT::Node *v)
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
Arc of graph implemented with double-linked adjacency lists.
Definition tpl_graph.H:222
DynList< char > l3
DynList< int > l1
DynList< int > l2
DynSetTree< char > l5
Dnode< int > Test
Definition testDnode.C:37
gsl_rng * r
Array-based graph implementation.
::testing::Types< ListGraph, ListDigraph, SparseGraph, SparseDigraph, ArrayGraph, ArrayDigraph > GraphTypes
Dynamic set implementations based on hash tables.
Generic graph and digraph implementations.
Mo's algorithm on trees: offline subtree and path queries.
TYPED_TEST_SUITE(MoOnTreesStress, GraphTypes)
TYPED_TEST(MoOnTreesStress, SubtreeRandomSmall)
Simple graph implementation with adjacency lists.