39# include <gtest/gtest.h>
54using namespace testing;
67 parent.
insert(tree_root,
nullptr);
72 auto [
cur, par] =
stk.pop();
73 for (
auto it =
typename GT::Node_Arc_Iterator(
cur);
74 it.has_curr(); it.next_ne())
76 auto * a = it.get_curr();
100 while (
not stk.is_empty())
104 for (
auto it =
typename GT::Node_Arc_Iterator(
cur);
105 it.has_curr(); it.next_ne())
107 auto * a = it.get_curr();
128 for (
auto * p = u; p; p = parent.
find(p))
139 vals.insert(p->get_info());
167 for (
size_t i = 0; i < n; ++i)
168 info.nodes[i] =
info.g.insert_node(
static_cast<int>(
rng() % max_val));
172 for (
size_t i = 1; i < n; ++i)
191 for (
size_t i = 0; i <
vals.size(); ++i)
194 for (
size_t i = 1; i <
vals.size(); ++i)
211 GTEST_SKIP() <<
"Gen_Mo_On_Trees requires a non-null root node; "
212 <<
"empty-graph constructor semantics are undefined.";
225 auto sub =
mot.subtree_solve({
r});
228 auto path =
mot.path_solve({{
r,
r}});
242 auto sub =
mot.subtree_solve({a, b});
246 auto path =
mot.path_solve({{a, b}});
260 auto sub =
mot.subtree_solve({a, b});
264 auto path =
mot.path_solve({{a, b}, {a, a}, {b, b}});
315 auto ans =
mot.subtree_solve({
r, a, b, c, d});
346 auto ans =
mot.path_solve({
358 for (
size_t i = 0; i < 4; ++i)
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]};
388 auto ans =
mot.path_solve({
428 auto sub =
mot.subtree_solve({
r, a, b});
437 auto path =
mot.path_solve({{c, d}, {c, b}});
460 std::mt19937
rng(123);
469 for (
size_t i = 0; i <
info.nodes.size(); ++i)
474 for (
size_t i = 0; i <
info.nodes.size(); ++i)
482 std::mt19937
rng(456);
486 const size_t n =
info.nodes.size();
491 const size_t Q = 200;
494 for (
size_t i = 0; i <
Q; ++i)
499 for (
size_t i = 0; i <
Q; ++i)
509 std::mt19937
rng(789);
513 const size_t n =
info.nodes.size();
517 const size_t Q = 500;
519 for (
size_t i = 0; i <
Q; ++i)
524 for (
size_t i = 0; i <
Q; ++i)
532 std::mt19937
rng(101112);
536 const size_t n =
info.nodes.size();
540 const size_t Q = 1000;
543 for (
size_t i = 0; i <
Q; ++i)
548 for (
size_t i = 0; i <
Q; ++i)
566 auto & n =
info.nodes;
570 auto ans =
mot.path_solve({{n[0], n[3]}});
574 auto sub =
mot.subtree_solve({n[0]});
585 const size_t N = 5000;
587 std::vector<typename G::Node*>
nodes;
588 for (
size_t i = 0; i <
N; ++i)
590 for (
size_t i = 1; i <
N; ++i)
596 auto sub =
mot.subtree_solve({
nodes[0]});
618 auto path =
mot.path_solve(
619 Array<std::pair<typename G::Node*, typename G::Node*>>());
630 auto *
r =
new TN(42);
634 auto sub =
mot.subtree_solve({
r});
637 auto path =
mot.path_solve({{
r,
r}});
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);
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);
673 auto sub =
mot.subtree_solve({
r, a, b, c, d, e, f, g});
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);
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);
709 auto path =
mot.path_solve({{g, f}, {e, b}, {d, c}, {
r,
r}, {a, g}});
727 const size_t N = 200;
728 const int max_val = 10;
730 std::mt19937
rng(54321);
731 std::uniform_int_distribution<int>
val_dist(0, max_val - 1);
735 std::vector<TN*>
nodes(
N);
737 for (
size_t i = 1; i <
N; ++i)
751 std::vector<TN*>
stk;
758 for (
auto *
ch =
cur->get_left_child();
ch !=
nullptr;
759 ch =
ch->get_right_sibling())
767 for (
size_t i = 0; i <
N; ++i)
771 for (
size_t i = 0; i <
N; ++i)
773 <<
"Mismatch at subtree node " << i;
788 auto *
r =
new TN(1);
794 auto path =
mot.path_solve(
Array<std::pair<TN*, TN*>>());
WeightedDigraph::Node Node
Simple dynamic array with automatic resizing and functional operations.
static Array create(size_t n)
Create an array with n logical elements.
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.
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Graph_Node< Node_Info > Node
The graph type.
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Graph class implemented with singly-linked adjacency lists.
Node * get_connected_node(Arc *arc, Node *node) const noexcept
Return the adjacent node to node through arc.
constexpr size_t vsize() const noexcept
size_t esize() const noexcept
Return the total of arcs of graph.
Container< Node * > nodes() const
Return a container with all the nodes of the graph.
__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)
DynArray< Graph::Node * > nodes
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.
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.
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.