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 }
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}