From 3c081da6511c161b80e42cbfc735aee68f61298d Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sun, 26 Oct 2025 21:42:47 +0100 Subject: [PATCH] refactor: use evaluated population in selection --- env/src/selection.rs | 66 +++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 37 deletions(-) diff --git a/env/src/selection.rs b/env/src/selection.rs index 8e83c69d0b67c205ab652dced5bc43631d354460..ea03a8746ad6015151cb26b71d19bc03940e4093 100644 --- a/env/src/selection.rs +++ b/env/src/selection.rs @@ -1,14 +1,13 @@ -// pub struct EvaluatedChromosome { -// chromosome: TInput, -// evaluation: TResult, -// } +use rand::{seq::IteratorRandom, Rng, RngCore}; -use rand::{Rng, RngCore}; +use crate::{comparison::BetterThanOperator, replacement::EvaluatedPopulation}; -use crate::comparison::BetterThanOperator; - -pub trait Selection { - fn select(&mut self, count: usize, evaluations: &Vec, better_than: &dyn BetterThanOperator) -> impl Iterator; +pub trait Selection { + fn select(&mut self, + count: usize, + evaluations: &EvaluatedPopulation, + better_than: &dyn BetterThanOperator + ) -> impl Iterator; } pub struct TournamentSelection { @@ -29,8 +28,16 @@ impl TournamentSelection { } } - fn tournament(&mut self, idxs: &mut Vec, evaluations: &Vec, better_than: &dyn BetterThanOperator) -> usize { - idxs.sort_by(|&i, &j| better_than.ordering(&evaluations[i], &evaluations[j])); + fn tournament( + &mut self, + idxs: &mut Vec, + evaluations: &EvaluatedPopulation, + better_than: &dyn BetterThanOperator + ) -> usize { + idxs.sort_by(|&i, &j| better_than.ordering( + &evaluations.population[i].evaluation, + &evaluations.population[j].evaluation) + ); let mut p_selector = self.rng.random_range(0.0..=1.0f64); let p = self.p; @@ -56,34 +63,19 @@ impl TournamentSelection { } } -impl Selection for TournamentSelection { - fn select(&mut self, count: usize, evaluations: &Vec, better_than: &dyn BetterThanOperator) -> impl Iterator { - // 1. Rank - // fn rank(l: &Vec) -> Vec { - // let mut indices = (0..l.len()).collect::>(); - // let mut ranks = vec![0; l.len()]; - - // // argsort... - // indices.sort_by_key(|&i| &l[i]); - - // for (rank, idx) in indices.into_iter().enumerate() { - // ranks[idx] = rank; - // } - - // ranks - // } - - // let ranks = rank(evaluations); - - // 2. Let's choose k random 'count' times - // let mut already_selected = vec![false; evaluations.len()]; - +impl Selection for TournamentSelection { + fn select( + &mut self, + count: usize, + evaluations: &EvaluatedPopulation, + better_than: &dyn BetterThanOperator + ) -> impl Iterator { + // Let's reuse a single vector for the indices let mut k_selected_idxs = vec![0; self.k]; (0..count).map(move |_| { - for selected_idx in k_selected_idxs.iter_mut() { - *selected_idx = self.rng.random_range(0..evaluations.len()); - } - + // Choose k. Do not care if already selected previously. + (0..evaluations.population.len()).choose_multiple_fill(&mut self.rng, &mut k_selected_idxs); + // Tournament between the k self.tournament(&mut k_selected_idxs, evaluations, better_than) }) }