76 static const std::array<const char *, NODES>
NODE_LABELS = {
77 "CEO",
"CTO",
"CFO",
"Platform",
"Data",
78 "Accounting",
"Legal",
"SRE",
"ML"
86 size_t expected_distance;
89 static const std::array<Query, 6>
QUERIES = {{
100 const char * backend_name =
"";
101 bool deterministic_ok =
true;
102 bool engines_agree =
true;
103 bool checksum_equal =
true;
104 std::uint64_t binary_ms = 0;
105 std::uint64_t euler_ms = 0;
106 std::uint64_t checksum_bin = 0;
107 std::uint64_t checksum_eul = 0;
124 Backend_Result
run_backend(
const char * backend_name)
131 for (
size_t i = 0; i <
NODES; ++i)
147 Backend_Result result;
148 result.backend_name = backend_name;
150 std::cout <<
"Backend: " << backend_name <<
"\n";
151 std::cout << std::left
152 << std::setw(18) <<
"Query(u,v)"
153 << std::setw(14) <<
"Binary LCA"
154 << std::setw(14) <<
"Euler LCA"
155 << std::setw(10) <<
"Distance"
157 std::cout << std::string(66,
'-') <<
"\n";
164 const auto bl_idx =
static_cast<size_t>(
lca_bin->get_info());
165 const auto er_idx =
static_cast<size_t>(
lca_eul->get_info());
171 (dist == q.expected_distance);
173 result.engines_agree = result.engines_agree
and agree;
174 result.deterministic_ok = result.deterministic_ok
and expected;
176 std::cout << std::left
181 << std::setw(10) << dist
186 constexpr size_t qcount = 200000;
188 std::mt19937
rng(0x1ca2026u);
189 std::uniform_int_distribution<size_t> pick(0,
NODES - 1);
190 for (
size_t i = 0; i <
qcount; ++i)
193 auto run_binary = [&]() -> std::pair<std::uint64_t, std::uint64_t>
195 const auto t0 = std::chrono::high_resolution_clock::now();
197 for (
size_t i = 0; i <
qcount; ++i)
202 const auto t1 = std::chrono::high_resolution_clock::now();
203 const auto ms =
static_cast<std::uint64_t
>(
204 std::chrono::duration_cast<std::chrono::milliseconds>(
t1 -
t0).count());
208 auto run_euler = [&]() -> std::pair<std::uint64_t, std::uint64_t>
210 const auto t0 = std::chrono::high_resolution_clock::now();
212 for (
size_t i = 0; i <
qcount; ++i)
217 const auto t1 = std::chrono::high_resolution_clock::now();
218 const auto ms =
static_cast<std::uint64_t
>(
219 std::chrono::duration_cast<std::chrono::milliseconds>(
t1 -
t0).count());
223 const auto [binary_ms, checksum_bin] =
run_binary();
224 const auto [euler_ms, checksum_eul] =
run_euler();
226 result.binary_ms = binary_ms;
227 result.euler_ms = euler_ms;
228 result.checksum_bin = checksum_bin;
229 result.checksum_eul = checksum_eul;
230 result.checksum_equal = (checksum_bin == checksum_eul);
232 std::cout <<
"Benchmark (" <<
qcount <<
" random queries):\n";
233 std::cout <<
" Binary lifting: " << binary_ms <<
" ms\n";
234 std::cout <<
" Euler + RMQ: " << euler_ms <<
" ms\n";
235 std::cout <<
" Checksums equal: " << (result.checksum_equal ?
"yes" :
"no") <<
"\n\n";
256 std::cout <<
"==============================================================\n";
257 std::cout <<
" LCA on Aleph Tree Graphs (Cross-Backend Parity Demo)\n";
258 std::cout <<
"==============================================================\n\n";
264 std::cout <<
"Parity summary:\n";
265 std::cout << std::left
266 << std::setw(13) <<
"Backend"
267 << std::setw(14) <<
"Deterministic"
268 << std::setw(14) <<
"EnginesAgree"
269 << std::setw(14) <<
"ChecksumEq"
270 << std::setw(11) <<
"Binary(ms)"
272 std::cout << std::string(72,
'-') <<
"\n";
278 std::cout << std::left
279 << std::setw(13) <<
r.backend_name
280 << std::setw(14) << (
r.deterministic_ok ?
"yes" :
"no")
281 << std::setw(14) << (
r.engines_agree ?
"yes" :
"no")
282 << std::setw(14) << (
r.checksum_equal ?
"yes" :
"no")
283 << std::setw(11) <<
r.binary_ms
284 <<
r.euler_ms <<
"\n";
294 std::cout <<
"\nCross-backend checksum parity: "
Lowest Common Ancestor (LCA) on rooted trees represented as Aleph graphs.
WeightedDigraph::Node Node
List_Graph< Graph_Node< Node_Info >, Graph_Arc< Arc_Info > > GT
Simple dynamic array with automatic resizing and functional operations.
static Array create(size_t n)
Create an array with n logical elements.
LCA via binary lifting on a rooted tree.
LCA via Euler tour + RMQ on depth in a rooted tree.
Arc for graphs implemented with simple 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.
DynArray< Graph::Node * > nodes
int main()
Runs the LCA cross-backend parity demo and prints results.
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
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.
Dynamic array container with automatic resizing.
Generic graph and digraph implementations.
Simple graph implementation with adjacency lists.