From 51a8da0c55de6d386aca5f541e47e514f5c7dda5 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sun, 30 Nov 2025 15:24:20 +0100 Subject: [PATCH] refactor: add possibility to use different logic for obtaining best candidate --- codes/eoa_lib/src/evolution.rs | 77 +++++++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 11 deletions(-) diff --git a/codes/eoa_lib/src/evolution.rs b/codes/eoa_lib/src/evolution.rs index a9e2c5ee06d98b859a85a399cffc1db99e88fd98..849e2ec578bfd0906e2161b51ca2da549a95e670 100644 --- a/codes/eoa_lib/src/evolution.rs +++ b/codes/eoa_lib/src/evolution.rs @@ -100,6 +100,64 @@ pub fn evolution_algorithm &mut TPerturbation, &mut TReplacement ) +) -> Result, Box> { + evolution_algorithm_best_candidate( + initial_population, + parents_count, + fitness, + selection, + pairing, + crossover, + perturbation, + replacement, + better_than, + iterations, + rng, + evolutionary_strategy, + |_, evaluation, last_best_candidate| last_best_candidate.is_none() || + better_than.better_than( + evaluation, + &last_best_candidate.as_ref().unwrap().evaluated_chromosome.evaluation + )) +} + +pub fn evolution_algorithm_best_candidate + , + TFitness: FitnessFunction, + TPairing: Pairing, + TCrossover: Crossover, + TReplacement: Replacement, + TPerturbation: PerturbationOperator>( + initial_population: Population, + parents_count: usize, + fitness: &mut TFitness, + selection: &mut TSelection, + pairing: &mut TPairing, + crossover: &mut TCrossover, + perturbation: &mut TPerturbation, + replacement: &mut TReplacement, + better_than: &impl BetterThanOperator, + // TODO: termination condition + iterations: usize, + rng: &mut dyn RngCore, + mut evolutionary_strategy: impl FnMut( + usize, + &EvolutionStats, + &EvaluatedPopulation, + + &mut TFitness, + &mut TSelection, + &mut TPairing, + &mut TCrossover, + &mut TPerturbation, + &mut TReplacement + ), + // For the statistics, evaluate if a candidate is better. Potential for different functrion than better_than that's used + // for the replacement, selection etc. + better_than_stats: impl Fn(&TChromosome, &TResult, &Option>) -> bool, ) -> Result, Box> { let mut current_evaluation = 0; @@ -110,21 +168,17 @@ pub fn evolution_algorithm fn apply_new_eval( current_evaluation: &mut usize, - better_than: &impl BetterThanOperator, current_iteration: &usize, stats: &mut EvolutionStats, population: &EvaluatedPopulation, - last_best_candidate: &mut Option> + last_best_candidate: &mut Option>, + better_than_stats: &impl Fn(&TChromosome, &TResult, &Option>) -> bool, ) { 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 - ) { + if better_than_stats(chromosome, evaluation, last_best_candidate) { let previous_best = std::mem::replace( last_best_candidate, Some(EvolutionCandidate { @@ -148,11 +202,11 @@ pub fn evolution_algorithm initial_population.evaluate(fitness)?; apply_new_eval( &mut current_evaluation, - better_than, &0, &mut stats, ¤t_population, - &mut last_best_candidate); + &mut last_best_candidate, + &better_than_stats); for iteration in 1..=iterations { // Selection @@ -171,11 +225,12 @@ pub fn evolution_algorithm offsprings.evaluate(fitness)?; apply_new_eval( &mut current_evaluation, - better_than, &iteration, &mut stats, ¤t_population, - &mut last_best_candidate); + &mut last_best_candidate, + &better_than_stats + ); // Replace current_population = replacement.replace(current_population, evaluated_offsprings, better_than, rng);