radiate_core/
evaluator.rs

1use crate::{Chromosome, Ecosystem, Executor, Problem};
2use std::sync::Arc;
3
4pub trait Evaluator<C: Chromosome, T>: Send + Sync {
5    fn eval(&self, ecosystem: &mut Ecosystem<C>, problem: Arc<dyn Problem<C, T>>) -> usize;
6}
7
8pub struct FitnessEvaluator {
9    executor: Arc<Executor>,
10}
11
12impl FitnessEvaluator {
13    pub fn new(executor: Arc<Executor>) -> Self {
14        Self { executor }
15    }
16}
17
18impl<C: Chromosome, T> Evaluator<C, T> for FitnessEvaluator
19where
20    C: Chromosome + 'static,
21    T: 'static,
22{
23    #[inline]
24    fn eval(&self, ecosystem: &mut Ecosystem<C>, problem: Arc<dyn Problem<C, T>>) -> usize {
25        let mut jobs = Vec::new();
26        let len = ecosystem.population.len();
27        for idx in 0..len {
28            if ecosystem.population[idx].score().is_none() {
29                let geno = ecosystem.population[idx].take_genotype();
30                jobs.push((idx, geno));
31            }
32        }
33
34        let results = self.executor.execute_batch(
35            jobs.into_iter()
36                .map(|(idx, geno)| {
37                    let problem = Arc::clone(&problem);
38                    move || {
39                        let score = problem.eval(&geno);
40                        (idx, score, geno)
41                    }
42                })
43                .collect::<Vec<_>>(),
44        );
45
46        let count = results.len();
47        for result in results {
48            let (idx, score, genotype) = result;
49            ecosystem.population[idx].set_score(Some(score));
50            ecosystem.population[idx].set_genotype(genotype);
51        }
52
53        count
54    }
55}
56
57impl Default for FitnessEvaluator {
58    fn default() -> Self {
59        Self {
60            executor: Arc::new(Executor::Serial),
61        }
62    }
63}