use rand::Rng;
use rand_distr::{Distribution, Standard};
use crate::gen::species::SpeciesId;
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum Crossover {
Fixed(Vec<f64>),
Adaptive,
}
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum Mutation {
Fixed(Vec<f64>),
Adaptive,
}
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
pub enum Survival {
TopProportion(f64),
SpeciesTopProportion(f64), }
impl Distribution<Survival> for Standard {
fn sample<R: Rng + ?Sized>(&self, r: &mut R) -> Survival {
match r.gen_range(0..2) {
0 => Survival::TopProportion(r.gen_range(0.0..0.9)),
_ => Survival::SpeciesTopProportion(r.gen_range(0.0..0.9)),
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd)]
pub enum Selection {
Sus,
Roulette,
}
impl Distribution<Selection> for Standard {
fn sample<R: Rng + ?Sized>(&self, r: &mut R) -> Selection {
match r.gen_range(0..2) {
0 => Selection::Sus,
_ => Selection::Roulette,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
pub enum Niching {
None,
SharedFitness(f64), SpeciesSharedFitness, }
impl Distribution<Niching> for Standard {
fn sample<R: Rng + ?Sized>(&self, r: &mut R) -> Niching {
match r.gen_range(0..3) {
0 => Niching::None,
1 => Niching::SharedFitness(r.gen_range(0.0..100.0)), _ => Niching::SpeciesSharedFitness,
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd)]
pub enum Species {
None,
TargetNumber(SpeciesId), }
impl Distribution<Species> for Standard {
fn sample<R: Rng + ?Sized>(&self, r: &mut R) -> Species {
match r.gen_range(0..2) {
0 => Species::None,
_ => Species::TargetNumber(r.gen_range(1..10)), }
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd)]
pub enum Stagnation {
None,
OneShotAfter(usize),
ContinuousAfter(usize),
}
impl Distribution<Stagnation> for Standard {
fn sample<R: Rng + ?Sized>(&self, r: &mut R) -> Stagnation {
match r.gen_range(0..2) {
0 => Stagnation::None,
1 => Stagnation::OneShotAfter(r.gen_range(1..1000)),
_ => Stagnation::ContinuousAfter(r.gen_range(1..1000)),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
pub enum StagnationCondition {
Default,
Epsilon(f64),
}
impl Distribution<StagnationCondition> for Standard {
fn sample<R: Rng + ?Sized>(&self, _: &mut R) -> StagnationCondition {
StagnationCondition::Default
}
}
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
pub enum Replacement {
ReplaceChildren(f64),
}
impl Distribution<Replacement> for Standard {
fn sample<R: Rng + ?Sized>(&self, r: &mut R) -> Replacement {
Replacement::ReplaceChildren(r.gen())
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd)]
pub enum Duplicates {
DisallowDuplicates, AllowDuplicates,
}
impl Distribution<Duplicates> for Standard {
fn sample<R: Rng + ?Sized>(&self, r: &mut R) -> Duplicates {
match r.gen_range(0..1) {
0 => Duplicates::DisallowDuplicates,
_ => Duplicates::AllowDuplicates,
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct Cfg {
pub pop_size: usize,
pub crossover: Crossover,
pub mutation: Mutation, pub survival: Survival,
pub selection: Selection,
pub niching: Niching,
pub species: Species,
pub stagnation: Stagnation,
pub stagnation_condition: StagnationCondition,
pub replacement: Replacement,
pub duplicates: Duplicates,
pub par_fitness: bool, pub par_dist: bool, }
impl Cfg {
#[must_use]
pub fn new(pop_size: usize) -> Self {
Self {
pop_size,
crossover: Crossover::Adaptive,
mutation: Mutation::Adaptive,
survival: Survival::TopProportion(0.2),
selection: Selection::Sus,
niching: Niching::None,
species: Species::None,
stagnation: Stagnation::None,
stagnation_condition: StagnationCondition::Default,
replacement: Replacement::ReplaceChildren(0.2),
duplicates: Duplicates::DisallowDuplicates,
par_fitness: false,
par_dist: false,
}
}
#[must_use]
pub fn with_pop_size(self, pop_size: usize) -> Self {
Self { pop_size, ..self }
}
#[must_use]
pub fn with_crossover(self, crossover: Crossover) -> Self {
Self { crossover, ..self }
}
#[must_use]
pub fn with_mutation(self, mutation: Mutation) -> Self {
Self { mutation, ..self }
}
#[must_use]
pub fn with_survival(self, survival: Survival) -> Self {
Self { survival, ..self }
}
#[must_use]
pub fn with_selection(self, selection: Selection) -> Self {
Self { selection, ..self }
}
#[must_use]
pub fn with_niching(self, niching: Niching) -> Self {
Self { niching, ..self }
}
#[must_use]
pub fn with_species(self, species: Species) -> Self {
Self { species, ..self }
}
#[must_use]
pub fn with_stagnation(self, stagnation: Stagnation) -> Self {
Self { stagnation, ..self }
}
#[must_use]
pub fn with_stagnation_condition(self, stagnation_condition: StagnationCondition) -> Self {
Self { stagnation_condition, ..self }
}
#[must_use]
pub fn with_replacement(self, replacement: Replacement) -> Self {
Self { replacement, ..self }
}
#[must_use]
pub fn with_duplicates(self, duplicates: Duplicates) -> Self {
Self { duplicates, ..self }
}
#[must_use]
pub fn with_par_fitness(self, par_fitness: bool) -> Self {
Self { par_fitness, ..self }
}
#[must_use]
pub fn with_par_dist(self, par_dist: bool) -> Self {
Self { par_dist, ..self }
}
}