use super::{FitnessFunction, FitnessName};
use crate::chromosone::Gene;
pub struct LocusDesirability<const N: usize, const NSYMS: usize> {
pub symbol_scores: Vec<Vec<f64>>, pub weight: f64,
}
impl<const N: usize, const NSYMS: usize> LocusDesirability<N, NSYMS> {
pub const fn new(symbol_scores: Vec<Vec<f64>>, weight: f64) -> LocusDesirability<N, NSYMS> {
LocusDesirability {
symbol_scores,
weight,
}
}
}
impl<const N: usize, const NSYMS: usize> FitnessFunction<N, NSYMS> for LocusDesirability<N, NSYMS> {
fn nscores(&self) -> usize {
N
}
fn weights(&self) -> Vec<f64> {
return vec![self.weight; self.nscores()];
}
fn run(&self, chromosone: &[Gene; N]) -> Vec<f64> {
chromosone
.iter()
.enumerate()
.map(|(i, gene)| self.symbol_scores[*gene as usize][i])
.collect()
}
fn names(&self) -> Vec<FitnessName> {
(0..N)
.map(|l| FitnessName {
prefix: "".to_string(),
gene: None,
locus: Some(l),
})
.collect()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_locus_desirability() {
let wc = LocusDesirability::<5, 3>::new(
vec![
vec![2.0, 2.0, 1.0, 1.0, 0.0],
vec![1.0, 1.0, 2.0, 2.0, 0.0],
vec![2.0, 2.0, 2.0, 2.0, 2.0],
],
1.0,
);
let scores = wc.run(&[0, 0, 0, 1, 1]);
assert_eq!(scores, vec![2.0, 2.0, 1.0, 2.0, 0.0]);
assert_eq!(wc.nscores(), scores.len());
}
}