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