Skip to main content

genetic_algorithm/mutate/
single_gene.rs

1use super::Mutate;
2use crate::genotype::EvolveGenotype;
3use crate::strategy::evolve::{EvolveConfig, EvolveState};
4use crate::strategy::{StrategyAction, StrategyReporter, StrategyState};
5use rand::distributions::{Bernoulli, Distribution};
6use rand::Rng;
7use std::marker::PhantomData;
8use std::time::Instant;
9
10/// Selects [Chromosomes](crate::chromosome::Chromosome) in the
11/// [Population](crate::population::Population) with the provided mutation_probability. Then
12/// mutates the selected chromosomes once, where the [Genotype](crate::genotype::Genotype)
13/// determines whether this is random, relative or scaled.
14#[derive(Debug, Clone)]
15pub struct SingleGene<G: EvolveGenotype> {
16    _phantom: PhantomData<G>,
17    pub mutation_probability: f32,
18    pub mutation_probability_sampler: Bernoulli,
19}
20
21impl<G: EvolveGenotype> Mutate for SingleGene<G> {
22    type Genotype = G;
23
24    fn call<R: Rng, SR: StrategyReporter<Genotype = G>>(
25        &mut self,
26        genotype: &G,
27        state: &mut EvolveState<G>,
28        _config: &EvolveConfig,
29        _reporter: &mut SR,
30        rng: &mut R,
31    ) {
32        let now = Instant::now();
33        for chromosome in state
34            .population
35            .chromosomes
36            .iter_mut()
37            .filter(|c| c.is_offspring())
38        {
39            if self.mutation_probability_sampler.sample(rng) {
40                genotype.mutate_chromosome_genes(1, true, chromosome, rng);
41            }
42        }
43        state.add_duration(StrategyAction::Mutate, now.elapsed());
44    }
45}
46
47impl<G: EvolveGenotype> SingleGene<G> {
48    /// Create a new SingleGene mutation strategy.
49    /// * `mutation_probability` - probability of mutating one gene per chromosome (0.05-0.3 typical)
50    pub fn new(mutation_probability: f32) -> Self {
51        let mutation_probability_sampler = Bernoulli::new(mutation_probability as f64).unwrap();
52        Self {
53            _phantom: PhantomData,
54            mutation_probability,
55            mutation_probability_sampler,
56        }
57    }
58}