radiate_core/
engine.rs

1use crate::{
2    Chromosome, Ecosystem, Front, MetricSet, Objective, Phenotype, Population, Problem, Score,
3    Species, metric_names,
4};
5use std::{
6    sync::{Arc, RwLock},
7    time::Duration,
8};
9
10pub trait Engine {
11    type Chromosome: Chromosome;
12    type Epoch: Epoch<Chromosome = Self::Chromosome>;
13
14    fn next(&mut self) -> Self::Epoch;
15}
16
17pub trait EngineExt<E: Engine> {
18    fn run<F>(&mut self, limit: F) -> E::Epoch
19    where
20        F: Fn(&E::Epoch) -> bool,
21        Self: Sized;
22}
23
24impl<E> EngineExt<E> for E
25where
26    E: Engine,
27{
28    fn run<F>(&mut self, limit: F) -> E::Epoch
29    where
30        F: Fn(&E::Epoch) -> bool,
31        Self: Sized,
32    {
33        loop {
34            let epoch = self.next();
35
36            if limit(&epoch) {
37                break epoch;
38            }
39        }
40    }
41}
42
43pub trait Epoch {
44    type Chromosome: Chromosome;
45    type Value;
46
47    fn value(&self) -> &Self::Value;
48    fn ecosystem(&self) -> &Ecosystem<Self::Chromosome>;
49    fn index(&self) -> usize;
50    fn metrics(&self) -> &MetricSet;
51    fn objective(&self) -> &Objective;
52
53    fn population(&self) -> &Population<Self::Chromosome> {
54        &self.ecosystem().population()
55    }
56
57    fn species(&self) -> Option<&[Species<Self::Chromosome>]> {
58        self.ecosystem().species().map(|s| s.as_slice())
59    }
60
61    fn time(&self) -> Duration {
62        self.metrics()
63            .get(metric_names::EVOLUTION_TIME)
64            .map(|m| m.time_sum())
65            .flatten()
66            .unwrap_or_default()
67    }
68
69    fn seconds(&self) -> f64 {
70        self.time().as_secs_f64()
71    }
72}
73
74pub trait EngineStep<C>: Send + Sync
75where
76    C: Chromosome,
77{
78    fn name(&self) -> &'static str {
79        std::any::type_name::<Self>()
80            .split("<")
81            .next()
82            .unwrap_or(std::any::type_name::<Self>())
83            .split("::")
84            .last()
85            .unwrap_or("Unknown Step")
86    }
87
88    fn execute(&mut self, generation: usize, metrics: &mut MetricSet, ecosystem: &mut Ecosystem<C>);
89}
90
91pub struct Context<C, T>
92where
93    C: Chromosome,
94{
95    pub ecosystem: Ecosystem<C>,
96    pub best: T,
97    pub index: usize,
98    pub metrics: MetricSet,
99    pub score: Option<Score>,
100    pub front: Arc<RwLock<Front<Phenotype<C>>>>,
101    pub objective: Objective,
102    pub problem: Arc<dyn Problem<C, T>>,
103}
104
105impl<C, T> Clone for Context<C, T>
106where
107    C: Chromosome + Clone,
108    T: Clone,
109{
110    fn clone(&self) -> Self {
111        Context {
112            ecosystem: self.ecosystem.clone(),
113            best: self.best.clone(),
114            index: self.index,
115            metrics: self.metrics.clone(),
116            score: self.score.clone(),
117            front: self.front.clone(),
118            objective: self.objective.clone(),
119            problem: Arc::clone(&self.problem),
120        }
121    }
122}