use crate::{comparison::BetterThanOperator, fitness::FitnessFunction}; #[derive(Clone, Debug)] pub struct Population { population: Vec } #[derive(Clone, Debug)] pub struct EvaluatedChromosome { pub chromosome: TChromosome, pub evaluation: TResult, } #[derive(Clone, Debug)] pub struct EvaluatedPopulation { pub population: Vec> } impl Population { pub fn from_vec(vec: Vec) -> Self { Self { population: vec } } pub fn from_iterator(iter: impl Iterator) -> Self { Self::from_vec(iter.collect()) } pub fn evaluate>(self, func: &T) -> Result, T::Err> { EvaluatedPopulation::evaluate( self.population, func ) } pub fn evaluate_mut(self, func: &mut dyn FnMut(&TChromosome) -> TResult) -> EvaluatedPopulation { EvaluatedPopulation::evaluate_mut( self.population, func ) } pub fn into_iter(self) -> impl Iterator { self.population.into_iter() } pub fn iter(&self) -> impl Iterator { self.population.iter() } pub fn iter_mut(&mut self) -> impl Iterator { self.population.iter_mut() } } impl EvaluatedChromosome { pub fn deconstruct(self) -> (TInput, TResult) { (self.chromosome, self.evaluation) } } impl EvaluatedPopulation { pub fn new() -> Self { Self { population: vec![] } } pub fn evaluate>(chromosomes: Vec, func: &T) -> Result { Ok(EvaluatedPopulation::from_vec( chromosomes.into_iter() .map(|chromosome| Ok(EvaluatedChromosome { evaluation: func.fit(&chromosome)?, chromosome })) .collect::>()?)) } pub fn evaluate_mut(chromosomes: Vec, func: &mut dyn FnMut(&TChromosome) -> TResult) -> Self { EvaluatedPopulation::from_vec( chromosomes.into_iter() .map(|chromosome| EvaluatedChromosome { evaluation: func(&chromosome), chromosome }) .collect::>()) } pub fn from_vec(vec: Vec>) -> Self { Self { population: vec } } pub fn best_candidate(&self, better_than: &impl BetterThanOperator) -> &EvaluatedChromosome { let mut best_so_far = &self.population[0]; for individual in self.population.iter().skip(1) { if better_than.better_than(&individual.evaluation, &best_so_far.evaluation) { best_so_far = individual; } } best_so_far } pub fn add(&mut self, c: EvaluatedChromosome) { self.population.push(c) } pub fn deconstruct(self) -> Vec> { self.population } pub fn join(&mut self, mut offsprings: EvaluatedPopulation) { self.population.append(&mut offsprings.population); } pub fn iter(&self) -> impl Iterator> { self.population.iter() } pub fn iter_mut(&mut self) -> impl Iterator> { self.population.iter_mut() } } impl EvaluatedPopulation { pub fn evaluations_vec(&self) -> Vec { self.population .iter() .map(|individual| individual.evaluation) .collect() } }