From bc75bdd2f28ec25715646009125204487695e223 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sun, 30 Nov 2025 16:04:07 +0100 Subject: [PATCH] feat: add ArithmeticCrossover for reals --- codes/eoa_lib/src/crossover.rs | 64 ++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/codes/eoa_lib/src/crossover.rs b/codes/eoa_lib/src/crossover.rs index 947de702128670e4edf58f645c5875aeebac198f..b195352f922063b8bd1453afcdbea0628a08036a 100644 --- a/codes/eoa_lib/src/crossover.rs +++ b/codes/eoa_lib/src/crossover.rs @@ -329,3 +329,67 @@ where Population::from_vec(offsprings) } } + +pub struct ArithmeticCrossover { + _phantom1: PhantomData, + _phantom2: PhantomData, +} + +impl ArithmeticCrossover { + pub fn new() -> Self { + Self { + _phantom1: PhantomData, + _phantom2: PhantomData, + } + } +} + +impl Crossover<2> for ArithmeticCrossover +where + D: Dim, + DefaultAllocator: Allocator +{ + type Chromosome = OVector; + type Out = TOutput; + + fn crossover( + &self, + population: &EvaluatedPopulation, + pairs: impl Iterator>, + rng: &mut dyn RngCore + ) -> Population { + let mut offsprings = Vec::new(); + + for pair in pairs { + let ( + parent1, + parent2 + ) = (&population.population[pair.x], &population.population[pair.y]); + + let ( + chromosome1, + chromosome2 + ) = (&parent1.chromosome, &parent2.chromosome); + + offsprings.push( + chromosome1.zip_map( + &chromosome2, + |first, second| { + let alpha = rng.random_range(0.0..=1.0); + alpha * first + (1.0 - alpha) * second + } + )); + + offsprings.push( + chromosome1.zip_map( + &chromosome2, + |first, second| { + let alpha = rng.random_range(0.0..=1.0); + alpha * second + (1.0 - alpha) * first + } + )); + } + + Population::from_vec(offsprings) + } +}