use std::marker::PhantomData;
use crate::encoding::*;
use crate::random::*;
pub trait Genome: Clone + Send + std::hash::Hash + std::cmp::Eq {
}
#[derive(Clone, Debug)]
pub struct Individual<G>
where
G: Genome,
{
raw_score: f64,
genome: G,
}
pub trait EvaluateObjectiveValue<G>: Clone + std::fmt::Debug + std::marker::Sync
where
G: Genome,
{
fn evaluate(&self, genome: &G) -> f64;
}
impl<G> Individual<G>
where
G: Genome,
{
pub fn new<E>(genome: G, func: &mut E) -> Self
where
E: EvaluateObjectiveValue<G>,
{
let raw_score = func.evaluate(&genome);
Self { genome, raw_score }
}
pub fn genome(&self) -> &G {
&self.genome
}
pub fn objective_value(&self) -> f64 {
self.raw_score
}
}
impl<G> AsRef<Individual<G>> for Individual<G>
where
G: Genome,
{
fn as_ref(&self) -> &Self {
self
}
}
use gut::prelude::*;
pub(crate) trait Create<G>
where
G: Genome,
{
fn create(&self, genomes: impl IntoIterator<Item = G>) -> Vec<Individual<G>>;
}
impl<G, T> Create<G> for T
where
G: Genome,
T: EvaluateObjectiveValue<G>,
{
fn create(&self, genomes: impl IntoIterator<Item = G>) -> Vec<Individual<G>> {
let genomes: Vec<_> = genomes.into_iter().collect();
let n = genomes.len();
let genomes: std::collections::HashSet<_> = genomes.into_iter().collect();
let m = n - genomes.len();
if m > 0 {
info!("Removed {m} duplicates from {n} created genomes.");
}
genomes
.into_par_iter()
.map(|g| {
let raw_score = self.evaluate(&g);
Individual { genome: g, raw_score }
})
.collect()
}
}
#[derive(Clone, Debug)]
pub struct OneMax;
impl EvaluateObjectiveValue<Binary> for OneMax {
fn evaluate(&self, genome: &Binary) -> f64 {
let s: usize = genome.iter().filter(|&b| *b).count();
s as f64
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::encoding::Binary;
#[test]
fn test() {
let codes: Vec<_> = vec!["10110", "01010"]
.iter()
.map(|x| Binary::from_str(x))
.collect();
let indvs = OneMax.create(codes);
for indv in indvs.iter() {
println!(
"indv {:}, objective value = {}",
indv.genome(),
indv.objective_value()
);
}
}
}