35#include <gtest/gtest.h>
120 table.record(100, 42);
135 table.record(0,
Opaque{1});
144 table.record(0,
"e2e4");
145 table.record(0,
"d2d4");
220 moves.
append({10, 1, 0,
false, 0});
221 moves.
append({20, 3, 1,
false, 0});
222 moves.
append({30, 2, 2,
false, 0});
225 [](
int a,
int b) {
return a > b; },
236 moves.
append({10, 5, 0,
false, 0});
237 moves.
append({20, 1, 1,
true, 0});
238 moves.
append({30, 3, 2,
false, 0});
241 [](
int a,
int b) {
return a > b; },
252 moves.
append({10, 5, 0,
false, 10});
253 moves.
append({20, 5, 1,
false, 50});
254 moves.
append({30, 5, 2,
false, 30});
257 [](
int a,
int b) {
return a > b; },
268 moves.
append({10, 5, 2,
false, 0});
269 moves.
append({20, 5, 0,
false, 0});
270 moves.
append({30, 5, 1,
false, 0});
273 [](
int a,
int b) {
return a > b; },
284 moves.
append({1, 100, 0,
false, 0});
285 moves.
append({2, 1, 1,
true, 0});
286 moves.
append({3, 50, 2,
false, 999});
287 moves.
append({4, 90, 3,
false, 1});
290 [](
int a,
int b) {
return a > b; },
302 moves.
append({42, 1, 0,
false, 0});
305 [](
int a,
int b) {
return a > b; },
316 [](
int a,
int b) {
return a > b; },
327 constexpr size_t N = 2000;
330 for (
size_t d = 0; d <
N; ++d)
331 table.record(d,
static_cast<int>(d * 10));
333 for (
size_t d = 0; d <
N; ++d)
334 EXPECT_TRUE(table.is_killer(d,
static_cast<int>(d * 10)));
337 for (
size_t d = 0; d <
N; ++d)
341 for (
size_t d = 0; d <
N; ++d)
342 EXPECT_FALSE(table.is_killer(d,
static_cast<int>(d * 10)));
349 for (
int i = 1; i <= 10; ++i)
364 for (
size_t d = 0; d < 500; ++d)
366 table.record(d,
Opaque{
static_cast<int>(d)});
375 constexpr int N = 5000;
377 for (
int k = 0;
k <
N; ++
k)
378 table.
record(
k,
static_cast<size_t>(
k + 1));
380 for (
int k = 0;
k <
N; ++
k)
384 for (
int k = 0;
k <
N; ++
k)
391 constexpr size_t REPS = 1000;
393 for (
size_t i = 0; i <
REPS; ++i)
404 for (
int k = 0;
k < 1000; ++
k)
407 for (
int k = 0;
k < 1000; ++
k)
417 constexpr size_t N = 2000;
418 constexpr unsigned SEED = 42u;
422 {
return std::uniform_int_distribution<int>(lo, hi)(
rng); };
423 auto rand_uint = [&](
size_t lo,
size_t hi)
424 {
return static_cast<size_t>(std::uniform_int_distribution<size_t>(lo, hi)(
rng)); };
425 auto rand_bool = [&]() {
return static_cast<bool>(
rng() & 1u); };
429 for (
size_t i = 0; i <
N; ++i)
451 const double n_log_n =
N * std::log2(
static_cast<double>(
N));
453 <<
"Performance regression in sort_ranked_moves hot path ("
456 for (
size_t i = 0; i + 1 <
N; ++i)
458 const auto &a = moves[i];
459 const auto &b = moves[i + 1];
463 if (a.killer
and not b.killer)
465 if (
not a.killer
and b.killer)
466 FAIL() <<
"Non-killer before killer at index " << i;
470 EXPECT_GE(a.history_score, b.history_score)
471 <<
"History ordering violated at index " << i;
474 if (a.priority != b.priority)
476 <<
"Priority ordering violated at index " << i;
479 <<
"Ordinal tiebreak violated at index " << i;
Simple dynamic array with automatic resizing and functional operations.
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
constexpr bool is_empty() const noexcept
Checks if the container is empty.
T & append(const T &data)
Append a copy of data
Sparse history heuristic table over Aleph hash maps.
size_t score(const Key &key) const noexcept
Read the current score for a move key.
void clear() noexcept
Reset all history scores to zero.
void record(const Key &key, const size_t bonus=1)
Increment the history score for a move key.
Two-slot killer heuristic table indexed by search depth.
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
void sort_ranked_moves(Array< RankedMove< Move, Priority > > &moves, BetterPriority better_priority, const bool prefer_killer, const bool prefer_history)
Sort one materialized move batch using priority and optional hooks.
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.
Shared support for configurable successor ordering heuristics.
Null history heuristic hook used when a domain has no move key.
static constexpr bool supported
Marker indicating that this table does nothing.
static void record(const Key &, const size_t=1) noexcept
No-op.
static size_t score(const Key &) noexcept
Always returns zero.
static void clear() noexcept
No-op.
One move plus the metadata used by ordering comparators.