use std::ops::Deref;
use rayon::prelude::*;
use crate::{Cached, Solution};
#[derive(Clone, Copy, Debug)]
pub struct MultiObjective<const M: usize> {
weighted: [f64; M],
}
impl<const M: usize> From<MultiObjective<M>> for f64 {
fn from(value: MultiObjective<M>) -> f64 {
let mut result: f64 = 0.0;
for i in 0..M {
result += value.weighted[i];
}
result
}
}
impl<const M: usize> MultiObjective<M> {
pub fn new_unweighted(values: [f64; M]) -> Self {
MultiObjective { weighted: values }
}
pub fn weighted_builder(weights: [f64; M]) -> impl Fn([f64; M]) -> Self {
move |values: [f64; M]| MultiObjective {
weighted: {
let mut arr = [0f64; M];
for i in 0..M {
arr[i] = weights[i] * values[i];
}
arr
},
}
}
}
impl<const M: usize> Deref for MultiObjective<M> {
type Target = [f64; M];
fn deref(&self) -> &Self::Target {
&self.weighted
}
}
impl<const M: usize> PartialEq for MultiObjective<M> {
fn eq(&self, other: &Self) -> bool {
for i in 0..M {
if (self[i] - other[i]).abs() > f64::EPSILON {
return false;
}
}
true
}
}
impl PartialEq<f64> for MultiObjective<1> {
fn eq(&self, other: &f64) -> bool {
(self[0] - other).abs() < f64::EPSILON
}
}
pub fn par_evaluate<T: Solution>(pop: &[Cached<T>]) {
pop.par_iter().for_each(|ind| {
ind.evaluate();
});
}