From 4ef3d988cfcefcd624d43dff088b456af928cefa Mon Sep 17 00:00:00 2001 From: Rutherther Date: Mon, 27 Oct 2025 20:51:11 +0100 Subject: [PATCH] tests: add simple test for evolution on one_max --- codes/eoa_lib/src/evolution.rs | 70 ++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/codes/eoa_lib/src/evolution.rs b/codes/eoa_lib/src/evolution.rs index ab28f13de1efa63a4c0becefbf5ad01d698b15be..7a54e14585b7e417a6d96ed9f01c09a28a31f3ac 100644 --- a/codes/eoa_lib/src/evolution.rs +++ b/codes/eoa_lib/src/evolution.rs @@ -2,23 +2,28 @@ use std::error::Error; use crate::{comparison::BetterThanOperator, crossover::Crossover, fitness::FitnessFunction, pairing::Pairing, perturbation::PerturbationOperator, replacement::{EvaluatedChromosome, EvaluatedPopulation, Population, Replacement}, selection::Selection}; +#[derive(Clone, Debug)] pub struct EvolutionCandidate { pub evaluated_chromosome: EvaluatedChromosome, pub iteration: usize } +#[derive(Clone, Debug)] pub struct EvolutionCandidatePopulation { pub current_population: EvaluatedPopulation, pub iteration: usize } +#[derive(Clone, Debug)] pub struct EvolutionStats { pub best_candidates: Vec>, } +#[derive(Clone, Debug)] pub struct EvolutionResult { pub population: EvaluatedPopulation, pub stats: EvolutionStats, + pub best_candidate: EvaluatedChromosome, pub iterations: usize } @@ -79,11 +84,76 @@ pub fn evolution_algorithm( current_population = replacement.replace(current_population, evaluated_offsprings, better_than); } + let best_candidate = last_best_candidate.evaluated_chromosome.clone(); stats.best_candidates.push(last_best_candidate); Ok(EvolutionResult { population: current_population, + best_candidate, stats, iterations }) } + +#[cfg(test)] +pub mod tests { + use nalgebra::Const; + + use crate::{binary_string::BinaryString, comparison::MinimizingOperator, crossover::BinaryOnePointCrossover, fitness::one_max::OneMax, initializer::{Initializer, RandomInitializer}, pairing::AdjacentPairing, perturbation::{BinaryStringBitPerturbation, MutationPerturbation}, replacement::{BestReplacement, Population, TournamentReplacement}, selection::{BestSelection, TournamentSelection}}; + + use super::evolution_algorithm; + + #[test] + pub fn test_one_max() { + const D: usize = 512; + let optimum = BinaryString::>::new(vec![0; D]); + let one_max = OneMax::>::new(); + + let mut initializer = RandomInitializer::, BinaryString::>>::new_binary(); + let population_size = 512; + + let population = Population::from_iterator( + initializer.initialize(Const::, population_size) + ); + + let result = evolution_algorithm( + population, + population_size / 4, + &one_max, + // TODO: tournament should somehow accept sorting? + // TODO: deterministic and nondeterministic tournament ordering + &mut TournamentSelection::new(3, 0.8), + &mut AdjacentPairing::new(), + &mut BinaryOnePointCrossover::new(), + &mut MutationPerturbation::new( + Box::new(BinaryStringBitPerturbation::new(0.05)), + 0.1), + &mut BestReplacement::new(), + &MinimizingOperator, + 1000 + ).unwrap(); + + println!("{:?}", result.stats.best_candidates + .iter() + .map(|candidate| candidate.evaluated_chromosome.evaluation) + .collect::>()); + println!("{:?}", result.stats.best_candidates + .iter() + .map(|candidate| candidate.iteration) + .collect::>()); + println!("{:?}", result.population.best_candidate(&MinimizingOperator)); + println!("{:?}", result.best_candidate); + // println!("{:?}", res); + + assert_eq!( + result.best_candidate.evaluation, + 0 + ); + + assert_eq!( + result.best_candidate.chromosome, + optimum + ); + + } +}