From 03a0e7a6502a93d9b582b2d04f65bff49a1a885b Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sun, 30 Nov 2025 16:04:15 +0100 Subject: [PATCH] feat: Add BlendCrossover for reals --- codes/eoa_lib/src/crossover.rs | 62 ++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/codes/eoa_lib/src/crossover.rs b/codes/eoa_lib/src/crossover.rs index b195352f922063b8bd1453afcdbea0628a08036a..59d7cf0fd8b7489d019a157939b3a6480ba11ec5 100644 --- a/codes/eoa_lib/src/crossover.rs +++ b/codes/eoa_lib/src/crossover.rs @@ -393,3 +393,65 @@ where Population::from_vec(offsprings) } } + + +pub struct BlendCrossover { + alpha: f64, + _phantom1: PhantomData, + _phantom2: PhantomData, +} + +impl BlendCrossover { + pub fn new(alpha: f64) -> Self { + BlendCrossover { + alpha, + _phantom1: PhantomData, + _phantom2: PhantomData, + } + } +} + +impl Crossover<2> for BlendCrossover +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 min = first.min(second); + let max = first.max(second); + + let interval = (min - self.alpha * (max - min))..=(max + self.alpha * (max - min)); + + rng.random_range(interval) + } + )); + } + + Population::from_vec(offsprings) + } +}