pub mod creep;
pub mod deletion;
pub mod duplication;
pub mod gaussian;
pub mod inversion;
pub mod scramble;
pub mod swap;
pub use creep::Creep;
pub use deletion::SegmentDeletion;
pub use duplication::SegmentDuplication;
pub use gaussian::Gaussian;
pub use inversion::Inversion;
pub use scramble::Scramble;
pub use swap::Swap;
use crate::{
core::{
context::Context, individual::Individual, offspring::Offspring, population::Population,
state::State,
},
fitness::FitnessEvaluator,
operators::{GeneticOperator, common::random_reset_mutate},
random::Randomizable,
};
use rand::{Rng, RngExt};
use std::marker::PhantomData;
trait GeneCollection {}
impl<T> GeneCollection for Vec<T> {}
impl<T> GeneCollection for Box<[T]> {}
impl<T> GeneCollection for [T] {}
impl<T, const N: usize> GeneCollection for [T; N] {}
#[derive(Debug, Default, Clone, Copy)]
pub struct RandomReset<T>(PhantomData<T>);
impl<T> RandomReset<T> {
pub fn new() -> Self {
Self(PhantomData)
}
}
impl<G, F, R, Fe, T, C> GeneticOperator<G, F, Fe, R, C> for RandomReset<T>
where
G: Clone + AsMut<[T]> + GeneCollection,
T: Randomizable<R>,
F: PartialOrd,
R: Rng,
Fe: FitnessEvaluator<G, F>,
{
fn apply(&self, state: &State<G, F>, ctx: &mut Context<Fe, R, C>) -> Offspring<G, F> {
if state.population().len() == 1 {
let individual = unsafe { state.population().as_slice().get_unchecked(0) };
Offspring::Single(Individual::new(random_reset_mutate(
individual.genome(),
ctx.rng(),
)))
} else {
let mut population = Population::with_capacity(state.population().len());
for individual in state.population() {
population.add(Individual::new(random_reset_mutate(
individual.genome(),
ctx.rng(),
)));
}
Offspring::Multiple(population)
}
}
fn transform(&self, state: State<G, F>, ctx: &mut Context<Fe, R, C>) -> Offspring<G, F> {
let population: Population<G, F> = state.into_population().into_iter()
.map(|ind| ind.mutate_genome(|genome| {
let genes = genome.as_mut();
let gene_index = ctx.rng().random_range(0..genes.len());
genes[gene_index] = T::random(ctx.rng());
}))
.collect();
if population.len() == 1 {
Offspring::Single(population.into_iter().next().unwrap())
} else {
Offspring::Multiple(population)
}
}
}
macro_rules! impl_random_reset_for_numbers {
($($t:ty),*) => {
$(
impl<F, R, Fe, C> GeneticOperator<$t, F, Fe, R, C> for RandomReset<$t>
where
F: PartialOrd,
R: Rng,
Fe: FitnessEvaluator<$t, F>,
{
fn apply(&self, state: &State<$t, F>, ctx: &mut Context<Fe, R, C>) -> Offspring<$t, F> {
if state.population().len() == 1 {
Offspring::Single(Individual::new(
<$t>::random(ctx.rng()),
))
} else {
let mut population = Population::with_capacity(state.population().len());
for _ in state.population() {
let new_ind = Individual::new(<$t>::random(ctx.rng()));
population.add(new_ind);
}
Offspring::Multiple(population)
}
}
}
)*
};
}
impl_random_reset_for_numbers!(
u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64, char
);