radiate_alters/mutators/
arithmetic.rs1use radiate_core::{
2 AlterContext, AlterResult, ArithmeticGene, Chromosome, Mutate, Rate, Valid, random_provider,
3};
4
5#[derive(Debug, Clone)]
13pub struct ArithmeticMutator {
14 rate: Rate,
15}
16
17impl ArithmeticMutator {
18 pub fn new(rate: impl Into<Rate>) -> Self {
21 let rate = rate.into();
22 if !rate.is_valid() {
23 panic!("Rate {rate:?} is not valid. Must be between 0.0 and 1.0",);
24 }
25
26 Self { rate }
27 }
28}
29
30impl<G, C> Mutate<C> for ArithmeticMutator
31where
32 G: ArithmeticGene,
33 C: Chromosome<Gene = G>,
34{
35 fn rate(&self) -> Rate {
36 self.rate.clone()
37 }
38
39 #[inline]
43 fn mutate_chromosome(&mut self, chromosome: &mut C, ctx: &mut AlterContext) -> AlterResult {
44 let mut mutations = 0;
45
46 for gene in chromosome.iter_mut() {
47 if random_provider::bool(ctx.rate()) {
48 let operator = random_provider::range(0..4);
49
50 let new_gene = match operator {
51 0 => gene.clone() + gene.new_instance(),
52 1 => gene.clone() - gene.new_instance(),
53 2 => gene.clone() * gene.new_instance(),
54 3 => gene.clone() / gene.new_instance(),
55 _ => panic!("Invalid operator - this shouldn't happen: {}", operator),
56 };
57
58 *gene = new_gene;
59 mutations += 1;
60 }
61 }
62
63 AlterResult::from(mutations)
64 }
65}