improve parent selection
This commit is contained in:
parent
bbeb1b8b37
commit
4ec9f3cf21
@ -8,9 +8,9 @@ use std::time::Duration;
|
||||
fn extend_layers_test(depth: usize) {
|
||||
let config = FutureMoveConfig {
|
||||
max_depth: depth,
|
||||
start_pruning_at_minus: 4,
|
||||
min_arena_depth_sub: 4,
|
||||
top_k_children: 2,
|
||||
up_to_mod: 4,
|
||||
up_to_minus: 4,
|
||||
max_arena_size: 10_000_000,
|
||||
};
|
||||
let mut fut = FutureMoves::new(Piece::Black, config);
|
||||
|
||||
@ -14,10 +14,10 @@ impl ComplexAgent {
|
||||
pub const fn new(color: Piece) -> Self {
|
||||
const CONFIG: FutureMoveConfig = FutureMoveConfig {
|
||||
max_depth: 10,
|
||||
start_pruning_at_minus: 4,
|
||||
min_arena_depth_sub: 3,
|
||||
top_k_children: 2,
|
||||
up_to_mod: 4,
|
||||
max_arena_size: 100_000_000,
|
||||
up_to_minus: 4,
|
||||
max_arena_size: 10_000_000,
|
||||
};
|
||||
Self {
|
||||
color,
|
||||
|
||||
@ -26,16 +26,17 @@ pub struct FutureMoveConfig {
|
||||
/// Max depth of that we should try and traverse
|
||||
pub max_depth: usize,
|
||||
|
||||
/// start pruning at X depth before self.max_depth is reached
|
||||
/// used for pruning during tree generation before the tree is fully grown
|
||||
pub start_pruning_at_minus: usize,
|
||||
/// subtract this value from FutureMove.max_depth
|
||||
/// and that would be the min depth an arena should fill for
|
||||
/// pruning to happen
|
||||
pub min_arena_depth_sub: usize,
|
||||
|
||||
/// when pruning, keep the top_k # of children
|
||||
pub top_k_children: usize,
|
||||
|
||||
// the lower the value, the more conservative the pruning is, what level to stop pruning at?
|
||||
// a lower value allows more possible paths
|
||||
pub up_to_mod: usize,
|
||||
pub up_to_minus: usize,
|
||||
|
||||
/// Max size of the arena, will not generate more if
|
||||
/// the arena is of that size or bigger
|
||||
@ -71,7 +72,7 @@ impl FutureMoves {
|
||||
// we want to select all nodes that don't have children, or are lazy (need to maybe be regenerated)
|
||||
.filter(|&idx| {
|
||||
let got = &self.arena[idx];
|
||||
got.is_trimmed || got.children.is_empty()
|
||||
!got.is_trimmed && got.winner == Winner::None && !got.tried_children
|
||||
})
|
||||
.filter(|&idx| self.is_connected_to_root(idx))
|
||||
.collect::<Vec<usize>>()
|
||||
@ -84,7 +85,8 @@ impl FutureMoves {
|
||||
.unwrap(),
|
||||
)
|
||||
.for_each(|node_idx| {
|
||||
self.generate_children(node_idx);
|
||||
self.generate_children(node_idx).last();
|
||||
self.arena[node_idx].tried_children = true;
|
||||
});
|
||||
|
||||
self.prune_bad_children();
|
||||
@ -109,14 +111,11 @@ impl FutureMoves {
|
||||
}
|
||||
|
||||
/// Creates children for a parent (`parent`), returns an iterator it's children's indexes
|
||||
fn generate_children(&mut self, parent_idx: usize) -> Option<impl Iterator<Item = usize>> {
|
||||
/// Completely unchecked, the caller should be the one who tests to make sure child generation
|
||||
/// hasn't already been tried on a parent
|
||||
fn generate_children(&mut self, parent_idx: usize) -> impl Iterator<Item = usize> {
|
||||
let parent = &self.arena[parent_idx];
|
||||
|
||||
// early-exit if a winner for the parent already exists
|
||||
if parent.winner != Winner::None {
|
||||
return None;
|
||||
}
|
||||
|
||||
let new_color = !parent.color;
|
||||
|
||||
// use [`Board::all_positions`] here instead of [`Board::possible_moves`]
|
||||
@ -140,7 +139,7 @@ impl FutureMoves {
|
||||
self.set_parent_child(parent_idx, child_idx);
|
||||
}
|
||||
|
||||
Some(new_indices)
|
||||
new_indices
|
||||
}
|
||||
|
||||
/// Given an index from `self.arena`, what depth is it at? 0-indexed
|
||||
@ -346,7 +345,7 @@ impl FutureMoves {
|
||||
if self
|
||||
.config
|
||||
.max_depth
|
||||
.saturating_sub(self.config.start_pruning_at_minus)
|
||||
.saturating_sub(self.config.min_arena_depth_sub)
|
||||
> self.current_depth
|
||||
{
|
||||
return;
|
||||
@ -354,7 +353,7 @@ impl FutureMoves {
|
||||
|
||||
for (depth, indexes) in by_depth {
|
||||
// TODO! maybe update by_depth every iteration or something?
|
||||
if depth > self.current_depth.saturating_sub(self.config.up_to_mod) {
|
||||
if depth > self.current_depth.saturating_sub(self.config.up_to_minus) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -454,9 +453,17 @@ impl FutureMoves {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const FUTURE_MOVES_CONFIG: FutureMoveConfig = FutureMoveConfig {
|
||||
max_depth: 1,
|
||||
min_arena_depth_sub: 2,
|
||||
top_k_children: 2,
|
||||
up_to_minus: 0,
|
||||
max_arena_size: 100,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn prune_tree_test() {
|
||||
let mut futm = FutureMoves::new(Piece::Black, Default::default());
|
||||
let mut futm = FutureMoves::new(Piece::Black, FUTURE_MOVES_CONFIG);
|
||||
|
||||
futm.arena.push(Move {
|
||||
i: 0,
|
||||
@ -469,6 +476,7 @@ mod tests {
|
||||
self_value: 0,
|
||||
color: Piece::Black,
|
||||
is_trimmed: false,
|
||||
tried_children: false,
|
||||
});
|
||||
|
||||
futm.update_root_idx_raw(0);
|
||||
@ -508,7 +516,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn expand_layer_test() {
|
||||
let mut futm = FutureMoves::new(Piece::Black, Default::default());
|
||||
let mut futm = FutureMoves::new(Piece::Black, FUTURE_MOVES_CONFIG);
|
||||
futm.config.max_depth = 1;
|
||||
|
||||
futm.arena.push(Move::new(
|
||||
@ -541,7 +549,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn depth_of_test() {
|
||||
let mut futm = FutureMoves::new(Piece::Black, Default::default());
|
||||
let mut futm = FutureMoves::new(Piece::Black, FUTURE_MOVES_CONFIG);
|
||||
|
||||
futm.arena.push(Move {
|
||||
i: 0,
|
||||
@ -554,6 +562,7 @@ mod tests {
|
||||
self_value: 0,
|
||||
color: Piece::Black,
|
||||
is_trimmed: false,
|
||||
tried_children: false,
|
||||
});
|
||||
|
||||
futm.update_root_idx_raw(0);
|
||||
@ -587,7 +596,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn by_depth_test() {
|
||||
let mut futm = FutureMoves::new(Piece::Black, Default::default());
|
||||
let mut futm = FutureMoves::new(Piece::Black, FUTURE_MOVES_CONFIG);
|
||||
|
||||
futm.arena.push(Move {
|
||||
i: 0,
|
||||
@ -600,6 +609,7 @@ mod tests {
|
||||
self_value: 0,
|
||||
color: Piece::Black,
|
||||
is_trimmed: false,
|
||||
tried_children: false,
|
||||
});
|
||||
|
||||
futm.update_root_idx_raw(0);
|
||||
|
||||
@ -22,6 +22,9 @@ pub struct Move {
|
||||
/// Indices of this Move's Children
|
||||
pub children: Vec<usize>,
|
||||
|
||||
/// Has this [`Move`] already attempted to create children?
|
||||
pub tried_children: bool,
|
||||
|
||||
/// Value of this move (including children)
|
||||
pub value: Option<i128>,
|
||||
|
||||
@ -52,6 +55,7 @@ impl Move {
|
||||
color,
|
||||
is_trimmed: false,
|
||||
self_value: 0,
|
||||
tried_children: false,
|
||||
};
|
||||
m.self_value = m.compute_self_value(agent_color);
|
||||
m
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user