use rand::prelude::*;
use std::ops::{Deref, DerefMut};
pub trait Individual: Clone + PartialEq + Send + Sync {
fn fitness(&self) -> f64;
#[inline]
fn is_valid(&self) -> bool {
self.fitness().is_finite()
}
}
pub trait RandomIndividual<A>: Individual {
fn new_random<R: Rng>(args: &A, rng: &mut R) -> Self;
}
pub struct IndividualWrapper<I: Individual> {
i: I,
}
impl<I: Individual> IndividualWrapper<I> {
#[inline]
pub fn take(self) -> I {
self.i
}
}
impl<I: Individual> Deref for IndividualWrapper<I> {
type Target = I;
#[inline]
fn deref(&self) -> &Self::Target {
&self.i
}
}
impl<I: Individual> DerefMut for IndividualWrapper<I> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.i
}
}
impl<I: Individual> PartialEq for IndividualWrapper<I> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.i.fitness() == other.i.fitness()
}
}
impl<I: Individual> Eq for IndividualWrapper<I> {}
impl<I: Individual> PartialOrd for IndividualWrapper<I> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.i.fitness().partial_cmp(&other.i.fitness())
}
}
impl<I: Individual> Ord for IndividualWrapper<I> {
#[inline]
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.partial_cmp(other).unwrap_or(std::cmp::Ordering::Equal)
}
}
impl<I: Individual> From<I> for IndividualWrapper<I> {
#[inline]
fn from(i: I) -> Self {
Self { i }
}
}