Skip to main content

radiate_engines/builder/
config.rs

1use crate::Chromosome;
2use crate::Generation;
3use crate::GeneticEngineBuilder;
4use crate::builder::EngineParams;
5use crate::builder::evaluators::EvaluationParams;
6use crate::builder::objectives::OptimizeParams;
7use crate::builder::population::PopulationParams;
8use crate::builder::problem::ProblemParams;
9use crate::builder::selectors::SelectionParams;
10use crate::builder::species::SpeciesParams;
11use crate::genome::phenotype::Phenotype;
12use crate::objectives::Objective;
13use crate::{EventHandler, Front, Problem, ReplacementStrategy, Select};
14use radiate_core::Expr;
15use radiate_core::MetricQuery;
16use radiate_core::metric_names;
17use radiate_core::{Alterer, Diversity, Ecosystem, Evaluator, Executor, Genotype, Rate};
18use std::sync::{Arc, Mutex, RwLock};
19
20#[derive(Clone)]
21pub(crate) struct EngineConfig<C: Chromosome, T: Clone> {
22    ecosystem: Ecosystem<C>,
23    problem: Arc<dyn Problem<C, T>>,
24    survivor_selector: Arc<dyn Select<C>>,
25    offspring_selector: Arc<dyn Select<C>>,
26    replacement_strategy: Arc<dyn ReplacementStrategy<C>>,
27    alterers: Vec<Alterer<C>>,
28    species_threshold: Rate,
29    diversity: Option<Arc<dyn Diversity<C>>>,
30    evaluator: Arc<dyn Evaluator<C, T>>,
31    objective: Objective,
32    max_age: usize,
33    max_species_age: usize,
34    front: Arc<RwLock<Front<Phenotype<C>>>>,
35    offspring_fraction: f32,
36    executor: EvaluationParams<C, T>,
37    handlers: Vec<Arc<Mutex<dyn EventHandler<T>>>>,
38    exprs: Option<Arc<Mutex<Vec<MetricQuery>>>>,
39    generation: Option<Generation<C, T>>,
40}
41
42impl<C: Chromosome, T: Clone> EngineConfig<C, T> {
43    pub fn ecosystem(&self) -> &Ecosystem<C> {
44        &self.ecosystem
45    }
46
47    pub fn survivor_selector(&self) -> Arc<dyn Select<C>> {
48        Arc::clone(&self.survivor_selector)
49    }
50
51    pub fn offspring_selector(&self) -> Arc<dyn Select<C>> {
52        Arc::clone(&self.offspring_selector)
53    }
54
55    pub fn replacement_strategy(&self) -> Arc<dyn ReplacementStrategy<C>> {
56        Arc::clone(&self.replacement_strategy)
57    }
58
59    pub fn alters(&self) -> &[Alterer<C>] {
60        &self.alterers
61    }
62
63    pub fn objective(&self) -> Objective {
64        self.objective.clone()
65    }
66
67    pub fn max_age(&self) -> usize {
68        self.max_age
69    }
70
71    pub fn max_species_age(&self) -> usize {
72        self.max_species_age
73    }
74
75    pub fn species_threshold(&self) -> Rate {
76        self.species_threshold.clone()
77    }
78
79    pub fn diversity(&self) -> Option<Arc<dyn Diversity<C>>> {
80        self.diversity.clone()
81    }
82
83    pub fn front(&self) -> Arc<RwLock<Front<Phenotype<C>>>> {
84        Arc::clone(&self.front)
85    }
86
87    pub fn evaluator(&self) -> Arc<dyn Evaluator<C, T>> {
88        Arc::clone(&self.evaluator)
89    }
90
91    pub fn survivor_count(&self) -> usize {
92        self.ecosystem.population().len() - self.offspring_count()
93    }
94
95    pub fn offspring_count(&self) -> usize {
96        (self.ecosystem.population().len() as f32 * self.offspring_fraction) as usize
97    }
98
99    pub fn bus_executor(&self) -> Arc<Executor> {
100        Arc::clone(&self.executor.bus_executor)
101    }
102
103    pub fn species_executor(&self) -> Arc<Executor> {
104        Arc::clone(&self.executor.species_executor)
105    }
106
107    pub fn handlers(&self) -> Vec<Arc<Mutex<dyn EventHandler<T>>>> {
108        self.handlers.clone()
109    }
110
111    pub fn problem(&self) -> Arc<dyn Problem<C, T>> {
112        Arc::clone(&self.problem)
113    }
114
115    pub fn generation(&self) -> Option<Generation<C, T>>
116    where
117        C: Clone,
118        T: Clone,
119    {
120        self.generation.clone()
121    }
122
123    pub fn encoder(&self) -> Arc<dyn Fn() -> Genotype<C> + Send + Sync>
124    where
125        C: 'static,
126        T: 'static,
127    {
128        let problem = Arc::clone(&self.problem);
129        Arc::new(move || problem.encode())
130    }
131
132    pub fn exprs(&self) -> Option<Arc<Mutex<Vec<MetricQuery>>>> {
133        self.exprs.clone()
134    }
135
136    // pub fn limits(&self) -> Option<Vec<Limit>> {
137    //     self.limits.clone()
138    // }
139}
140
141impl<C, T> From<&EngineParams<C, T>> for EngineConfig<C, T>
142where
143    C: Chromosome + Clone + 'static,
144    T: Clone + Send + Sync + 'static,
145{
146    fn from(params: &EngineParams<C, T>) -> Self {
147        let threshold = if let Some(count) = params.species_params.target_species_count {
148            let curr_threshold = params.species_params.species_threshold.get_by_index(1);
149
150            let index = Expr::select(metric_names::INDEX);
151            let thresh = Expr::select(metric_names::SPECIES_THRESHOLD);
152            let err = Expr::select(metric_names::SPECIES_COUNT).error(count as f32) * 0.05;
153
154            Rate::Expr(
155                Expr::when(index.lt(2))
156                    .then(curr_threshold)
157                    .otherwise(err + thresh),
158            )
159        } else {
160            params.species_params.species_threshold.clone()
161        };
162
163        Self {
164            ecosystem: params.population_params.ecosystem.clone().unwrap(),
165            problem: params.problem_params.problem.clone().unwrap(),
166            survivor_selector: params.selection_params.survivor_selector.clone(),
167            offspring_selector: params.selection_params.offspring_selector.clone(),
168            replacement_strategy: params.replacement_strategy.clone(),
169            alterers: params.alterers.clone(),
170            objective: params.optimization_params.objectives.clone(),
171            max_age: params.population_params.max_age,
172            max_species_age: params.species_params.max_species_age,
173            species_threshold: threshold,
174            diversity: params.species_params.diversity.clone(),
175            front: Arc::new(RwLock::new(
176                params.optimization_params.front.clone().unwrap(),
177            )),
178            offspring_fraction: params.selection_params.offspring_fraction,
179            evaluator: params.evaluation_params.evaluator.clone(),
180            executor: params.evaluation_params.clone(),
181            handlers: params.handlers.clone(),
182            generation: params.generation.clone(),
183            exprs: params.exprs.clone(),
184        }
185    }
186}
187
188impl<C, T> From<EngineConfig<C, T>> for GeneticEngineBuilder<C, T>
189where
190    C: Chromosome + Clone + 'static,
191    T: Clone + Send + Sync + 'static,
192{
193    fn from(config: EngineConfig<C, T>) -> Self {
194        GeneticEngineBuilder {
195            params: EngineParams {
196                population_params: PopulationParams {
197                    population_size: config.ecosystem.population().len(),
198                    max_age: config.max_age,
199                    ecosystem: Some(config.ecosystem),
200                },
201                species_params: SpeciesParams {
202                    diversity: config.diversity,
203                    species_threshold: config.species_threshold,
204                    max_species_age: config.max_species_age,
205                    target_species_count: None,
206                },
207                evaluation_params: config.executor,
208                selection_params: SelectionParams {
209                    offspring_fraction: config.offspring_fraction,
210                    survivor_selector: config.survivor_selector,
211                    offspring_selector: config.offspring_selector,
212                },
213                optimization_params: OptimizeParams {
214                    objectives: config.objective,
215                    front_range: config.front.read().unwrap().range().clone(),
216                    front: Some(config.front.read().unwrap().clone()),
217                },
218                problem_params: ProblemParams {
219                    codec: None,
220                    problem: Some(config.problem),
221                    fitness_fn: None,
222                    batch_fitness_fn: None,
223                    raw_fitness_fn: None,
224                    raw_batch_fitness_fn: None,
225                },
226
227                replacement_strategy: config.replacement_strategy,
228                alterers: config.alterers,
229                handlers: config.handlers,
230                exprs: config.exprs,
231                generation: config.generation,
232            },
233            errors: Vec::new(),
234        }
235    }
236}