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
57
58
59
60
use std::mem::swap;
use mop_blocks::{mp::mphos::Mphos, SolutionMut};
use rand::{thread_rng, Rng};
use genetic_algorithm::operators::mutation::Mutation;
#[derive(Clone, Debug)]
pub struct Swap {
genes_num: usize,
probability: f64,
}
impl Swap {
pub fn new(genes_num: usize, probability: f64) -> Self {
Swap {
genes_num,
probability,
}
}
fn swap_ind_genes<R, T>(solution: &mut SolutionMut<T>, vars_range: usize, rng: &mut R)
where
R: Rng,
{
let var_idx = rng.gen_range(0, vars_range);
let mut first_idx;
let mut second_idx;
loop {
first_idx = rng.gen_range(0, solution.events());
second_idx = rng.gen_range(0, solution.events());
if second_idx > first_idx {
break;
}
}
let (mut a, mut b) = solution.two_events_mut(first_idx, second_idx);
let first_var = a.var_mut(var_idx);
let second_var = b.var_mut(var_idx);
if first_var.is_some() && second_var.is_some() {
swap(first_var.unwrap(), second_var.unwrap());
}
}
}
impl<C, N, V> Mutation<C, N, V> for Swap {
fn mutation(&self, or: &mut Mphos<C, N, V>) {
let vars_range = or.definitions().vars_domains().len();
let mut rng = thread_rng();
or.results_mut().iter_mut().for_each(|mut x| {
if self.probability >= rng.gen_range(0.0, 100.0) {
for _ in 0..self.genes_num {
Self::swap_ind_genes(x.solution_mut(), vars_range, &mut rng);
}
}
});
}
}