@@ 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<TInput, TResult> {
pub evaluated_chromosome: EvaluatedChromosome<TInput, TResult>,
pub iteration: usize
}
+#[derive(Clone, Debug)]
pub struct EvolutionCandidatePopulation<TInput, TResult> {
pub current_population: EvaluatedPopulation<TInput, TResult>,
pub iteration: usize
}
+#[derive(Clone, Debug)]
pub struct EvolutionStats<TInput, TResult> {
pub best_candidates: Vec<EvolutionCandidate<TInput, TResult>>,
}
+#[derive(Clone, Debug)]
pub struct EvolutionResult<TInput, TResult> {
pub population: EvaluatedPopulation<TInput, TResult>,
pub stats: EvolutionStats<TInput, TResult>,
+ pub best_candidate: EvaluatedChromosome<TInput, TResult>,
pub iterations: usize
}
@@ 79,11 84,76 @@ pub fn evolution_algorithm<TChromosome: Clone, TResult: Clone>(
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::<Const<D>>::new(vec![0; D]);
+ let one_max = OneMax::<Const<D>>::new();
+
+ let mut initializer = RandomInitializer::<Const<D>, BinaryString::<Const<D>>>::new_binary();
+ let population_size = 512;
+
+ let population = Population::from_iterator(
+ initializer.initialize(Const::<D>, 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::<Vec<_>>());
+ println!("{:?}", result.stats.best_candidates
+ .iter()
+ .map(|candidate| candidate.iteration)
+ .collect::<Vec<_>>());
+ 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
+ );
+
+ }
+}