use rand::distributions::Distribution;
use rand::distributions::Standard;
use rand::Rng;
use crate::genotype::Distance;
use crate::random::Random;
use super::Gene;
use super::Genotype;
impl<G, const GENE_COUNT: usize> Genotype for [G; GENE_COUNT]
where
G: Gene,
{
type Gene = G;
}
impl<G, const GENE_COUNT: usize> Distance for [G; GENE_COUNT]
where
G: Gene + PartialEq,
{
#[allow(clippy::cast_precision_loss, clippy::float_arithmetic, clippy::as_conversions)]
fn distance(&self, other: &Self) -> f32 {
self.iter()
.zip(other)
.fold(0.0, |distance, (l, r)| distance + if l == r { 0. } else { 1. })
/ GENE_COUNT as f32
}
}
impl<G, const GENE_COUNT: usize> Random for [G; GENE_COUNT]
where
Standard: Distribution<G>,
{
fn random<RNG>(rng: &mut RNG) -> Self
where
RNG: Rng,
Self: Sized,
{
core::array::from_fn(|_| rng.gen())
}
}
#[cfg(test)]
mod tests {
use crate::genotype::Distance;
#[test]
fn distance() {
let arr1 = [1, 2, 3];
let arr2 = [3, 2, 1];
assert!((arr1.distance(&arr2) - 0.66666).abs() < 0.0001)
}
}