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 rand::{thread_rng, Rng};
use std::cmp::min;
use std::mem::swap;
use std::slice;
use mop_blocks::mp::mphos::Morhos;
use genetic_algorithm::operators::crossover::Crossover;
#[derive(Clone, Debug)]
pub struct MultiPoint {
points: usize,
probability: f64,
}
impl MultiPoint {
pub fn new(points: usize, probability: f64) -> Self {
MultiPoint {
points,
probability,
}
}
fn swap_inds_data<T>(&self, first: &mut [T], second: &mut [T]) {
let slices_len = min(first.len(), second.len());
let step = slices_len / self.points;
for idx in 0..slices_len {
if idx % step == 0 {
swap(&mut first[idx], &mut second[idx]);
}
}
}
}
impl<N, V> Crossover<N, V> for MultiPoint {
fn crossover(&self, or: &mut Morhos<N, V>) {
let mut rng = thread_rng();
for _ in 0..or.len() {
if self.probability < rng.gen_range(0.0, 100.0) {
break;
}
let first_solut_slice = {
let index = rng.gen_range(0, or.len());
let mut opt_result = or.get_mut(index);
let vm = opt_result.solution_mut().variables_mut();
unsafe { slice::from_raw_parts_mut(vm.as_mut_ptr(), vm.len()) }
};
let second_solut_slice = {
let index = rng.gen_range(0, or.len());
let mut opt_result = or.get_mut(index);
let vm = opt_result.solution_mut().variables_mut();
unsafe { slice::from_raw_parts_mut(vm.as_mut_ptr(), vm.len()) }
};
self.swap_inds_data(first_solut_slice, second_solut_slice)
}
}
}