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