radiate_core/genome/chromosomes/
int.rs1use super::{
2 Chromosome,
3 gene::{ArithmeticGene, Gene, Valid},
4};
5use crate::{chromosomes::BoundedGene, random_provider};
6use radiate_utils::Integer;
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9use std::{
10 fmt::Debug,
11 ops::{Add, Div, Mul, Range, Sub},
12};
13
14#[derive(Clone, PartialEq, Default, Debug)]
47#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
48pub struct IntGene<T: Integer> {
49 allele: T,
50 value_range: Range<T>,
51 bounds: Range<T>,
52}
53
54impl<T: Integer> IntGene<T> {
55 pub fn new(allele: T, value_range: Range<T>, bounds: Range<T>) -> Self {
57 IntGene {
58 allele,
59 value_range,
60 bounds,
61 }
62 }
63}
64
65impl<T: Integer> Gene for IntGene<T> {
67 type Allele = T;
68
69 fn allele(&self) -> &T {
70 &self.allele
71 }
72
73 fn allele_mut(&mut self) -> &mut T {
74 &mut self.allele
75 }
76
77 fn new_instance(&self) -> IntGene<T> {
79 IntGene {
80 allele: random_provider::range(self.value_range.clone()),
81 value_range: self.value_range.clone(),
82 bounds: self.bounds.clone(),
83 }
84 }
85
86 fn with_allele(&self, allele: &T) -> IntGene<T> {
87 IntGene {
88 allele: *allele,
89 value_range: self.value_range.clone(),
90 bounds: self.bounds.clone(),
91 }
92 }
93}
94
95impl<T: Integer> Valid for IntGene<T> {
100 fn is_valid(&self) -> bool {
101 self.allele >= self.bounds.start && self.allele <= self.bounds.end
102 }
103}
104
105impl<T: Integer> BoundedGene for IntGene<T> {
108 fn min(&self) -> &Self::Allele {
109 &self.value_range.start
110 }
111
112 fn max(&self) -> &Self::Allele {
113 &self.value_range.end
114 }
115
116 fn bounds(&self) -> (&Self::Allele, &Self::Allele) {
117 (&self.bounds.start, &self.bounds.end)
118 }
119}
120
121impl<T: Integer> ArithmeticGene for IntGene<T> {
125 fn mean(&self, other: &IntGene<T>) -> IntGene<T> {
126 IntGene {
127 allele: (self.allele.safe_add(other.allele)).safe_div(T::TWO),
128 value_range: self.value_range.clone(),
129 bounds: self.bounds.clone(),
130 }
131 }
132}
133
134impl<T: Integer> Add for IntGene<T> {
135 type Output = IntGene<T>;
136
137 fn add(self, other: IntGene<T>) -> IntGene<T> {
138 IntGene {
139 allele: self
140 .allele
141 .safe_add(other.allele)
142 .safe_clamp(self.bounds.start, self.bounds.end),
143 value_range: self.value_range.clone(),
144 bounds: self.bounds.clone(),
145 }
146 }
147}
148
149impl<T: Integer> Sub for IntGene<T> {
150 type Output = IntGene<T>;
151
152 fn sub(self, other: IntGene<T>) -> IntGene<T> {
153 IntGene {
154 allele: self
155 .allele
156 .safe_sub(other.allele)
157 .safe_clamp(self.bounds.start, self.bounds.end),
158 value_range: self.value_range.clone(),
159 bounds: self.bounds.clone(),
160 }
161 }
162}
163
164impl<T: Integer> Mul for IntGene<T> {
165 type Output = IntGene<T>;
166
167 fn mul(self, other: IntGene<T>) -> IntGene<T> {
168 IntGene {
169 allele: self
170 .allele
171 .safe_mul(other.allele)
172 .safe_clamp(self.bounds.start, self.bounds.end),
173 value_range: self.value_range.clone(),
174 bounds: self.bounds.clone(),
175 }
176 }
177}
178
179impl<T: Integer> Div for IntGene<T> {
180 type Output = IntGene<T>;
181
182 fn div(self, other: IntGene<T>) -> IntGene<T> {
183 IntGene {
184 allele: self
185 .allele
186 .safe_div(other.allele)
187 .safe_clamp(self.bounds.start, self.bounds.end),
188 value_range: self.value_range.clone(),
189 bounds: self.bounds.clone(),
190 }
191 }
192}
193
194impl<T: Integer> From<T> for IntGene<T> {
195 fn from(allele: T) -> Self {
196 IntGene {
197 allele,
198 value_range: T::MIN..T::MAX,
199 bounds: T::MIN..T::MAX,
200 }
201 }
202}
203
204impl<T: Integer> From<Range<T>> for IntGene<T> {
205 fn from(range: Range<T>) -> Self {
206 let (min, max) = (range.start, range.end);
207
208 IntGene {
209 allele: random_provider::range(range),
210 value_range: min..max,
211 bounds: min..max,
212 }
213 }
214}
215
216impl<T: Integer> From<(Range<T>, Range<T>)> for IntGene<T> {
217 fn from((range, bounds): (Range<T>, Range<T>)) -> Self {
218 IntGene {
219 allele: random_provider::range(range.clone()),
220 value_range: range,
221 bounds,
222 }
223 }
224}
225
226impl<T: Integer> std::fmt::Display for IntGene<T> {
227 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
228 write!(f, "{}", self.allele)
229 }
230}
231
232#[derive(Clone, PartialEq, Default)]
258#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
259pub struct IntChromosome<I: Integer> {
260 genes: Vec<IntGene<I>>,
261}
262
263impl<I: Integer> IntChromosome<I> {
264 pub fn new(genes: Vec<IntGene<I>>) -> Self {
266 IntChromosome { genes }
267 }
268}
269
270impl<I: Integer> Chromosome for IntChromosome<I> {
271 type Gene = IntGene<I>;
272
273 fn as_slice(&self) -> &[Self::Gene] {
274 &self.genes
275 }
276
277 fn as_mut_slice(&mut self) -> &mut [Self::Gene] {
278 &mut self.genes
279 }
280}
281
282impl<T: Integer> Valid for IntChromosome<T> {
283 fn is_valid(&self) -> bool {
284 self.genes.iter().all(|gene| gene.is_valid())
285 }
286}
287
288impl<T: Integer> From<IntGene<T>> for IntChromosome<T> {
289 fn from(gene: IntGene<T>) -> Self {
290 IntChromosome { genes: vec![gene] }
291 }
292}
293
294impl<T: Integer> From<Vec<IntGene<T>>> for IntChromosome<T> {
295 fn from(genes: Vec<IntGene<T>>) -> Self {
296 IntChromosome { genes }
297 }
298}
299
300impl<T: Integer> From<(usize, Range<T>)> for IntChromosome<T> {
301 fn from((size, range): (usize, Range<T>)) -> Self {
302 IntChromosome {
303 genes: (0..size).map(|_| IntGene::from(range.clone())).collect(),
304 }
305 }
306}
307
308impl<T: Integer> From<(usize, Range<T>, Range<T>)> for IntChromosome<T> {
309 fn from((size, range, bounds): (usize, Range<T>, Range<T>)) -> Self {
310 IntChromosome {
311 genes: (0..size)
312 .map(|_| IntGene::from((range.clone(), bounds.clone())))
313 .collect(),
314 }
315 }
316}
317
318impl<T: Integer> From<Vec<T>> for IntChromosome<T> {
319 fn from(alleles: Vec<T>) -> Self {
320 IntChromosome {
321 genes: alleles.into_iter().map(IntGene::from).collect(),
322 }
323 }
324}
325
326impl<T: Integer> FromIterator<IntGene<T>> for IntChromosome<T> {
327 fn from_iter<I: IntoIterator<Item = IntGene<T>>>(iter: I) -> Self {
328 IntChromosome {
329 genes: iter.into_iter().collect(),
330 }
331 }
332}
333
334impl<T: Integer> IntoIterator for IntChromosome<T> {
335 type Item = IntGene<T>;
336 type IntoIter = std::vec::IntoIter<IntGene<T>>;
337
338 fn into_iter(self) -> Self::IntoIter {
339 self.genes.into_iter()
340 }
341}
342
343impl<T: Integer> Debug for IntChromosome<T> {
344 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
345 write!(f, "{:?}", self.genes)
346 }
347}
348
349#[cfg(test)]
350mod tests {
351 use super::*;
352
353 #[test]
354 fn test_new() {
355 let gene = IntGene::from(0..10);
356 assert!(gene.allele >= 0 && gene.allele <= 10);
357 }
358
359 #[test]
360 fn test_new_instance() {
361 let gene = IntGene::from(0..10);
362 let new_gene = gene.new_instance();
363 assert!(new_gene.allele >= 0 && new_gene.allele <= 10);
364 }
365
366 #[test]
367 fn test_from_allele() {
368 let gene = IntGene::from(5);
369 let new_gene = gene.with_allele(&5);
370 assert_eq!(new_gene.allele, 5);
371 }
372
373 #[test]
374 fn test_is_valid() {
375 let gene = IntGene::from(0..10);
376 assert!(gene.is_valid());
377 }
378
379 #[test]
380 fn test_bounds() {
381 let gene_one = IntGene::from((0..10, 0..10));
382 let gene_two = IntGene::from((0..10, -100..100));
383
384 let (one_min, one_max) = gene_one.bounds();
385 let (two_min, two_max) = gene_two.bounds();
386
387 assert_eq!(*one_min, 0);
388 assert_eq!(*one_max, 10);
389 assert_eq!(*two_min, -100);
390 assert_eq!(*two_max, 100);
391 assert_eq!(gene_one.min(), &0);
392 assert_eq!(gene_one.max(), &10);
393 assert_eq!(gene_two.min(), &0);
394 assert_eq!(gene_two.max(), &10);
395 assert!(gene_one.is_valid());
396 assert!(gene_two.is_valid());
397 }
398
399 #[test]
400 fn test_mean() {
401 let gene = IntGene::from(5);
402 let other = IntGene::from(5);
403 let new_gene = gene.mean(&other);
404 assert_eq!(new_gene.allele, 5);
405 }
406
407 #[test]
408 fn test_int_arithmetic_doesnt_overflow() {
409 let gene = IntGene::<u8>::from(8_u8);
410 let other = IntGene::<u8>::from(8_u8);
411 let sixteen = IntGene::<u8>::from(16_u8);
412
413 assert_eq!((gene.clone() + other.clone()).allele, 16);
414 assert_eq!((gene.clone() - sixteen.clone()).allele, 0);
415 assert_eq!((gene.clone() * other.clone()).allele, 64);
416
417 let zero = IntGene::<u8>::from(0_u8);
418 assert_eq!((gene.clone() / zero.clone()).allele, 8);
419 assert_eq!((gene.clone() / other.clone()).allele, 1);
420
421 let max = IntGene::<u8>::from(u8::MAX);
422 assert_eq!((max.clone() + other.clone()).allele, u8::MAX);
423 assert_eq!((zero.clone() - other.clone()).allele, 0);
424
425 let i_eight = IntGene::<i8>::from(8_i8);
426 let i_other = IntGene::<i8>::from(8_i8);
427 let i_sixteen = IntGene::<i8>::from(16_i8);
428
429 assert_eq!((i_eight.clone() + i_other.clone()).allele, 16);
430 assert_eq!((i_eight.clone() - i_sixteen.clone()).allele, -8);
431 assert_eq!((i_eight.clone() * i_other.clone()).allele, 64);
432 }
433
434 #[test]
435 fn test_int_clamp_arithmetic_clamping() {
436 let gene = IntGene::new(5, 5..10, 0..10);
437 let other = IntGene::new(5, 8..10, 0..10);
438 let really_big = IntGene::new(100000, 0..10, 0..10);
439
440 let add = gene.clone() + other.clone();
441 let sub = gene.clone() - other.clone();
442 let mul = gene.clone() * other.clone();
443 let div = gene.clone() / other.clone();
444
445 let really_big_add = gene.clone() + really_big.clone();
446 let really_big_sub = gene.clone() - really_big.clone();
447 let really_big_mul = gene.clone() * really_big.clone();
448 let really_big_div = gene.clone() / really_big.clone();
449
450 assert_eq!(add.allele, 10);
451 assert_eq!(sub.allele, 0);
452 assert_eq!(mul.allele, 10);
453 assert_eq!(div.allele, 1);
454
455 assert_eq!(really_big_add.allele, 10);
456 assert_eq!(really_big_sub.allele, 0);
457 assert_eq!(really_big_mul.allele, 10);
458 assert_eq!(really_big_div.allele, 0);
459 }
460
461 #[test]
462 fn test_into() {
463 let gene: IntGene<i32> = 5.into();
464 assert_eq!(gene.allele, 5);
465 }
466
467 #[test]
468 fn test_chromosome_from_range() {
469 let chromosome = IntChromosome::from((10, 0..10));
470 assert_eq!(chromosome.genes.len(), 10);
471 for gene in &chromosome.genes {
472 assert!(gene.allele >= 0 && gene.allele <= 10);
473 }
474 }
475
476 #[test]
477 fn test_chromosome_from_range_with_bounds() {
478 let chromosome = IntChromosome::from((10, 0..10, -10..10));
479
480 assert_eq!(chromosome.genes.len(), 10);
481 for gene in &chromosome.genes {
482 assert!(gene.allele >= 0 && gene.allele <= 10);
483 assert_eq!(*gene.bounds().0, -10);
484 assert_eq!(*gene.bounds().1, 10);
485 }
486 }
487
488 #[test]
489 fn test_chromosome_from_alleles() {
490 let alleles = vec![1, 2, 3, 4, 5];
491 let chromosome = IntChromosome::from(alleles.clone());
492
493 assert_eq!(chromosome.genes.len(), 5);
494 for (i, gene) in chromosome.genes.iter().enumerate() {
495 assert_eq!(gene.allele, alleles[i]);
496 }
497 }
498
499 #[test]
500 fn test_gene_arithmetic() {
501 let gene_one = IntGene::from(5);
502 let gene_two = IntGene::from(5);
503 let zero_gene = IntGene::from(0);
504
505 let add = gene_one.clone() + gene_two.clone();
506 let sub = gene_one.clone() - gene_two.clone();
507 let mul = gene_one.clone() * gene_two.clone();
508 let div = gene_one.clone() / gene_two.clone();
509 let div_zero = gene_one.clone() / zero_gene.clone();
510 let mean = gene_one.mean(&gene_two);
511
512 assert_eq!(add.allele, 10);
513 assert_eq!(sub.allele, 0);
514 assert_eq!(mul.allele, 25);
515 assert_eq!(div.allele, 1);
516 assert_eq!(div_zero.allele, 5);
517 assert_eq!(mean.allele, 5);
518 }
519
520 #[test]
521 #[cfg(feature = "serde")]
522 fn test_int_gene_serialization() {
523 let gene = IntGene::from(-5_i32..5_i32);
524
525 assert!(gene.is_valid());
526
527 let serialized = serde_json::to_string(&gene).expect("Failed to serialize IntGene");
528 let deserialized: IntGene<i32> =
529 serde_json::from_str(&serialized).expect("Failed to deserialize IntGene");
530
531 let chromosome = IntChromosome::from((10, 0..10, -10..10));
532 let serialized_chromosome =
533 serde_json::to_string(&chromosome).expect("Failed to serialize IntChromosome");
534 let deserialized_chromosome: IntChromosome<i32> =
535 serde_json::from_str(&serialized_chromosome)
536 .expect("Failed to deserialize IntChromosome");
537
538 assert_eq!(gene, deserialized);
539 assert_eq!(chromosome, deserialized_chromosome);
540 }
541}