Skip to main content

radiate_alters/mutators/
invert.rs

1use radiate_core::{AlterResult, Chromosome, Mutate, Rate, Valid, 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.
7#[derive(Debug, Clone)]
8pub struct InversionMutator {
9    rate: Rate,
10}
11
12impl InversionMutator {
13    /// Create a new instance of the [InversionMutator] with the given rate.
14    /// The rate must be between 0.0 and 1.0.
15    pub fn new(rate: impl Into<Rate>) -> Self {
16        let rate = rate.into();
17        if !rate.is_valid() {
18            panic!("Rate is not valid: {:?}", rate);
19        }
20
21        InversionMutator { rate }
22    }
23}
24
25impl<C: Chromosome> Mutate<C> for InversionMutator {
26    fn rate(&self) -> Rate {
27        self.rate.clone()
28    }
29
30    #[inline]
31    fn mutate_chromosome(&self, chromosome: &mut C, rate: f32) -> AlterResult {
32        let mut mutations = 0;
33
34        random_provider::with_rng(|rand| {
35            if rand.bool(rate) {
36                let start = rand.range(0..chromosome.len());
37                let end = rand.range(start..chromosome.len());
38
39                chromosome.as_mut_slice()[start..end].reverse();
40                mutations += 1;
41            }
42        });
43
44        AlterResult::from(mutations)
45    }
46}