radiate_rust/engines/alterers/mutators/
numeric_mutator.rs

1use rand::Rng;
2
3use crate::engines::alterers::mutators::mutate::Mutate;
4use crate::engines::genome::chromosome::Chromosome;
5use crate::engines::genome::genes::gene::NumericGene;
6
7pub struct NumericMutator {
8    rate: f32,
9}
10
11impl NumericMutator {
12    pub fn new(rate: f32) -> Self {
13        Self { rate }
14    }
15}
16
17impl<G, A> Mutate<G, A> for NumericMutator
18where
19    G: NumericGene<G, A>
20{
21    fn mutate_rate(&self) -> f32 {
22        self.rate
23    }
24
25    #[inline]
26    fn mutate_chromosome(&self, chromosome: &mut Chromosome<G, A>, _: i32) -> i32 {
27        let mut random = rand::thread_rng();
28        let mut mutations = 0;
29
30        for gene in chromosome.iter_mut() {
31            if random.gen::<f32>() < self.rate {
32                let new_instance = gene.new_instance();
33                let operator = random.gen_range(0..4);
34                
35                mutations += 1;
36
37                *gene = match operator {
38                    0 => gene.add(&new_instance),
39                    1 => gene.sub(&new_instance),
40                    2 => gene.mul(&new_instance),
41                    3 => gene.div(&new_instance),
42                    _ => panic!("Invalid operator: {}", operator),
43                };
44            }
45        }
46
47        mutations
48    }
49}