@@ 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)
+ }
+}