use super::*;
use object_pool::Pool;
use rayon::prelude::*;
mod ga;
pub use ga::*;
mod aga;
pub use aga::*;
pub trait EvolutionParameters {
fn initial_population_size(&self) -> usize;
fn max_population_size(&self) -> usize;
fn validate(&self);
}
pub trait EvolutionAlgorithm<M: EvolutionModel> {
type Parameters: EvolutionParameters;
fn build_evolution(model: M) -> Evolution<Self, M>
where
Self: From<M> + Sized,
{
Evolution::from(Self::from(model))
}
fn model(&self) -> &M;
fn reproduction_parameters(&self) -> (&ReproductionParameters<M>, usize);
fn configure(&mut self, parameters: &Self::Parameters);
fn select_elites(
&self,
population: &Population<M::Individual>,
elites: &mut Vec<M::Individual>,
) {
elites.push(population.fittest().clone())
}
fn initialize_population(
&self,
mut individuals: Vec<M::Individual>,
) -> Population<M::Individual> {
individuals
.par_iter_mut()
.for_each_with(self.model(), |model, individual| model.evaluate(individual));
individuals.retain(|individual| individual.is_valid());
Population::new(individuals)
}
fn prepare_for_next_population(&mut self, population: &Population<M::Individual>);
fn generate_new_population(
&self,
population: &Population<M::Individual>,
offspring: &mut Vec<M::Individual>,
rng_pool: &Pool<M::Rng>,
) {
let (breeding_parameters, offspring_size) = self.reproduction_parameters();
match offspring_size.saturating_sub(offspring.len()) {
0 => {}
1 => {
let mut rng = rng_pool.pull(M::rng);
self.model()
.breed(population, breeding_parameters, &mut *rng);
}
size => {
offspring.par_extend(rayon::iter::repeatn(self.model(), size).map_init(
|| rng_pool.pull(M::rng),
|rng, model| model.breed(population, breeding_parameters, &mut *rng),
));
}
}
}
#[inline]
fn replace_population(
&self,
population: &mut Population<M::Individual>,
offspring: &mut Vec<M::Individual>,
) {
population.replace(offspring);
}
}