~ruther/ctu-fee-eoa

bc75bdd2f28ec25715646009125204487695e223 — Rutherther 11 days ago ada978e
feat: add ArithmeticCrossover for reals
1 files changed, 64 insertions(+), 0 deletions(-)

M codes/eoa_lib/src/crossover.rs
M codes/eoa_lib/src/crossover.rs => codes/eoa_lib/src/crossover.rs +64 -0
@@ 329,3 329,67 @@ where
        Population::from_vec(offsprings)
    }
}

pub struct ArithmeticCrossover<D: Dim, TOutput> {
    _phantom1: PhantomData<D>,
    _phantom2: PhantomData<TOutput>,
}

impl<D, TOutput> ArithmeticCrossover<D, TOutput> {
    pub fn new() -> Self {
        Self {
            _phantom1: PhantomData,
            _phantom2: PhantomData,
        }
    }
}

impl<D, TOutput> Crossover<2> for ArithmeticCrossover<D, TOutput>
where
    D: Dim,
    DefaultAllocator: Allocator<D>
{
    type Chromosome = OVector<f64, D>;
    type Out = TOutput;

    fn crossover(
        &self,
        population: &EvaluatedPopulation<Self::Chromosome, Self::Out>,
        pairs: impl Iterator<Item = ParentPairing<2>>,
        rng: &mut dyn RngCore
    ) -> Population<Self::Chromosome> {
        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)
    }
}