use std::convert::Infallible;
use crate::{binary_string::BinaryString, test_infra::load_test_file};
use super::FitnessFunction;
pub struct LABS;
impl LABS {
fn new() -> Self {
LABS
}
fn Ck(k: usize, S: &Vec<i32>) -> i32 {
let D = S.len();
S.iter()
.take(D - k)
.zip(S.iter().skip(k))
.map(|(x, y)| x * y)
.sum()
}
}
impl FitnessFunction for LABS {
type In = BinaryString;
type Out = i32;
type Err = Infallible;
fn fit(self: &Self, chromosome: &BinaryString) -> Result<i32, Infallible> {
let S: Vec<i32> = chromosome
.into_iter()
.map(|c| (*c as i32) * 2 - 1)
.collect();
let D = S.len();
Ok((1..=D-1)
.map(|k| LABS::Ck(k, &S).pow(2))
.sum())
}
}
#[test]
fn test_LABS() {
let data = load_test_file::<i8, i32>("tests/labs.txt");
for test in data {
println!("Test vector {}", test.inp.iter()
.map(|x| x.to_string())
.collect::<Vec<String>>()
.join(", "));
assert_eq!(
LABS::new().fit(&BinaryString::new(test.inp)).unwrap(),
test.out
)
}
}