1use crate::{
2 Chromosome, Gene, Genotype, Metric, Population, ToSnakeCase, indexes, labels, random_provider,
3};
4
5#[macro_export]
6macro_rules! alters {
7 ($($struct_instance:expr),* $(,)?) => {
8 {
9 let mut vec: Vec<Box<dyn Alter<_>>> = Vec::new();
10 $(
11 vec.push(Box::new($struct_instance.alterer()));
12 )*
13 vec
14 }
15 };
16}
17
18pub trait Alter<C: Chromosome>: Send + Sync {
39 fn alter(&self, population: &mut Population<C>, generation: usize) -> Vec<Metric>;
40}
41
42#[derive(Default)]
47pub struct AlterResult(pub usize, pub Option<Vec<Metric>>);
48
49impl AlterResult {
50 pub fn count(&self) -> usize {
51 self.0
52 }
53
54 pub fn metrics(&self) -> Option<&Vec<Metric>> {
55 self.1.as_ref()
56 }
57
58 pub fn merge(&mut self, other: AlterResult) {
59 let AlterResult(other_count, other_metrics) = other;
60
61 self.0 += other_count;
62 if let Some(metrics) = other_metrics {
63 if let Some(self_metrics) = &mut self.1 {
64 self_metrics.extend(metrics);
65 } else {
66 self.1 = Some(metrics);
67 }
68 }
69 }
70}
71
72impl Into<AlterResult> for usize {
73 fn into(self) -> AlterResult {
74 AlterResult(self, None)
75 }
76}
77
78impl Into<AlterResult> for (usize, Vec<Metric>) {
79 fn into(self) -> AlterResult {
80 AlterResult(self.0, Some(self.1))
81 }
82}
83
84impl Into<AlterResult> for (usize, Metric) {
85 fn into(self) -> AlterResult {
86 AlterResult(self.0, Some(vec![self.1]))
87 }
88}
89
90pub enum AlterAction<C: Chromosome> {
94 Mutate(&'static str, f32, Box<dyn Mutate<C>>),
95 Crossover(&'static str, f32, Box<dyn Crossover<C>>),
96}
97
98impl<C: Chromosome> Alter<C> for AlterAction<C> {
99 fn alter(&self, population: &mut Population<C>, generation: usize) -> Vec<Metric> {
100 match &self {
101 AlterAction::Mutate(name, rate, m) => {
102 m.update(generation);
103
104 let timer = std::time::Instant::now();
105 let AlterResult(count, metrics) = m.mutate(population, generation, *rate);
106 let metric = Metric::new(name)
107 .with_labels(labels![
108 "operator" => "mutation",
109 "type" => "alter",
110 "rate" => rate.to_string(),
111 ])
112 .upsert(count)
113 .upsert(timer.elapsed());
114
115 match metrics {
116 Some(metrics) => metrics
117 .into_iter()
118 .map(|m| {
119 m.with_labels(labels![
120 "operator" => "mutation",
121 "type" => "alter",
122 "rate" => rate.to_string(),
123 ])
124 })
125 .chain(std::iter::once(metric))
126 .collect(),
127 None => vec![metric],
128 }
129 }
130 AlterAction::Crossover(name, rate, c) => {
131 c.update(generation);
132
133 let timer = std::time::Instant::now();
134 let AlterResult(count, metrics) = c.crossover(population, generation, *rate);
135 let metric = Metric::new(name)
136 .with_labels(labels![
137 "operator" => "crossover",
138 "type" => "alter",
139 "rate" => rate.to_string(),
140 ])
141 .upsert(count)
142 .upsert(timer.elapsed());
143
144 match metrics {
145 Some(metrics) => metrics
146 .into_iter()
147 .map(|m| {
148 m.with_labels(labels![
149 "operator" => "crossover",
150 "type" => "alter",
151 "rate" => rate.to_string(),
152 ])
153 })
154 .chain(std::iter::once(metric))
155 .collect(),
156 None => vec![metric],
157 }
158 }
159 }
160 }
161}
162
163pub trait Crossover<C: Chromosome>: Send + Sync {
175 fn name(&self) -> String {
176 std::any::type_name::<Self>()
177 .split("::")
178 .last()
179 .map(|s| s.to_snake_case())
180 .unwrap()
181 }
182
183 fn update(&self, _: usize) {}
184
185 fn rate(&self) -> f32 {
186 1.0
187 }
188
189 fn alterer(self) -> AlterAction<C>
190 where
191 Self: Sized + 'static,
192 {
193 AlterAction::Crossover(self.name().leak(), self.rate(), Box::new(self))
194 }
195
196 #[inline]
197 fn crossover(
198 &self,
199 population: &mut Population<C>,
200 generation: usize,
201 rate: f32,
202 ) -> AlterResult {
203 let mut result = AlterResult::default();
204
205 for i in 0..population.len() {
206 if random_provider::random::<f32>() < rate && population.len() > 3 {
207 let parent_indexes = indexes::individual_indexes(i, population.len(), 2);
208 let cross_result = self.cross(population, &parent_indexes, generation, rate);
209 result.merge(cross_result);
210 }
211 }
212
213 result
214 }
215
216 #[inline]
217 fn cross(
218 &self,
219 population: &mut Population<C>,
220 parent_indexes: &[usize],
221 generation: usize,
222 rate: f32,
223 ) -> AlterResult {
224 let mut result = AlterResult::default();
225
226 if let Some((one, two)) = population.get_pair_mut(parent_indexes[0], parent_indexes[1]) {
227 let cross_result = {
228 let geno_one = one.genotype_mut();
229 let geno_two = two.genotype_mut();
230
231 let min_len = std::cmp::min(geno_one.len(), geno_two.len());
232 let chromosome_index = random_provider::range(0..min_len);
233
234 let chrom_one = &mut geno_one[chromosome_index];
235 let chrom_two = &mut geno_two[chromosome_index];
236
237 self.cross_chromosomes(chrom_one, chrom_two, rate)
238 };
239
240 if cross_result.count() > 0 {
241 one.invalidate(generation);
242 two.invalidate(generation);
243 result.merge(cross_result);
244 }
245 }
246
247 result
248 }
249
250 #[inline]
251 fn cross_chromosomes(&self, chrom_one: &mut C, chrom_two: &mut C, rate: f32) -> AlterResult {
252 let mut cross_count = 0;
253
254 for i in 0..std::cmp::min(chrom_one.len(), chrom_two.len()) {
255 if random_provider::random::<f32>() < rate {
256 let gene_one = chrom_one.get(i);
257 let gene_two = chrom_two.get(i);
258
259 let new_gene_one = gene_one.with_allele(gene_two.allele());
260 let new_gene_two = gene_two.with_allele(gene_one.allele());
261
262 chrom_one.set(i, new_gene_one);
263 chrom_two.set(i, new_gene_two);
264
265 cross_count += 1;
266 }
267 }
268
269 cross_count.into()
270 }
271}
272
273pub trait Mutate<C: Chromosome>: Send + Sync {
274 fn name(&self) -> String {
275 std::any::type_name::<Self>()
276 .split("::")
277 .last()
278 .map(|s| s.to_snake_case())
279 .unwrap()
280 }
281
282 fn update(&self, _: usize) {}
283
284 fn rate(&self) -> f32 {
285 1.0
286 }
287
288 fn alterer(self) -> AlterAction<C>
289 where
290 Self: Sized + 'static,
291 {
292 AlterAction::Mutate(self.name().leak(), self.rate(), Box::new(self))
293 }
294
295 #[inline]
296 fn mutate(&self, population: &mut Population<C>, generation: usize, rate: f32) -> AlterResult {
297 let mut result = AlterResult::default();
298
299 for phenotype in population.iter_mut() {
300 let mutate_result = self.mutate_genotype(phenotype.genotype_mut(), rate);
301
302 if mutate_result.count() > 0 {
303 phenotype.invalidate(generation);
304 }
305
306 result.merge(mutate_result);
307 }
308
309 result
310 }
311
312 #[inline]
313 fn mutate_genotype(&self, genotype: &mut Genotype<C>, rate: f32) -> AlterResult {
314 let mut result = AlterResult::default();
315
316 for chromosome in genotype.iter_mut() {
317 let mutate_result = self.mutate_chromosome(chromosome, rate);
318 result.merge(mutate_result);
319 }
320
321 result
322 }
323
324 #[inline]
325 fn mutate_chromosome(&self, chromosome: &mut C, rate: f32) -> AlterResult {
326 let mut count = 0;
327 for gene in chromosome.iter_mut() {
328 if random_provider::random::<f32>() < rate {
329 *gene = self.mutate_gene(gene);
330 count += 1;
331 }
332 }
333
334 count.into()
335 }
336
337 #[inline]
338 fn mutate_gene(&self, gene: &C::Gene) -> C::Gene {
339 gene.new_instance()
340 }
341}