1use crate::{Chromosome, Gene, Genotype, Metric, Population, math::indexes, random_provider};
2use crate::{Lineage, LineageUpdate, Rate, metric};
3use radiate_utils::{ToSnakeCase, intern};
4use std::iter::once;
5use std::sync::Arc;
6
7#[macro_export]
8macro_rules! alters {
9 ($($struct_instance:expr),* $(,)?) => {
10 {
11 let mut vec: Vec<Alterer<_>> = Vec::new();
12 $(
13 vec.push($struct_instance.alterer());
14 )*
15 vec
16 }
17 };
18}
19
20pub struct AlterResult(
25 pub usize,
26 pub Option<Vec<Metric>>,
27 pub Option<Vec<LineageUpdate>>,
28);
29
30impl AlterResult {
31 pub fn empty() -> Self {
32 Default::default()
33 }
34
35 pub fn count(&self) -> usize {
36 self.0
37 }
38
39 pub fn update_lineage(&mut self, lineage: impl Into<LineageUpdate>) {
40 let lineage = lineage.into();
41 if let Some(self_lineage) = &mut self.2 {
42 self_lineage.push(lineage);
43 } else {
44 self.2 = Some(vec![lineage]);
45 }
46 }
47
48 pub fn merge(&mut self, other: AlterResult) {
49 let AlterResult(other_count, other_metrics, other_lineage) = other;
50
51 self.0 += other_count;
52 if let Some(metrics) = other_metrics {
53 if let Some(self_metrics) = &mut self.1 {
54 self_metrics.extend(metrics);
55 } else {
56 self.1 = Some(metrics);
57 }
58 }
59
60 if let Some(lineage) = other_lineage {
61 if let Some(self_lineage) = &mut self.2 {
62 self_lineage.extend(lineage);
63 } else {
64 self.2 = Some(lineage);
65 }
66 }
67 }
68}
69
70impl Default for AlterResult {
71 fn default() -> Self {
72 AlterResult(0, None, None)
73 }
74}
75
76impl From<usize> for AlterResult {
77 fn from(value: usize) -> Self {
78 AlterResult(value, None, None)
79 }
80}
81
82impl From<(usize, Vec<Metric>)> for AlterResult {
83 fn from((count, metrics): (usize, Vec<Metric>)) -> Self {
84 AlterResult(count, Some(metrics), None)
85 }
86}
87
88impl From<(usize, Metric)> for AlterResult {
89 fn from((count, metric): (usize, Metric)) -> Self {
90 AlterResult(count, Some(vec![metric]), None)
91 }
92}
93
94impl From<Metric> for AlterResult {
95 fn from(value: Metric) -> Self {
96 AlterResult(1, Some(vec![value]), None)
97 }
98}
99
100impl From<(usize, LineageUpdate)> for AlterResult {
101 fn from((count, lineage): (usize, LineageUpdate)) -> Self {
102 AlterResult(count, None, Some(vec![lineage]))
103 }
104}
105
106impl From<(usize, Vec<Metric>, Vec<LineageUpdate>)> for AlterResult {
107 fn from((count, metrics, lineage): (usize, Vec<Metric>, Vec<LineageUpdate>)) -> Self {
108 AlterResult(count, Some(metrics), Some(lineage))
109 }
110}
111
112impl From<(Vec<Metric>, Vec<LineageUpdate>)> for AlterResult {
113 fn from((metrics, lineage): (Vec<Metric>, Vec<LineageUpdate>)) -> Self {
114 AlterResult(metrics.len(), Some(metrics), Some(lineage))
115 }
116}
117
118#[derive(Clone)]
123pub enum Alterer<C: Chromosome> {
124 Mutate(&'static str, Rate, Arc<dyn Mutate<C>>),
125 Crossover(&'static str, Rate, Arc<dyn Crossover<C>>),
126}
127
128impl<C: Chromosome> Alterer<C> {
129 pub fn name(&self) -> &str {
130 match &self {
131 Alterer::Mutate(name, _, _) => name,
132 Alterer::Crossover(name, _, _) => name,
133 }
134 }
135
136 pub fn rate(&self) -> &Rate {
137 match &self {
138 Alterer::Mutate(_, rate, _) => rate,
139 Alterer::Crossover(_, rate, _) => rate,
140 }
141 }
142
143 #[inline]
144 pub fn alter(
145 &self,
146 population: &mut Population<C>,
147 lineage: &mut Lineage,
148 generation: usize,
149 ) -> Vec<Metric> {
150 match &self {
151 Alterer::Mutate(name, rate, m) => {
152 let (rate_value, rate_metric) = Self::rate_metric(generation, rate, name);
153
154 let timer = std::time::Instant::now();
155 let AlterResult(count, metrics, lineage_events) =
156 m.mutate(population, generation, rate_value);
157
158 if let Some(lineage_events) = lineage_events {
159 lineage.extend(name, lineage_events);
160 }
161
162 let metric = metric!(name, (count, timer.elapsed()));
163
164 match metrics {
165 Some(metrics) => metrics
166 .into_iter()
167 .chain(once(metric))
168 .chain(once(rate_metric))
169 .collect(),
170 None => vec![metric, rate_metric],
171 }
172 }
173 Alterer::Crossover(name, rate, c) => {
174 let (rate_value, rate_metric) = Self::rate_metric(generation, rate, name);
175
176 let timer = std::time::Instant::now();
177 let AlterResult(count, metrics, lineage_events) =
178 c.crossover(population, generation, rate_value);
179
180 if let Some(lineage_events) = lineage_events {
181 lineage.extend(name, lineage_events);
182 }
183
184 let metric = metric!(name, (count, timer.elapsed()));
185
186 match metrics {
187 Some(metrics) => metrics
188 .into_iter()
189 .chain(once(metric))
190 .chain(once(rate_metric))
191 .collect(),
192 None => vec![metric, rate_metric],
193 }
194 }
195 }
196 }
197
198 #[inline]
199 fn rate_metric(generation: usize, rate: &Rate, name: &str) -> (f32, Metric) {
200 let rate_value = rate.value(generation);
201 let metric = metric!(radiate_utils::intern!(format!("{}_rate", name)), rate_value);
202
203 (rate_value, metric)
204 }
205}
206
207const MIN_POPULATION_SIZE: usize = 3;
211const MIN_NUM_PARENTS: usize = 2;
214
215pub trait Crossover<C: Chromosome>: Send + Sync {
227 fn name(&self) -> String {
228 std::any::type_name::<Self>()
229 .split("::")
230 .last()
231 .map(|s| s.to_snake_case())
232 .unwrap()
233 }
234
235 fn rate(&self) -> Rate {
236 Rate::default()
237 }
238
239 fn alterer(self) -> Alterer<C>
240 where
241 Self: Sized + 'static,
242 {
243 Alterer::Crossover(intern!(self.name()), self.rate(), Arc::new(self))
244 }
245
246 #[inline]
247 fn crossover(
248 &self,
249 population: &mut Population<C>,
250 generation: usize,
251 rate: f32,
252 ) -> AlterResult {
253 let mut result = AlterResult::default();
254
255 for i in 0..population.len() {
256 if random_provider::bool(rate) && population.len() > MIN_POPULATION_SIZE {
257 let parent_indexes =
258 indexes::individual_indexes(i, population.len(), MIN_NUM_PARENTS);
259 let cross_result = self.cross(population, &parent_indexes, generation, rate);
260 result.merge(cross_result);
261 }
262 }
263
264 result
265 }
266
267 #[inline]
268 fn cross(
269 &self,
270 population: &mut Population<C>,
271 parent_indexes: &[usize],
272 generation: usize,
273 rate: f32,
274 ) -> AlterResult {
275 let mut result = AlterResult::default();
276
277 if let Some((one, two)) = population.get_pair_mut(parent_indexes[0], parent_indexes[1]) {
278 let mut cross_result = {
279 let geno_one = one.genotype_mut();
280 let geno_two = two.genotype_mut();
281
282 let min_len = std::cmp::min(geno_one.len(), geno_two.len());
283 let chromosome_index = random_provider::range(0..min_len);
284
285 let chrom_one = &mut geno_one[chromosome_index];
286 let chrom_two = &mut geno_two[chromosome_index];
287
288 self.cross_chromosomes(chrom_one, chrom_two, rate)
289 };
290
291 if cross_result.count() > 0 {
292 let parent_lineage = (one.family(), two.family());
293 let parent_ids = (one.id(), two.id());
294 one.invalidate(generation);
295 two.invalidate(generation);
296
297 cross_result.update_lineage((parent_lineage, parent_ids, one.id()));
298 cross_result.update_lineage((parent_lineage, parent_ids, two.id()));
299 result.merge(cross_result);
300 }
301 }
302
303 result
304 }
305
306 #[inline]
307 fn cross_chromosomes(&self, chrom_one: &mut C, chrom_two: &mut C, rate: f32) -> AlterResult {
308 let mut cross_count = 0;
309
310 for i in 0..std::cmp::min(chrom_one.len(), chrom_two.len()) {
311 if random_provider::bool(rate) {
312 let gene_one = chrom_one.get(i);
313 let gene_two = chrom_two.get(i);
314
315 let new_gene_one = gene_one.with_allele(gene_two.allele());
316 let new_gene_two = gene_two.with_allele(gene_one.allele());
317
318 chrom_one.set(i, new_gene_one);
319 chrom_two.set(i, new_gene_two);
320
321 cross_count += 1;
322 }
323 }
324
325 AlterResult::from(cross_count)
326 }
327}
328
329pub trait Mutate<C: Chromosome>: Send + Sync {
330 fn name(&self) -> String {
331 std::any::type_name::<Self>()
332 .split("::")
333 .last()
334 .map(|s| s.to_snake_case())
335 .unwrap()
336 }
337
338 fn rate(&self) -> Rate {
339 Rate::default()
340 }
341
342 fn alterer(self) -> Alterer<C>
343 where
344 Self: Sized + 'static,
345 {
346 Alterer::Mutate(intern!(self.name()), self.rate(), Arc::new(self))
347 }
348
349 #[inline]
350 fn mutate(&self, population: &mut Population<C>, generation: usize, rate: f32) -> AlterResult {
351 let mut result = AlterResult::default();
352
353 for phenotype in population.iter_mut() {
354 let mutate_result = self.mutate_genotype(phenotype.genotype_mut(), rate);
355
356 if mutate_result.count() > 0 {
357 let parent = (phenotype.family(), phenotype.id());
358 phenotype.invalidate(generation);
359 result.update_lineage((parent, phenotype.id()));
360 }
361
362 result.merge(mutate_result);
363 }
364
365 result
366 }
367
368 #[inline]
369 fn mutate_genotype(&self, genotype: &mut Genotype<C>, rate: f32) -> AlterResult {
370 let mut result = AlterResult::default();
371
372 for chromosome in genotype.iter_mut() {
373 let mutate_result = self.mutate_chromosome(chromosome, rate);
374 result.merge(mutate_result);
375 }
376
377 result
378 }
379
380 #[inline]
381 fn mutate_chromosome(&self, chromosome: &mut C, rate: f32) -> AlterResult {
382 let mut count = 0;
383 for gene in chromosome.iter_mut() {
384 if random_provider::bool(rate) {
385 *gene = self.mutate_gene(gene);
386 count += 1;
387 }
388 }
389
390 count.into()
391 }
392
393 #[inline]
394 fn mutate_gene(&self, gene: &C::Gene) -> C::Gene {
395 gene.new_instance()
396 }
397}