radiate_alters/mutators/
invert.rs

1use radiate_core::{AlterResult, Chromosome, Mutate, Rate, 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        InversionMutator { rate }
18    }
19}
20
21impl<C: Chromosome> Mutate<C> for InversionMutator {
22    fn rate(&self) -> Rate {
23        self.rate.clone()
24    }
25
26    #[inline]
27    fn mutate_chromosome(&self, chromosome: &mut C, rate: f32) -> AlterResult {
28        let mut mutations = 0;
29
30        random_provider::with_rng(|rand| {
31            if rand.bool(rate) {
32                let start = rand.range(0..chromosome.len());
33                let end = rand.range(start..chromosome.len());
34
35                chromosome.genes_mut()[start..end].reverse();
36                mutations += 1;
37            }
38        });
39
40        AlterResult::from(mutations)
41    }
42}