mod elite;
mod tournament;
mod wrapper;
pub use self::elite::Elite as SelectElite;
pub use self::tournament::Tournament as SelectTournament;
pub use self::wrapper::Wrapper as SelectWrapper;
use crate::chromosome::Chromosome;
use crate::genotype::{EvolveGenotype, Genotype};
use crate::strategy::evolve::{EvolveConfig, EvolveState};
use crate::strategy::StrategyReporter;
use rand::prelude::*;
pub type SelectGenotype<S> = <S as Select>::Genotype;
pub type SelectEvolveState<S> = EvolveState<<S as Select>::Genotype>;
pub type SelectAllele<S> = <<S as Select>::Genotype as Genotype>::Allele;
pub trait Select: Clone + Send + Sync + std::fmt::Debug {
type Genotype: EvolveGenotype;
fn call<R: Rng, SR: StrategyReporter<Genotype = Self::Genotype>>(
&mut self,
genotype: &Self::Genotype,
state: &mut EvolveState<Self::Genotype>,
config: &EvolveConfig,
reporter: &mut SR,
rng: &mut R,
);
fn extract_elite_chromosomes(
&self,
state: &mut EvolveState<Self::Genotype>,
config: &EvolveConfig,
elitism_rate: f32,
) -> Vec<Chromosome<SelectAllele<Self>>> {
let elitism_size = ((state.population.size() as f32 * elitism_rate).ceil() as usize)
.min(state.population.size());
let mut elite_chromosomes: Vec<Chromosome<SelectAllele<Self>>> =
Vec::with_capacity(elitism_size);
for index in state
.population
.best_chromosome_indices(elitism_size, config.fitness_ordering)
.into_iter()
.rev()
{
let chromosome = state.population.chromosomes.swap_remove(index);
elite_chromosomes.push(chromosome);
}
elite_chromosomes
}
fn parent_and_offspring_survival_sizes(
&self,
parents_size: usize,
offspring_size: usize,
target_size: usize,
replacement_rate: f32,
) -> (usize, usize) {
let target_offspring_size =
((target_size as f32 * replacement_rate).ceil() as usize).min(target_size);
let target_parents_size = target_size - target_offspring_size;
let mut new_offspring_size = target_offspring_size.min(offspring_size);
let mut new_parents_size = target_parents_size.min(parents_size);
let target_shortage =
(target_size as isize - new_offspring_size as isize - new_parents_size as isize).max(0)
as usize;
new_offspring_size += target_shortage.min(offspring_size - new_offspring_size);
let target_shortage =
(target_size as isize - new_offspring_size as isize - new_parents_size as isize).max(0)
as usize;
new_parents_size += target_shortage.min(parents_size - new_parents_size);
(new_parents_size, new_offspring_size)
}
}
#[derive(Clone, Debug)]
pub struct SelectEvent(pub String);