Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
search_move_ordering.H
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
48# ifndef SEARCH_MOVE_ORDERING_H
49# define SEARCH_MOVE_ORDERING_H
50
51#include <concepts>
52#include <cstddef>
53#include <optional>
54#include <utility>
55
56#include <tpl_array.H>
57#include <tpl_hash.H>
58#include <tpl_sort_utils.H>
59
60namespace Aleph {
61
69
72{
73 size_t ordered_batches = 0;
74 size_t ordered_moves = 0;
75 size_t priority_estimates = 0;
76 size_t killer_hits = 0;
77 size_t history_hits = 0;
78};
79
85template <typename Move, typename Priority>
87{
88 Move move;
91 size_t ordinal = 0;
92 bool killer = false;
93 size_t history_score = 0;
94};
95
105template <typename Move, bool Supported = std::equality_comparable<Move>>
107
109template <typename Move>
111{
112public:
114 static constexpr bool supported = false;
115
117 static void clear() noexcept
118 {
119 // empty
120 }
121
125 [[nodiscard]] static bool is_killer(const size_t, const Move &) noexcept
126 {
127 return false;
128 }
129
131 static void record(const size_t, const Move &) noexcept
132 {
133 // empty
134 }
135};
136
138template <typename Move>
140{
141public:
143 static constexpr bool supported = true;
144
147 {
148 primary_.empty();
149 secondary_.empty();
150 }
151
157 [[nodiscard]] bool is_killer(const size_t depth, const Move &move) const noexcept
158 {
159 return depth < primary_.size()
160 and ((primary_[depth].has_value() and *primary_[depth] == move)
161 or (secondary_[depth].has_value() and *secondary_[depth] == move));
162 }
163
168 void record(const size_t depth, const Move &move)
169 {
170 ensure_depth(depth + 1);
171 if (primary_[depth].has_value() and *primary_[depth] == move)
172 return;
173
174 secondary_[depth] = primary_[depth];
175 primary_[depth] = move;
176 }
177
178private:
179 void ensure_depth(const size_t required)
180 {
181 while (primary_.size() < required)
182 {
183 primary_.append(std::optional<Move>{});
184 secondary_.append(std::optional<Move>{});
185 }
186 }
187
190};
191
194{
196 static constexpr bool supported = false;
197
199 static void clear() noexcept
200 {
201 // empty
202 }
203
207 template <typename Key>
208 [[nodiscard]] static size_t score(const Key &) noexcept
209 {
210 return 0;
211 }
212
214 template <typename Key>
215 static void record(const Key &, const size_t = 1) noexcept
216 {
217 // empty
218 }
219};
220
227template <typename Key,
228 template <typename, typename, class> class HashMapTable = MapOLhash,
231{
232public:
234 static constexpr bool supported = true;
236 using Key_Type = Key;
239
242 {
243 table_.empty();
244 }
245
250 [[nodiscard]] size_t score(const Key &key) const noexcept
251 {
252 if (auto *entry = table_.search(key); entry != nullptr)
253 return entry->second;
254
255 return 0;
256 }
257
262 void record(const Key &key, const size_t bonus = 1)
263 {
264 if (auto *entry = table_.search(key); entry != nullptr)
265 {
266 entry->second += bonus;
267 return;
268 }
269
270 (void) table_.insert(key, bonus);
271 }
272
273private:
275};
276
294template <typename Move, typename Priority, typename BetterPriority>
297 const bool prefer_killer,
298 const bool prefer_history)
299{
300 if (moves.size() < 2)
301 return;
302
303 introsort(moves,
305 {
306 if (prefer_killer and lhs.killer != rhs.killer)
307 return lhs.killer and not rhs.killer;
308
309 if (prefer_history and lhs.history_score != rhs.history_score)
310 return lhs.history_score > rhs.history_score;
311
312 if (better_priority(lhs.priority, rhs.priority))
313 return true;
314
315 if (better_priority(rhs.priority, lhs.priority))
316 return false;
317
318 return lhs.ordinal < rhs.ordinal;
319 });
320}
321
322} // end namespace Aleph
323
324# endif // SEARCH_MOVE_ORDERING_H
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:139
Sparse history heuristic table over Aleph hash maps.
size_t score(const Key &key) const noexcept
Read the current score for a move key.
static constexpr bool supported
Marker indicating that this table tracks history.
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.
static void record(const size_t, const Move &) noexcept
No-op.
static bool is_killer(const size_t, const Move &) noexcept
Always returns false.
void clear() noexcept
Remove all recorded killer moves.
Array< std::optional< Move > > primary_
Array< std::optional< Move > > secondary_
bool is_killer(const size_t depth, const Move &move) const noexcept
Return true if move is in a killer slot for depth.
void record(const size_t depth, const Move &move)
Record a move that caused a cutoff at depth.
Two-slot killer heuristic table indexed by search depth.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
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.
MoveOrderingMode
Built-in move-ordering modes supported by the framework.
@ Estimated_Bound
Rank successors by an optimistic child bound.
@ Domain
Preserve the order emitted by for_each_successor().
@ Estimated_Score
Rank successors by a cheap heuristic score estimate.
void introsort(T *a, const long l, const long r, const Compare &cmp=Compare())
Sort an array using introsort (introspective sort).
Open addressing hash map using linear probing.
Statistics collected by engines that reorder successor batches.
size_t priority_estimates
Number of score/bound estimates computed for ordering.
size_t killer_hits
Moves promoted because they matched a killer slot.
size_t history_hits
Moves promoted because they had non-zero history.
size_t ordered_moves
Number of individual moves considered by ordering.
size_t ordered_batches
Number of successor batches materialized and ordered.
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.
One move plus the metadata used by ordering comparators.
Priority priority
Cheap heuristic priority (lower or higher depending on engine).
size_t ordinal
Original order from successor generator (tie-breaker).
size_t history_score
Accumulated history heuristic score.
Move move
The candidate move.
bool killer
True if this move matched a killer slot.
Dynamic array container with automatic resizing.
Unified hash table interface.
Comprehensive sorting algorithms and search utilities for Aleph-w.