1use rand::Rng;
6use serde::{Deserialize, Serialize};
7
8pub trait Genome: Clone + Send + Sync + Sized {
13 type Phenotype;
15
16 fn random<R: Rng>(rng: &mut R) -> Self;
18
19 fn mutate<R: Rng>(&mut self, rng: &mut R, rate: f64);
25
26 fn crossover<R: Rng>(&self, other: &Self, rng: &mut R) -> Self;
32
33 fn to_phenotype(&self) -> Self::Phenotype;
35
36 fn distance(&self, _other: &Self) -> f64 {
40 0.0
41 }
42}
43
44#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
46pub struct BehaviorDescriptor {
47 pub values: Vec<f64>,
49}
50
51impl BehaviorDescriptor {
52 pub fn new(values: Vec<f64>) -> Self {
54 Self { values }
55 }
56
57 pub fn distance(&self, other: &Self) -> f64 {
59 self.values
60 .iter()
61 .zip(other.values.iter())
62 .map(|(a, b)| (a - b).powi(2))
63 .sum::<f64>()
64 .sqrt()
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn test_behavior_distance() {
74 let a = BehaviorDescriptor::new(vec![0.0, 0.0]);
75 let b = BehaviorDescriptor::new(vec![3.0, 4.0]);
76 assert!((a.distance(&b) - 5.0).abs() < 1e-10);
77 }
78
79 #[test]
80 fn test_behavior_distance_same_point() {
81 let a = BehaviorDescriptor::new(vec![1.0, 2.0, 3.0]);
82 let b = BehaviorDescriptor::new(vec![1.0, 2.0, 3.0]);
83 assert!((a.distance(&b)).abs() < 1e-10);
84 }
85
86 #[test]
87 fn test_behavior_distance_single_dimension() {
88 let a = BehaviorDescriptor::new(vec![0.0]);
89 let b = BehaviorDescriptor::new(vec![5.0]);
90 assert!((a.distance(&b) - 5.0).abs() < 1e-10);
91 }
92
93 #[test]
94 fn test_behavior_descriptor_new() {
95 let desc = BehaviorDescriptor::new(vec![1.0, 2.0, 3.0]);
96 assert_eq!(desc.values, vec![1.0, 2.0, 3.0]);
97 }
98}