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
52    fn population(&self) -> &Population<Self::Chromosome> {
53        &self.ecosystem().population()
54    }
55
56    fn species(&self) -> Option<&Vec<Species<Self::Chromosome>>> {
57        self.ecosystem().species()
58    }
59
60    fn time(&self) -> Duration {
61        self.metrics()
62            .get(metric_names::EVOLUTION_TIME)
63            .unwrap()
64            .time_sum()
65            .unwrap()
66    }
67
68    fn seconds(&self) -> f64 {
69        self.time().as_secs_f64()
70    }
71}
72
73pub trait EngineStep<C>: Send + Sync
74where
75    C: Chromosome,
76{
77    fn name(&self) -> &'static str {
78        std::any::type_name::<Self>()
79            .split("<")
80            .next()
81            .unwrap_or(std::any::type_name::<Self>())
82            .split("::")
83            .last()
84            .unwrap_or("Unknown Step")
85    }
86
87    fn execute(&mut self, generation: usize, metrics: &mut MetricSet, ecosystem: &mut Ecosystem<C>);
88}
89
90pub struct Context<C, T>
91where
92    C: Chromosome,
93{
94    pub ecosystem: Ecosystem<C>,
95    pub best: T,
96    pub index: usize,
97    pub metrics: MetricSet,
98    pub score: Option<Score>,
99    pub front: Arc<RwLock<Front<Phenotype<C>>>>,
100    pub objective: Objective,
101    pub problem: Arc<dyn Problem<C, T>>,
102}
103
104impl<C, T> Clone for Context<C, T>
105where
106    C: Chromosome,
107    T: Clone,
108{
109    fn clone(&self) -> Self {
110        Context {
111            ecosystem: self.ecosystem.clone(),
112            best: self.best.clone(),
113            index: self.index,
114            metrics: self.metrics.clone(),
115            score: self.score.clone(),
116            front: self.front.clone(),
117            objective: self.objective.clone(),
118            problem: Arc::clone(&self.problem),
119        }
120    }
121}