scirs2_optimize/multi_objective/crossover/
mod.rs1use scirs2_core::random::Rng;
6
7pub trait CrossoverOperator {
9 fn crossover(&self, parent1: &[f64], parent2: &[f64]) -> (Vec<f64>, Vec<f64>);
11}
12
13#[derive(Debug, Clone)]
15pub struct SimulatedBinaryCrossover {
16 crossover_probability: f64,
17 distribution_index: f64,
18}
19
20pub type SBX = SimulatedBinaryCrossover;
22
23impl SimulatedBinaryCrossover {
24 pub fn new(distribution_index: f64, crossover_probability: f64) -> Self {
25 Self {
26 crossover_probability,
27 distribution_index,
28 }
29 }
30}
31
32impl CrossoverOperator for SimulatedBinaryCrossover {
33 fn crossover(&self, parent1: &[f64], parent2: &[f64]) -> (Vec<f64>, Vec<f64>) {
34 let mut rng = scirs2_core::random::rng();
35 let n = parent1.len();
36 let mut child1 = vec![0.0; n];
37 let mut child2 = vec![0.0; n];
38
39 if rng.random::<f64>() <= self.crossover_probability {
40 for i in 0..n {
41 if rng.random::<f64>() <= 0.5 {
42 let beta = self.calculate_beta(&mut rng);
43 child1[i] = 0.5 * ((1.0 + beta) * parent1[i] + (1.0 - beta) * parent2[i]);
44 child2[i] = 0.5 * ((1.0 - beta) * parent1[i] + (1.0 + beta) * parent2[i]);
45 } else {
46 child1[i] = parent1[i];
47 child2[i] = parent2[i];
48 }
49 }
50 } else {
51 child1 = parent1.to_vec();
52 child2 = parent2.to_vec();
53 }
54
55 (child1, child2)
56 }
57}
58
59impl SimulatedBinaryCrossover {
60 fn calculate_beta(&self, rng: &mut impl Rng) -> f64 {
61 let u = rng.random::<f64>();
62 if u <= 0.5 {
63 (2.0 * u).powf(1.0 / (self.distribution_index + 1.0))
64 } else {
65 (1.0 / (2.0 * (1.0 - u))).powf(1.0 / (self.distribution_index + 1.0))
66 }
67 }
68}
69
70#[derive(Debug, Clone)]
72pub struct UniformCrossover {
73 crossover_probability: f64,
74}
75
76impl UniformCrossover {
77 pub fn new(crossover_probability: f64) -> Self {
78 Self {
79 crossover_probability,
80 }
81 }
82}
83
84impl CrossoverOperator for UniformCrossover {
85 fn crossover(&self, parent1: &[f64], parent2: &[f64]) -> (Vec<f64>, Vec<f64>) {
86 let mut rng = scirs2_core::random::rng();
87 let n = parent1.len();
88 let mut child1 = vec![0.0; n];
89 let mut child2 = vec![0.0; n];
90
91 if rng.random::<f64>() <= self.crossover_probability {
92 for i in 0..n {
93 if rng.gen_bool(0.5) {
94 child1[i] = parent1[i];
95 child2[i] = parent2[i];
96 } else {
97 child1[i] = parent2[i];
98 child2[i] = parent1[i];
99 }
100 }
101 } else {
102 child1 = parent1.to_vec();
103 child2 = parent2.to_vec();
104 }
105
106 (child1, child2)
107 }
108}