use radiate_core::{
AlterContext, AlterResult, ArithmeticGene, Chromosome, Crossover, Rate, Valid, random_provider,
};
pub struct MeanCrossover {
rate: Rate,
}
impl MeanCrossover {
pub fn new(rate: impl Into<Rate>) -> Self {
let rate = rate.into();
if !rate.is_valid() {
panic!("Rate {rate:?} is not valid. Must be between 0.0 and 1.0",);
}
MeanCrossover { rate }
}
}
impl<C: Chromosome> Crossover<C> for MeanCrossover
where
C::Gene: ArithmeticGene,
{
fn rate(&self) -> Rate {
self.rate.clone()
}
#[inline]
fn cross_chromosomes(
&self,
chrom_one: &mut C,
chrom_two: &mut C,
ctx: &mut AlterContext,
) -> AlterResult {
let mut count = 0;
random_provider::with_rng(|rand| {
for (gene_one, gene_two) in chrom_one.iter_mut().zip(chrom_two.iter()) {
if rand.bool(ctx.rate()) {
*gene_one = gene_one.mean(gene_two);
count += 1;
}
}
});
count.into()
}
}