Skip to main content

radiate_alters/mutators/
scramble.rs

1use radiate_core::{AlterContext, AlterResult, Chromosome, Mutate, Rate, random_provider};
2
3/// The [ScrambleMutator] is a simple mutator that scrambles a random section of the [Chromosome].
4///
5/// Because the slice of the chromosome is of random length, with small chromosomes, the scrambling
6/// may not be very effective. This mutator is best used with larger [Chromosome]s.
7#[derive(Debug, Clone)]
8pub struct ScrambleMutator {
9    rate: Rate,
10}
11
12impl ScrambleMutator {
13    pub fn new(rate: impl Into<Rate>) -> Self {
14        let rate = rate.into();
15        ScrambleMutator { rate }
16    }
17}
18
19impl<C: Chromosome> Mutate<C> for ScrambleMutator {
20    fn rate(&self) -> Rate {
21        self.rate.clone()
22    }
23
24    #[inline]
25    fn mutate_chromosome(&mut self, chromosome: &mut C, ctx: &mut AlterContext) -> AlterResult {
26        let mut mutations = 0;
27
28        random_provider::with_rng(|rand| {
29            if rand.bool(ctx.rate()) {
30                let start = rand.range(0..chromosome.len());
31                let end = rand.range(start..chromosome.len());
32                let segment = &mut chromosome.as_mut_slice()[start..end];
33
34                rand.shuffle(segment);
35                mutations += 1;
36            }
37        });
38
39        AlterResult::from(mutations)
40    }
41}