optimize compute_values a TON (reduce depth_of calls)... and other stuff
This commit is contained in:
parent
ad3d31e24a
commit
9a8b674720
@ -1,3 +1,5 @@
|
|||||||
|
use either::Either;
|
||||||
|
|
||||||
use crate::{agent::Agent, board::Board, piece::Piece};
|
use crate::{agent::Agent, board::Board, piece::Piece};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -137,8 +139,20 @@ impl FutureMoves {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn compute_values(&mut self) {
|
fn compute_values(&mut self) {
|
||||||
|
// PERF! doing this filtering here previously visited moves reduces time
|
||||||
|
// spent in `depth_of` from 27.79% -> 2.9%
|
||||||
|
let mut visited = vec![false; self.arena.len()];
|
||||||
|
|
||||||
for depth in (0..=self.current_depth).rev() {
|
for depth in (0..=self.current_depth).rev() {
|
||||||
let nodes_at_depth: Vec<usize> = (0..self.arena.len())
|
let nodes_at_depth: Vec<usize> = (0..self.arena.len())
|
||||||
|
.filter(|&idx| {
|
||||||
|
if visited[idx] {
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
visited[idx] = true;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
})
|
||||||
.filter(|&idx| self.depth_of(idx) == depth)
|
.filter(|&idx| self.depth_of(idx) == depth)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -171,21 +185,18 @@ impl FutureMoves {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn best_move(&self) -> Option<(usize, usize)> {
|
pub fn best_move(&self) -> Option<(usize, usize)> {
|
||||||
let root_nodes = match self.current_root {
|
(match self.current_root {
|
||||||
Some(root) => vec![root],
|
Some(root) => Either::Left(vec![root].into_iter()),
|
||||||
None => self
|
None => Either::Right(
|
||||||
.arena
|
self.arena
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(idx, node)| node.parent.is_none().then_some(idx))
|
.filter_map(|(idx, node)| node.parent.is_none().then_some(idx)),
|
||||||
.collect(),
|
),
|
||||||
};
|
})
|
||||||
|
.map(|idx| &self.arena[idx])
|
||||||
root_nodes
|
.max_by_key(|x| x.value)
|
||||||
.into_iter()
|
.map(|x| (x.i, x.j))
|
||||||
.map(|idx| &self.arena[idx])
|
|
||||||
.max_by_key(|x| x.value)
|
|
||||||
.map(|x| (x.i, x.j))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_root(&mut self, i: usize, j: usize) -> bool {
|
pub fn update_root(&mut self, i: usize, j: usize) -> bool {
|
||||||
@ -209,7 +220,12 @@ impl FutureMoves {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut retain = vec![false; self.arena.len()];
|
let mut retain = vec![false; self.arena.len()];
|
||||||
let mut stack = vec![root];
|
|
||||||
|
// stack is going to be AT MAXIMUM, the size of the array,
|
||||||
|
// so lets just pre-allocate it
|
||||||
|
let mut stack = Vec::with_capacity(self.arena.len());
|
||||||
|
stack.push(root);
|
||||||
|
|
||||||
// traverse children of the current root
|
// traverse children of the current root
|
||||||
while let Some(idx) = stack.pop() {
|
while let Some(idx) = stack.pop() {
|
||||||
retain[idx] = true;
|
retain[idx] = true;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user