radiate_engines/
epoch.rs

1use crate::Chromosome;
2use radiate_core::objectives::Scored;
3use radiate_core::{
4    Ecosystem, Front, MetricSet, Objective, Phenotype, Population, Problem, Score, Species,
5    metric_names,
6};
7use std::fmt::Debug;
8use std::sync::{Arc, RwLock};
9use std::time::Duration;
10
11pub struct Context<C: Chromosome, T> {
12    pub(crate) ecosystem: Ecosystem<C>,
13    pub(crate) best: T,
14    pub(crate) index: usize,
15    pub(crate) metrics: MetricSet,
16    pub(crate) epoch_metrics: MetricSet,
17    pub(crate) score: Option<Score>,
18    pub(crate) front: Arc<RwLock<Front<Phenotype<C>>>>,
19    pub(crate) objective: Objective,
20    pub(crate) problem: Arc<dyn Problem<C, T>>,
21}
22
23impl<C, T> Clone for Context<C, T>
24where
25    C: Chromosome + Clone,
26    T: Clone,
27{
28    fn clone(&self) -> Self {
29        Context {
30            ecosystem: self.ecosystem.clone(),
31            best: self.best.clone(),
32            index: self.index,
33            metrics: self.metrics.clone(),
34            epoch_metrics: self.epoch_metrics.clone(),
35            score: self.score.clone(),
36            front: self.front.clone(),
37            objective: self.objective.clone(),
38            problem: Arc::clone(&self.problem),
39        }
40    }
41}
42
43pub struct Generation<C, T>
44where
45    C: Chromosome,
46{
47    ecosystem: Ecosystem<C>,
48    value: T,
49    index: usize,
50    metrics: MetricSet,
51    score: Score,
52    objective: Objective,
53    front: Option<Front<Phenotype<C>>>,
54}
55
56impl<C: Chromosome, T> Generation<C, T> {
57    pub fn score(&self) -> &Score {
58        &self.score
59    }
60
61    pub fn front(&self) -> Option<&Front<Phenotype<C>>> {
62        self.front.as_ref()
63    }
64
65    pub fn ecosystem(&self) -> &Ecosystem<C> {
66        &self.ecosystem
67    }
68
69    pub fn value(&self) -> &T {
70        &self.value
71    }
72
73    pub fn index(&self) -> usize {
74        self.index
75    }
76
77    pub fn metrics(&self) -> &MetricSet {
78        &self.metrics
79    }
80
81    pub fn objective(&self) -> &Objective {
82        &self.objective
83    }
84
85    pub fn population(&self) -> &Population<C> {
86        &self.ecosystem().population()
87    }
88
89    pub fn species(&self) -> Option<&[Species<C>]> {
90        self.ecosystem().species().map(|s| s.as_slice())
91    }
92
93    pub fn time(&self) -> Duration {
94        self.metrics()
95            .get(metric_names::TIME)
96            .map(|m| m.time_statistic().map(|t| t.sum()))
97            .flatten()
98            .unwrap_or_default()
99    }
100
101    pub fn seconds(&self) -> f64 {
102        self.time().as_secs_f64()
103    }
104}
105
106impl<C: Chromosome, T> Scored for Generation<C, T> {
107    fn score(&self) -> Option<&Score> {
108        Some(&self.score)
109    }
110}
111
112impl<C: Chromosome + Clone, T: Clone> From<&Context<C, T>> for Generation<C, T> {
113    fn from(context: &Context<C, T>) -> Self {
114        Generation {
115            ecosystem: context.ecosystem.clone(),
116            value: context.best.clone(),
117            index: context.index,
118            metrics: context.metrics.clone(),
119            score: context.score.clone().unwrap(),
120            objective: context.objective.clone(),
121            front: match context.objective {
122                Objective::Multi(_) => Some(context.front.read().unwrap().clone()),
123                _ => None,
124            },
125        }
126    }
127}
128
129impl<C: Chromosome, T: Debug> Debug for Generation<C, T> {
130    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
131        write!(f, "Generation {{\n")?;
132        write!(f, "  value: {:?},\n", self.value)?;
133        write!(f, "  score: {:?},\n", self.score)?;
134        write!(f, "  index: {:?},\n", self.index)?;
135        write!(f, "  size: {:?},\n", self.ecosystem.population.len())?;
136        write!(f, "  duration: {:?},\n", self.time())?;
137
138        if let Some(species) = &self.ecosystem.species {
139            for s in species {
140                write!(f, "  species: {:?},\n", s)?;
141            }
142        }
143
144        write!(f, "  metrics: {:?},\n", self.metrics)?;
145        write!(f, "}}")
146    }
147}
148
149impl<C, T> FromIterator<Generation<C, T>> for Front<Phenotype<C>>
150where
151    C: Chromosome + Clone,
152{
153    fn from_iter<I: IntoIterator<Item = Generation<C, T>>>(iter: I) -> Self {
154        iter.into_iter()
155            .last()
156            .map(|generation| generation.front().map(|front| front.clone()))
157            .flatten()
158            .unwrap_or_default()
159    }
160}