1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use crate::genetic_algorithm::operators::mutation::Mutation;
use cl_traits::Storage;
use mop_blocks::{gp::MpOrs, Domain, Pct, Solution};
use rand::{rngs::StdRng, Rng, SeedableRng};

#[derive(Clone, Debug)]
pub struct RandomDomainAssignments {
  times: usize,
  probability: Pct,
}

impl RandomDomainAssignments {
  pub fn new(times: usize, probability: Pct) -> Self {
    RandomDomainAssignments { times, probability }
  }
}
impl<D, OR, ORS, S, SS> Mutation<D, MpOrs<ORS, SS>> for RandomDomainAssignments
where
  D: Domain<S>,
  S: Solution,

  ORS: AsMut<[OR]> + Storage<Item = OR>,
  SS: AsMut<[S]> + Storage<Item = S>,
{
  type Error = core::convert::Infallible;

  fn mutation(&self, sd: &D, source: &mut MpOrs<ORS, SS>) -> Result<(), Self::Error> {
    let mut rng = StdRng::from_entropy();
    for mut result in source.iter_mut() {
      if self.probability.is_in_rnd_pbty(&mut rng) {
        for _ in 0..self.times {
          let var_idx = rng.gen_range(0, result.solution().len());
          sd.set_rnd_domain(result.solution_mut(), var_idx, &mut rng);
        }
      }
    }
    Ok(())
  }
}

#[cfg(test)]
mod tests {
  use crate::genetic_algorithm::operators::mutation::{Mutation, RandomDomainAssignments};
  use mop_blocks::{utils::dummy_mp, Pct};

  #[test]
  fn random_domain_assignment() {
    let mut problem = dummy_mp();
    let (defs, source) = problem.parts_mut();
    source.constructor().or_os_iter([2.0, 4.0].iter().cloned(), [1.0, 2.0]);
    let rda = RandomDomainAssignments::new(2, Pct::from_percent(100));
    rda.mutation(defs.domain(), source).unwrap();
    let solution = *source.get(0).unwrap().solution();
    assert_ne!([*solution.get(0).unwrap() as i32, *solution.get(0).unwrap() as i32], [1, 2]);
  }
}