M codes/eoa_lib/src/evolution.rs => codes/eoa_lib/src/evolution.rs +49 -49
@@ 72,53 72,53 @@ pub fn evolution_algorithm
best_candidates: vec![]
};
- fn get_fitness_fn<TChromosome: Clone, TResult: Clone>(
+ fn apply_new_eval<TChromosome: Clone, TResult: Clone>(
current_evaluation: &mut usize,
better_than: &impl BetterThanOperator<TResult>,
fitness: &impl FitnessFunction<In = TChromosome, Out = TResult>,
current_iteration: &usize,
stats: &mut EvolutionStats<TChromosome, TResult>,
+ population: &EvaluatedPopulation<TChromosome, TResult>,
last_best_candidate: &mut Option<EvolutionCandidate<TChromosome, TResult>>
- ) -> impl FnMut(&TChromosome) -> TResult {
- |chromosome| {
- let evaluation = fitness.fit(chromosome).unwrap();
-
- if last_best_candidate.is_none() ||
- better_than.better_than(
- &evaluation,
- &last_best_candidate.as_ref().unwrap().evaluated_chromosome.evaluation
- ) {
- let previous_best = std::mem::replace(
- last_best_candidate,
- Some(EvolutionCandidate {
- evaluated_chromosome: EvaluatedChromosome {
- chromosome: chromosome.clone(),
- evaluation: evaluation.clone(),
- },
- evaluation: *current_evaluation,
- iteration: *current_iteration
- }));
-
- if let Some(previous_best) = previous_best {
- stats.best_candidates.push(previous_best);
- }
- }
- *current_evaluation += 1;
-
- evaluation
- }
+ ) {
+ for individual in population.iter() {
+ let evaluation = &individual.evaluation;
+ let chromosome = &individual.chromosome;
+
+ if last_best_candidate.is_none() ||
+ better_than.better_than(
+ evaluation,
+ &last_best_candidate.as_ref().unwrap().evaluated_chromosome.evaluation
+ ) {
+ let previous_best = std::mem::replace(
+ last_best_candidate,
+ Some(EvolutionCandidate {
+ evaluated_chromosome: EvaluatedChromosome {
+ chromosome: chromosome.clone(),
+ evaluation: evaluation.clone(),
+ },
+ evaluation: *current_evaluation,
+ iteration: *current_iteration
+ }));
+
+ if let Some(previous_best) = previous_best {
+ stats.best_candidates.push(previous_best);
+ }
+ }
+ *current_evaluation += 1;
+ }
}
- let mut current_population = initial_population.evaluate_mut(
- &mut get_fitness_fn(
- &mut current_evaluation,
- better_than,
- fitness,
- &0,
- &mut stats,
- &mut last_best_candidate
- )
- );
+ let mut current_population =
+ initial_population.evaluate(fitness)?;
+ apply_new_eval(
+ &mut current_evaluation,
+ better_than,
+ fitness,
+ &0,
+ &mut stats,
+ ¤t_population,
+ &mut last_best_candidate);
for iteration in 1..=iterations {
// Selection
@@ 133,16 133,16 @@ pub fn evolution_algorithm
perturbation.perturb(offspring, rng);
}
- let evaluated_offsprings = offsprings.evaluate_mut(
- &mut get_fitness_fn(
- &mut current_evaluation,
- better_than,
- fitness,
- &iteration,
- &mut stats,
- &mut last_best_candidate
- )
- );
+ let evaluated_offsprings =
+ offsprings.evaluate(fitness)?;
+ apply_new_eval(
+ &mut current_evaluation,
+ better_than,
+ fitness,
+ &iteration,
+ &mut stats,
+ ¤t_population,
+ &mut last_best_candidate);
// Replace
current_population = replacement.replace(current_population, evaluated_offsprings, better_than, rng);
M codes/eoa_lib/src/fitness/mod.rs => codes/eoa_lib/src/fitness/mod.rs +13 -2
@@ 2,7 2,7 @@ use std::{convert::Infallible, error::Error, marker::PhantomData};
use nalgebra::{allocator::Allocator, DefaultAllocator, Dim, OVector};
-use crate::binary_string::{BinaryString, BinaryStringConversionError};
+use crate::{binary_string::{BinaryString, BinaryStringConversionError}, population::EvaluatedChromosome};
pub mod labs;
pub mod one_max;
@@ 15,7 15,18 @@ pub trait FitnessFunction {
type Out;
type Err: Error + 'static;
- fn fit(self: &Self, inp: &Self::In) -> Result<Self::Out, Self::Err>;
+ fn fit(&self, inp: &Self::In) -> Result<Self::Out, Self::Err>;
+
+ fn fit_population(&self, inp: Vec<Self::In>) -> Result<Vec<EvaluatedChromosome<Self::In, Self::Out>>, Self::Err> {
+ inp
+ .into_iter()
+ .map(|chromosome|
+ Ok(EvaluatedChromosome {
+ evaluation: self.fit(&chromosome)?,
+ chromosome,
+ }))
+ .collect::<Result<Vec<_>, _>>()
+ }
}
pub struct BinaryFitnessWrapper<D, DString, TFitness>
M codes/eoa_lib/src/population.rs => codes/eoa_lib/src/population.rs +2 -26
@@ 34,13 34,6 @@ impl<TChromosome> Population<TChromosome> {
)
}
- pub fn evaluate_mut<TResult>(self, func: &mut dyn FnMut(&TChromosome) -> TResult) -> EvaluatedPopulation<TChromosome, TResult> {
- EvaluatedPopulation::evaluate_mut(
- self.population,
- func
- )
- }
-
pub fn into_iter(self) -> impl Iterator<Item = TChromosome> {
self.population.into_iter()
}
@@ 68,25 61,8 @@ impl<TChromosome, TResult> EvaluatedPopulation<TChromosome, TResult> {
}
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 evaluate_mut(chromosomes: Vec<TChromosome>, func: &mut dyn FnMut(&TChromosome) -> TResult) -> Self {
- EvaluatedPopulation::from_vec(
- chromosomes.into_iter()
- .map(|chromosome|
- EvaluatedChromosome {
- evaluation: func(&chromosome),
- chromosome
- })
- .collect::<Vec<_>>())
+ func.fit_population(chromosomes)
+ .map(|population| Self::from_vec(population))
}
pub fn from_vec(vec: Vec<EvaluatedChromosome<TChromosome, TResult>>) -> Self {