use std::fmt::Debug;
use std::sync::Arc;
use crate::evolution::Challenge;
use crate::phenotype::Phenotype;
use super::LocalSearch;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone)]
pub struct HybridLocalSearch<P, C>
where
P: Phenotype,
C: Challenge<P> + Debug,
{
#[cfg_attr(feature = "serde", serde(skip))]
algorithms: Vec<Arc<dyn LocalSearch<P, C>>>,
}
impl<P, C> HybridLocalSearch<P, C>
where
P: Phenotype,
C: Challenge<P> + Debug,
{
pub fn new() -> Self {
Self {
algorithms: Vec::new(),
}
}
pub fn add_algorithm<L>(&mut self, algorithm: L) -> &mut Self
where
L: LocalSearch<P, C> + 'static,
{
self.algorithms.push(Arc::new(algorithm));
self
}
}
impl<P, C> LocalSearch<P, C> for HybridLocalSearch<P, C>
where
P: Phenotype,
C: Challenge<P> + Debug,
{
fn search(&self, phenotype: &mut P, challenge: &C) -> bool {
let mut improved = false;
for algorithm in &self.algorithms {
if algorithm.search(phenotype, challenge) {
improved = true;
}
}
improved
}
}
impl<P, C> Default for HybridLocalSearch<P, C>
where
P: Phenotype,
C: Challenge<P> + Debug,
{
fn default() -> Self {
Self::new()
}
}