radiate_core/
evaluator.rs1use 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}