Skip to main content

radiate_alters/mutators/
scramble.rs

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