From ec2647b8696dad6844a448d29af485b862ec6841 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sat, 1 Nov 2025 12:43:48 +0100 Subject: [PATCH] feat(lib): add roulette wheel selection --- codes/eoa_lib/src/selection.rs | 50 +++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/codes/eoa_lib/src/selection.rs b/codes/eoa_lib/src/selection.rs index 0c497f445f2e07f5bbc476e3ab80c3ea2fa68c70..ca1e4f6f8527afea0f831b15c1cb7885bf1df69b 100644 --- a/codes/eoa_lib/src/selection.rs +++ b/codes/eoa_lib/src/selection.rs @@ -1,5 +1,7 @@ +use nalgebra::{Dyn, OVector, Scalar, U1}; use rand::{seq::IteratorRandom, Rng, RngCore}; -use std::fmt::Debug; +use rand_distr::uniform::{SampleRange, SampleUniform}; +use std::{cmp::Ordering, fmt::Debug, ops::{AddAssign, Sub}}; use crate::{comparison::BetterThanOperator, replacement::EvaluatedPopulation}; @@ -108,3 +110,49 @@ impl Selection for Tou }) } } + + +pub struct RouletteWheelSelection; +impl RouletteWheelSelection { + pub fn new() -> Self { + Self + } +} + +impl> + Selection for RouletteWheelSelection +{ + fn select( + &self, + count: usize, + evaluations: &EvaluatedPopulation, + _: &dyn BetterThanOperator, + rng: &mut dyn RngCore + ) -> impl Iterator { + let zero: TResult = Default::default(); + let max = evaluations.iter() + .map(|i| i.evaluation) + .max_by(|a, b| + a.partial_cmp(b).unwrap_or(Ordering::Less)) + .unwrap(); + let summed = evaluations.iter().scan( + zero, + |acc, individual| { + let subtracted: TResult = max - individual.evaluation; + *acc += subtracted; + Some(*acc) + }) + .collect::>(); + let max = summed.last().unwrap().clone(); + + (0..count).map(move |_| { + let rand = rng.random_range(zero..=max); + + (0..summed.len()) + .filter(|&i| summed[i] > rand) + .next() + .unwrap_or(summed.len() - 1) + }) + } +}