@@ 0,0 1,222 @@
+use rand::{seq::IteratorRandom, RngCore};
+
+use crate::{comparison::BetterThanOperator, fitness::FitnessFunction, selection::{Selection, TournamentSelection}};
+
+#[derive(Clone)]
+pub struct Population<TChromosome> {
+ population: Vec<TChromosome>
+}
+
+#[derive(Clone)]
+pub struct EvaluatedChromosome<TChromosome, TResult> {
+ pub chromosome: TChromosome,
+ pub evaluation: TResult,
+}
+
+#[derive(Clone)]
+pub struct EvaluatedPopulation<TChromosome, TResult> {
+ pub population: Vec<EvaluatedChromosome<TChromosome, TResult>>
+}
+
+impl<TChromosome> Population<TChromosome> {
+ pub fn from_vec(vec: Vec<TChromosome>) -> Self {
+ Self {
+ population: vec
+ }
+ }
+
+ pub fn evaluate<T: FitnessFunction<In = TChromosome>>(self, func: &T) -> Result<EvaluatedPopulation<TChromosome, T::Out>, T::Err> {
+ EvaluatedPopulation::evaluate(
+ self.population,
+ func
+ )
+ }
+
+ pub fn iter(&mut self) -> impl Iterator<Item = &TChromosome> {
+ self.population.iter()
+ }
+
+ pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut TChromosome> {
+ self.population.iter_mut()
+ }
+}
+
+impl<TInput, TResult> EvaluatedChromosome<TInput, TResult> {
+ pub fn deconstruct(self) -> (TInput, TResult) {
+ (self.chromosome, self.evaluation)
+ }
+}
+
+impl<TChromosome, TResult> EvaluatedPopulation<TChromosome, TResult> {
+ pub fn new() -> Self {
+ Self {
+ population: vec![]
+ }
+ }
+
+ pub fn evaluate<T: FitnessFunction<In = TChromosome, Out = TResult>>(chromosomes: Vec<TChromosome>, func: &T) -> Result<Self, T::Err> {
+ Ok(EvaluatedPopulation::from_vec(
+ chromosomes.into_iter()
+ .map(|chromosome|
+ Ok(EvaluatedChromosome {
+ evaluation: func.fit(&chromosome)?,
+ chromosome
+ }))
+ .collect::<Result<_, _>>()?))
+ }
+
+ pub fn from_vec(vec: Vec<EvaluatedChromosome<TChromosome, TResult>>) -> Self {
+ Self {
+ population: vec
+ }
+ }
+
+ pub fn best_candidate(&self, better_than: &impl BetterThanOperator<TResult>) -> &EvaluatedChromosome<TChromosome, TResult> {
+ 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<TChromosome, TResult>) {
+ self.population.push(c)
+ }
+
+ pub fn deconstruct(self) -> Vec<EvaluatedChromosome<TChromosome, TResult>> {
+ self.population
+ }
+
+ fn join(&mut self, mut offsprings: EvaluatedPopulation<TChromosome, TResult>) {
+ self.population.append(&mut offsprings.population);
+ }
+
+ pub fn iter(&mut self) -> impl Iterator<Item = &EvaluatedChromosome<TChromosome, TResult>> {
+ self.population.iter()
+ }
+
+ pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut EvaluatedChromosome<TChromosome, TResult>> {
+ self.population.iter_mut()
+ }
+
+}
+
+impl<TChromosome, TResult: Copy> EvaluatedPopulation<TChromosome, TResult> {
+ pub fn evaluations_vec(&self) -> Vec<TResult> {
+ self.population
+ .iter()
+ .map(|individual| individual.evaluation)
+ .collect()
+ }
+}
+
+pub trait Replacement<TChromosome, TResult> {
+ fn replace(
+ &mut self,
+ parents_evaluations: EvaluatedPopulation<TChromosome, TResult>,
+ offsprings_evaluations: EvaluatedPopulation<TChromosome, TResult>,
+ better_than: &dyn BetterThanOperator<TResult>
+ ) -> EvaluatedPopulation<TChromosome, TResult>;
+}
+
+pub struct GenerationalReplacement;
+impl<TInput, TResult> Replacement<TInput, TResult> for GenerationalReplacement {
+ fn replace(
+ &mut self,
+ parents: EvaluatedPopulation<TInput, TResult>,
+ mut offsprings: EvaluatedPopulation<TInput, TResult>,
+ _: &dyn BetterThanOperator<TResult>
+ ) -> EvaluatedPopulation<TInput, TResult> {
+ let count = parents.population.len();
+ if count == offsprings.population.len() {
+ return offsprings;
+ }
+
+ offsprings.join(parents);
+ offsprings.population.truncate(count);
+ // let population = offsprings.deconstruct();
+ // population.truncate(count);
+
+ // EvaluatedPopulation::from_vec(population)
+
+ offsprings
+ }
+}
+
+pub struct RandomReplacement {
+ rng: Box<dyn RngCore>
+}
+
+impl RandomReplacement {
+ pub fn new() -> Self {
+ Self {
+ rng: Box::new(rand::rng())
+ }
+ }
+}
+
+impl<TInput, TResult> Replacement<TInput, TResult> for RandomReplacement {
+ fn replace(
+ &mut self,
+ parents: EvaluatedPopulation<TInput, TResult>,
+ offsprings: EvaluatedPopulation<TInput, TResult>,
+ _: &dyn BetterThanOperator<TResult>
+ ) -> EvaluatedPopulation<TInput, TResult> {
+ let count = parents.population.len();
+
+ EvaluatedPopulation::from_vec(
+ parents.deconstruct()
+ .into_iter()
+ .chain(offsprings.deconstruct().into_iter())
+ .choose_multiple(&mut self.rng, count))
+ }
+}
+
+pub struct TournamentReplacement {
+ selection: TournamentSelection,
+ evaluation_pool: Vec<f64>
+}
+
+impl TournamentReplacement {
+ pub fn new(k: usize, p: f64) -> Self {
+ TournamentReplacement {
+ evaluation_pool: vec![],
+ selection: TournamentSelection::new(
+ k,
+ p,
+ )
+ }
+ }
+}
+
+impl<TInput, TResult: Copy> Replacement<TInput, TResult> for TournamentReplacement {
+ fn replace(
+ &mut self,
+ parents: EvaluatedPopulation<TInput, TResult>,
+ offsprings: EvaluatedPopulation<TInput, TResult>,
+ better_than: &dyn BetterThanOperator<TResult>
+ ) -> EvaluatedPopulation<TInput, TResult> {
+ let count = parents.population.len();
+ let mut population = parents;
+ population.join(offsprings);
+
+ self.evaluation_pool.clear();
+
+ // TODO: use a pool instead of allocating vector every run of this function
+ let selected = self.selection.select(count, &population, better_than)
+ .collect::<Vec<_>>();
+
+ let mut population = population.deconstruct();
+
+ for (write_idx, read_idx) in selected.into_iter().enumerate() {
+ population.swap(read_idx, write_idx);
+ }
+
+ population.truncate(count);
+
+ EvaluatedPopulation::from_vec(population)
+ }
+}