49#include <gtest/gtest.h>
77 class Naive_Path_Oracle
79 static constexpr size_t NONE = std::numeric_limits<size_t>::max();
83 std::vector<std::vector<size_t>> adj_;
84 std::vector<size_t> parent_;
85 std::vector<size_t> depth_;
86 std::vector<int> values_;
88 void dfs(
const size_t u,
const size_t p,
const size_t d)
93 for (
const auto v : adj_[u])
99 Naive_Path_Oracle(
const size_t n,
100 const std::vector<std::pair<size_t, size_t>> & edges,
102 const std::vector<int> &
vals)
103 : n_(n), root_(
root), adj_(n), parent_(n, NONE),
104 depth_(n, 0), values_(
vals)
106 for (
const auto & [u, v] : edges)
108 adj_[u].push_back(v);
109 adj_[v].push_back(u);
114 [[
nodiscard]]
size_t lca(
size_t u,
size_t v)
const
116 if (depth_[u] < depth_[v])
119 while (depth_[u] > depth_[v])
132 const size_t a = lca(u, v);
137 result += values_[x];
143 result += values_[x];
146 result += values_[a];
152 const size_t a = lca(u, v);
153 int result = std::numeric_limits<int>::lowest();
157 result = std::max(result, values_[x]);
163 result = std::max(result, values_[x]);
166 result = std::max(result, values_[a]);
172 const size_t a = lca(u, v);
173 int result = std::numeric_limits<int>::max();
177 result = std::min(result, values_[x]);
183 result = std::min(result, values_[x]);
186 result = std::min(result, values_[a]);
192 int result = values_[v];
193 std::vector<size_t> stack = {v};
194 while (
not stack.empty())
196 const size_t u = stack.back();
198 for (
const auto c : adj_[u])
201 result += values_[c];
208 [[
nodiscard]]
size_t distance(
size_t u,
size_t v)
const
210 const size_t a = lca(u, v);
211 return depth_[u] + depth_[v] - 2 * depth_[a];
214 void set_value(
size_t u,
int val) { values_[u] = val; }
215 [[
nodiscard]]
int value(
size_t u)
const {
return values_[u]; }
216 [[
nodiscard]]
size_t depth(
size_t u)
const {
return depth_[u]; }
220 class HldTypedTest :
public ::testing::Test
239 auto nv = [](
typename Graph::Node * p) {
return p->get_info(); };
257 auto nv = [](
Node * p) {
return p->get_info(); };
286 const std::vector<std::pair<size_t, size_t>> edges = {
293 auto nodes = build_graph_with_unit_arcs(g, 9, edges);
295 auto nv = [](
Node * p) {
return p->get_info() * 10; };
325 const std::vector<std::pair<size_t, size_t>> edges = {
332 auto nodes = build_graph_with_unit_arcs(g, 9, edges);
335 const int vals[] = {5, 3, 8, 1, 9, 2, 7, 4, 6};
354 const std::vector<std::pair<size_t, size_t>> edges = {
361 auto nodes = build_graph_with_unit_arcs(g, 9, edges);
363 auto nv = [](
Node * p) {
return p->get_info() + 1; };
387 const std::vector<std::pair<size_t, size_t>> edges = {
388 {0, 1}, {0, 2}, {1, 3}, {1, 4}};
391 auto nodes = build_graph_with_unit_arcs(g, 5, edges);
394 auto nv = [](
Node *) {
return 10; };
425 const std::vector<std::pair<size_t, size_t>> edges = {
426 {0, 1}, {0, 2}, {1, 3}};
429 auto nodes = build_graph_with_unit_arcs(g, 4, edges);
455 const std::vector<std::pair<size_t, size_t>> edges = {
462 auto nodes = build_graph_with_unit_arcs(g, 9, edges);
464 auto nv = [](
Node * p) {
return p->get_info(); };
469 for (
size_t u = 0; u < 9; ++u)
470 for (
size_t v = u; v < 9; ++v)
475 <<
"u=" << u <<
" v=" << v;
487 const std::vector<std::pair<size_t, size_t>> edges = {
494 auto nodes = build_graph_with_unit_arcs(g, 9, edges);
496 auto nv = [](
Node * p) {
return p->get_info(); };
504 std::vector<bool>
seen(9,
false);
505 for (
size_t i = 0; i < 9; ++i)
507 const size_t pos =
hld.position(i);
523 for (
size_t i = 0; i < 9; ++i)
525 const size_t head =
hld.chain_head_id(i);
535 auto nv = [](
Node * p) {
return p->get_info(); };
540 auto nodes = build_graph_with_unit_arcs(g, 3, {{0, 1}, {1, 2}, {2, 0}});
547 auto nodes = build_graph_with_unit_arcs(g, 4, {{0, 1}, {2, 3}});
554 auto nodes = build_graph_with_unit_arcs(g, 3, {{0, 1}, {1, 2}, {2, 2}});
561 auto nodes = build_graph_with_unit_arcs(g, 2, {{0, 1}, {0, 1}});
573 for (
size_t i = 0; i < 6; ++i)
588 auto nv = [](
Node * p) {
return p->get_info(); };
598 EXPECT_EQ(
static_cast<size_t>(
l->get_info()), 0u);
601 EXPECT_EQ(
static_cast<size_t>(
l->get_info()), 1u);
609 std::mt19937
rng(0x41d2026u);
611 for (
size_t sample = 0; sample < 20; ++sample)
613 std::uniform_int_distribution<size_t>
n_pick(2, 80);
617 std::uniform_int_distribution<int>
val_pick(-100, 100);
618 std::vector<int>
vals(n);
619 for (
size_t i = 0; i < n; ++i)
622 std::uniform_int_distribution<size_t>
root_pick(0, n - 1);
626 auto nodes = build_graph_with_unit_arcs(g, n, edges);
638 std::uniform_int_distribution<size_t>
node_pick(0, n - 1);
641 for (
size_t q = 0; q < 200; ++q)
648 <<
"sample=" << sample <<
" u=" << u <<
" v=" << v;
652 <<
"sample=" << sample <<
" u=" << u <<
" v=" << v;
656 <<
"sample=" << sample <<
" u=" << u <<
" v=" << v;
661 <<
"sample=" << sample <<
" u=" << u <<
" v=" << v;
666 <<
"sample=" << sample <<
" u=" << u <<
" v=" << v;
670 for (
size_t q = 0; q < 50; ++q)
675 <<
"sample=" << sample <<
" v=" << v;
679 for (
size_t q = 0; q < 20; ++q)
692 <<
"sample=" << sample <<
" after update";
Heavy-Light Decomposition for tree path queries on Aleph graphs.
Lowest Common Ancestor (LCA) on rooted trees represented as Aleph graphs.
TYPED_TEST_SUITE(AStarHeapTest, HeapTypes)
WeightedDigraph::Node Node
static Array create(size_t n)
Create an array with n logical elements.
LCA via binary lifting on a rooted tree.
Arc for graphs implemented with simple adjacency lists.
Graph implemented with double-linked adjacency lists.
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Graph class implemented with singly-linked adjacency lists.
__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
TYPED_TEST(HldTypedTest, EmptyTree)
DFSResult< typename Domain::Distance > dfs(Domain &domain, typename Domain::State &state, SearchPath< typename Domain::Move > &path, const typename Domain::Distance g, const typename Domain::Distance threshold, const size_t depth, IDAStarResult< Solution, typename Domain::Distance > &result, OnSolution &on_solution)
Core recursive DFS used by IDA* for a single threshold pass.
Aleph::Array< typename GT::Node * > build_graph_with_unit_arcs(GT &g, const size_t n, const std::vector< std::pair< size_t, size_t > > &edges)
EdgeContainer make_random_tree_edges(const size_t n, std::mt19937 &rng)
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.
HLD with path/subtree max queries.
HLD with path/subtree min queries.
HLD with path/subtree sum queries.
Array-based graph implementation.
Generic graph and digraph implementations.
Simple graph implementation with adjacency lists.