radiate_alters/mutators/
invert.rs

1use radiate_core::{AlterResult, Chromosome, Mutate, random_provider};
2
3/// The `InversionMutator` is a simple mutator that inverts a random section of the chromosome.
4///
5/// Because the slice of the chromosome is of random length, with small chromosomes, the inversion
6/// may not be very effective. This mutator is best used with larger chromosomes.
7pub struct InversionMutator {
8    rate: f32,
9}
10
11impl InversionMutator {
12    /// Create a new instance of the `InversionMutator` with the given rate.
13    /// The rate must be between 0.0 and 1.0.
14    pub fn new(rate: f32) -> Self {
15        if !(0.0..=1.0).contains(&rate) {
16            panic!("rate must be between 0.0 and 1.0");
17        }
18
19        InversionMutator { rate }
20    }
21}
22
23impl<C: Chromosome> Mutate<C> for InversionMutator {
24    fn rate(&self) -> f32 {
25        self.rate
26    }
27
28    #[inline]
29    fn mutate_chromosome(&self, chromosome: &mut C, rate: f32) -> AlterResult {
30        let mut mutations = 0;
31
32        if random_provider::random::<f32>() < rate {
33            let start = random_provider::range(0..chromosome.len());
34            let end = random_provider::range(start..chromosome.len());
35
36            chromosome.as_mut()[start..end].reverse();
37            mutations += 1;
38        }
39
40        mutations.into()
41    }
42}