From c47387ebf95401195e25fd03014e113ec8655e23 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Tue, 28 Oct 2025 11:14:47 +0100 Subject: [PATCH] refactor: abstract pairing to n-ary --- codes/eoa_lib/src/crossover.rs | 18 +++++++++--------- codes/eoa_lib/src/evolution.rs | 6 +++--- codes/eoa_lib/src/pairing.rs | 18 ++++++++++-------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/codes/eoa_lib/src/crossover.rs b/codes/eoa_lib/src/crossover.rs index 2a08c7bf1c2bdc696e7921acfb68e95af2be96bc..cdc563201100c42cfb1adb1d29ae5c6b849467b5 100644 --- a/codes/eoa_lib/src/crossover.rs +++ b/codes/eoa_lib/src/crossover.rs @@ -5,14 +5,14 @@ use rand::{Rng, RngCore}; use crate::{binary_string::BinaryString, pairing::ParentPairing, replacement::{EvaluatedPopulation, Population}}; -pub trait Crossover { +pub trait Crossover { type Chromosome; type Out; fn crossover( &self, parents: &EvaluatedPopulation, - pairs: impl Iterator, + pairs: impl Iterator>, rng: &mut dyn RngCore ) -> Population; } @@ -42,7 +42,7 @@ where // TODO: make common functions for ovector that will be used from both BinaryOnePointCrossover and OVectorOnePointCrossover // for not repeating the code. -impl Crossover for BinaryOnePointCrossover +impl Crossover<2> for BinaryOnePointCrossover where D: Dim, DefaultAllocator: Allocator @@ -53,7 +53,7 @@ where fn crossover( &self, population: &EvaluatedPopulation, - pairs: impl Iterator, + pairs: impl Iterator>, rng: &mut dyn RngCore ) -> Population { @@ -66,7 +66,7 @@ where let ( parent1, parent2 - ) = (&population.population[pair.0], &population.population[pair.1]); + ) = (&population.population[pair.x], &population.population[pair.y]); let ( chromosome1, @@ -113,7 +113,7 @@ where } } -impl Crossover for OVectorOnePointCrossover +impl Crossover<2> for OVectorOnePointCrossover where T: Scalar, D: Dim, @@ -125,7 +125,7 @@ where fn crossover( &self, population: &EvaluatedPopulation, - pairs: impl Iterator, + pairs: impl Iterator>, rng: &mut dyn RngCore ) -> Population { @@ -138,7 +138,7 @@ where let ( parent1, parent2 - ) = (&population.population[pair.0], &population.population[pair.1]); + ) = (&population.population[pair.x], &population.population[pair.y]); let ( chromosome1, @@ -157,4 +157,4 @@ where Population::from_vec(offsprings) } -} \ No newline at end of file +} diff --git a/codes/eoa_lib/src/evolution.rs b/codes/eoa_lib/src/evolution.rs index 24d3739520842fa33703e4d2ec83f8f5eb326696..5303dfb137909bc57f3ed9f4961e2bba60dd0b57 100644 --- a/codes/eoa_lib/src/evolution.rs +++ b/codes/eoa_lib/src/evolution.rs @@ -28,13 +28,13 @@ pub struct EvolutionResult { pub iterations: usize } -pub fn evolution_algorithm( +pub fn evolution_algorithm( initial_population: Population, parents_count: usize, fitness: &impl FitnessFunction, selection: &impl Selection, - pairing: &mut impl Pairing, - crossover: &impl Crossover, + pairing: &mut impl Pairing, + crossover: &impl Crossover, perturbation: &impl PerturbationOperator, replacement: &impl Replacement, better_than: &impl BetterThanOperator, diff --git a/codes/eoa_lib/src/pairing.rs b/codes/eoa_lib/src/pairing.rs index 4d71f157c4cb6a2054b3955a9bfb00ebf6d2f238..45ed006e4017167885168970ed18238afc956dd7 100644 --- a/codes/eoa_lib/src/pairing.rs +++ b/codes/eoa_lib/src/pairing.rs @@ -1,10 +1,12 @@ use std::marker::PhantomData; +use nalgebra::{Const, OVector, SVector}; + use crate::replacement::EvaluatedPopulation; -pub type ParentPairing = (usize, usize); +pub type ParentPairing = OVector>; -pub trait Pairing { +pub trait Pairing { type Chromosome; type Out; @@ -12,7 +14,7 @@ pub trait Pairing { &mut self, population: &EvaluatedPopulation, parents: T - ) -> impl Iterator; + ) -> impl Iterator>; } pub struct AdjacentPairing { @@ -29,7 +31,7 @@ impl AdjacentPairing { } } -impl Pairing for AdjacentPairing { +impl Pairing<2> for AdjacentPairing { type Chromosome = TChromosome; type Out = TOutput; @@ -37,7 +39,7 @@ impl Pairing for AdjacentPairing { &mut self, _: &EvaluatedPopulation, parents: T - ) -> impl Iterator { + ) -> impl Iterator> { AdjacentIterator(parents, 0) } } @@ -45,7 +47,7 @@ impl Pairing for AdjacentPairing { pub struct AdjacentIterator>(T, usize); impl> Iterator for AdjacentIterator { - type Item = ParentPairing; + type Item = ParentPairing<2>; fn next(&mut self) -> Option { let first = self.0.next(); @@ -55,10 +57,10 @@ impl> Iterator for AdjacentIterator { // Still two elements left, return them (Some(first), Some(second)) => { self.1 = second; // Save previous - Some((first, second)) + Some(ParentPairing::<2>::new(first, second)) }, // Only one element remaining, return it and the previous one - (Some(first), _) => Some((first, self.1)), + (Some(first), _) => Some(ParentPairing::<2>::new(first, self.1)), (None, Some(_)) => panic!("Iterators cannot return something after they return none."), // No more elements _ => None