1pub mod creation;
12pub mod cross;
13pub mod mutation;
14pub mod pairing;
15pub mod pre_birth;
16pub mod selection;
17
18use std::cmp::Ordering;
19use std::f64;
20use std::ops;
21use std::slice;
22
23use crate::tools::logging::Logger;
24use crate::tools::stopchecker::StopChecker;
25use crate::{Agent, AgentsState, AlgorithmState, Goal, IterativeOptimizer, Optimizer, Solution};
26
27#[derive(Debug)]
31pub struct Individual<T> {
32 chromosomes: T,
34
35 fitness: f64,
37
38 alive: bool,
40}
41
42impl<T: Clone> Clone for Individual<T> {
43 fn clone(&self) -> Individual<T> {
44 Individual {
45 chromosomes: self.chromosomes.clone(),
46 fitness: self.fitness,
47 alive: self.alive,
48 }
49 }
50}
51
52impl<T> Agent<T> for Individual<T> {
53 fn get_goal(&self) -> f64 {
54 self.fitness
55 }
56
57 fn get_parameter(&self) -> &T {
58 &self.chromosomes
59 }
60}
61
62impl<T> Individual<T> {
63 pub fn get_chromosomes(&self) -> &T {
65 &self.chromosomes
66 }
67
68 pub fn get_fitness(&self) -> f64 {
70 self.fitness
71 }
72
73 pub fn is_alive(&self) -> bool {
75 self.alive
76 }
77
78 pub fn kill(&mut self) {
80 self.alive = false;
81 }
82}
83
84pub struct Population<'a, T> {
88 goal: Box<dyn Goal<T> + 'a>,
90
91 individuals: Vec<Individual<T>>,
92
93 best_individual: Option<Individual<T>>,
95
96 worst_individual: Option<Individual<T>>,
98
99 iteration: usize,
101}
102
103impl<'a, T: Clone> Population<'a, T> {
104 fn update_best_worst_individuals(&mut self) {
106 let best = self
108 .individuals
109 .iter()
110 .min_by(|ind_1, ind_2| self.individuals_min_cmp(ind_1, ind_2));
111
112 if let Some(ref individual) = best {
113 self.best_individual = Some((*individual).clone());
114 }
115
116 let worst = self
118 .individuals
119 .iter()
120 .max_by(|ind_1, ind_2| self.individuals_max_cmp(ind_1, ind_2));
121
122 if let Some(ref individual) = worst {
123 self.worst_individual = Some((*individual).clone());
124 }
125 }
126}
127
128impl<'a, T: Clone> AgentsState<T> for Population<'a, T> {
129 type Agent = Individual<T>;
130
131 fn get_agents(&self) -> Vec<&Self::Agent> {
133 let mut agents: Vec<&Self::Agent> = Vec::with_capacity(self.len());
134 for individual in self.individuals.iter() {
135 agents.push(individual);
136 }
137
138 agents
139 }
140}
141
142impl<'a, T> Population<'a, T> {
143 fn new(goal: Box<dyn Goal<T> + 'a>) -> Self {
147 Population {
148 goal,
149 individuals: vec![],
150 best_individual: None,
151 worst_individual: None,
152 iteration: 0,
153 }
154 }
155
156 fn reset(&mut self) {
158 self.individuals.clear();
159 self.best_individual = None;
160 self.worst_individual = None;
161 self.iteration = 0;
162 }
163
164 fn push(&mut self, chromosomes: T) {
166 let fitness = self.goal.get(&chromosomes);
167 let new_individual = Individual {
168 chromosomes,
169 fitness,
170 alive: true,
171 };
172
173 self.individuals.push(new_individual);
174 }
175
176 fn append(&mut self, chromosomes_list: Vec<T>) {
179 for chromosome in chromosomes_list {
180 self.push(chromosome);
181 }
182 }
183
184 pub fn iter(&self) -> slice::Iter<Individual<T>> {
186 self.individuals.iter()
187 }
188
189 pub fn iter_mut(&mut self) -> slice::IterMut<Individual<T>> {
191 self.individuals.iter_mut()
192 }
193
194 pub fn get_iteration(&self) -> usize {
196 self.iteration
197 }
198
199 pub fn len_alive(&self) -> usize {
201 self.individuals
202 .iter()
203 .filter(|individual| individual.is_alive())
204 .count()
205 }
206
207 pub fn get_best(&self) -> &Option<Individual<T>> {
209 &self.best_individual
210 }
211
212 pub fn get_worst(&self) -> &Option<Individual<T>> {
214 &self.worst_individual
215 }
216
217 pub fn len(&self) -> usize {
219 self.individuals.len()
220 }
221
222 fn individuals_min_cmp(
226 &self,
227 individual_1: &Individual<T>,
228 individual_2: &Individual<T>,
229 ) -> Ordering {
230 let goal_1 = individual_1.get_goal();
231 let goal_2 = individual_2.get_goal();
232
233 if goal_1.is_nan() && goal_2.is_nan() {
234 Ordering::Greater
235 } else if goal_1.is_nan() {
236 Ordering::Greater
237 } else if goal_2.is_nan() {
238 Ordering::Less
239 } else {
240 goal_1.partial_cmp(&goal_2).unwrap()
241 }
242 }
243
244 fn individuals_max_cmp(
248 &self,
249 individual_1: &Individual<T>,
250 individual_2: &Individual<T>,
251 ) -> Ordering {
252 let goal_1 = individual_1.get_goal();
253 let goal_2 = individual_2.get_goal();
254
255 if goal_1.is_nan() && goal_2.is_nan() {
256 Ordering::Less
257 } else if goal_1.is_nan() {
258 Ordering::Less
259 } else if goal_2.is_nan() {
260 Ordering::Greater
261 } else {
262 goal_1.partial_cmp(&goal_2).unwrap()
263 }
264 }
265
266 fn next_iteration(&mut self) {
268 self.iteration += 1;
269 }
270
271 fn remove_dead(&mut self) {
272 self.individuals.retain(|individual| individual.is_alive());
273 }
274}
275
276impl<'a, T> ops::Index<usize> for Population<'a, T> {
278 type Output = Individual<T>;
279
280 fn index(&self, index: usize) -> &Individual<T> {
281 &self.individuals[index]
282 }
283}
284
285impl<'a, T> ops::IndexMut<usize> for Population<'a, T> {
287 fn index_mut<'b>(&'b mut self, index: usize) -> &'b mut Individual<T> {
288 &mut self.individuals[index]
289 }
290}
291
292impl<'a, T: Clone> AlgorithmState<T> for Population<'a, T> {
293 fn get_best_solution(&self) -> Option<(T, f64)> {
294 match &self.best_individual {
295 None => None,
296 Some(individual) => Some((individual.chromosomes.clone(), individual.fitness)),
297 }
298 }
299
300 fn get_iteration(&self) -> usize {
301 self.iteration
302 }
303}
304
305pub trait Creator<T> {
309 fn create(&mut self) -> Vec<T>;
311}
312
313pub trait Cross<T> {
317 fn cross(&mut self, parents: &[&T]) -> Vec<T>;
321}
322
323pub trait Mutation<T> {
327 fn mutation(&mut self, chromosomes: &T) -> T;
331}
332
333pub trait PreBirth<T> {
337 fn pre_birth(&mut self, population: &Population<T>, new_chromosomes: &mut Vec<T>);
339}
340
341pub trait Selection<T> {
345 fn kill(&mut self, population: &mut Population<T>);
348}
349
350pub trait Pairing<T> {
354 fn get_pairs(&mut self, population: &Population<T>) -> Vec<Vec<usize>>;
357}
358
359pub struct GeneticOptimizer<'a, T> {
366 stop_checker: Box<dyn StopChecker<T> + 'a>,
367 creator: Box<dyn Creator<T> + 'a>,
368 pairing: Box<dyn Pairing<T> + 'a>,
369 cross: Box<dyn Cross<T> + 'a>,
370 mutation: Box<dyn Mutation<T> + 'a>,
371 selections: Vec<Box<dyn Selection<T> + 'a>>,
372 pre_births: Vec<Box<dyn PreBirth<T> + 'a>>,
373 loggers: Vec<Box<dyn Logger<T> + 'a>>,
374 population: Population<'a, T>,
375}
376
377impl<'a, T: Clone> GeneticOptimizer<'a, T> {
378 pub fn new(
380 goal: Box<dyn Goal<T> + 'a>,
381 stop_checker: Box<dyn StopChecker<T> + 'a>,
382 creator: Box<dyn Creator<T> + 'a>,
383 pairing: Box<dyn Pairing<T> + 'a>,
384 cross: Box<dyn Cross<T> + 'a>,
385 mutation: Box<dyn Mutation<T> + 'a>,
386 selections: Vec<Box<dyn Selection<T> + 'a>>,
387 pre_births: Vec<Box<dyn PreBirth<T> + 'a>>,
388 ) -> GeneticOptimizer<'a, T> {
389 GeneticOptimizer {
390 creator,
391 stop_checker,
392 pairing,
393 cross,
394 mutation,
395 selections,
396 pre_births,
397 loggers: vec![],
398 population: Population::new(goal),
399 }
400 }
401
402 pub fn set_loggers(&mut self, loggers: Vec<Box<dyn Logger<T> + 'a>>) {
403 self.loggers = loggers;
404 }
405
406 pub fn set_pairing(&mut self, pairing: Box<dyn Pairing<T>>) {
408 self.pairing = pairing;
409 }
410
411 pub fn set_cross(&mut self, cross: Box<dyn Cross<T>>) {
413 self.cross = cross;
414 }
415
416 pub fn set_mutation(&mut self, mutation: Box<dyn Mutation<T>>) {
418 self.mutation = mutation;
419 }
420
421 pub fn set_selection(&mut self, selections: Vec<Box<dyn Selection<T>>>) {
423 self.selections = selections;
424 }
425
426 pub fn set_pre_birth(&mut self, pre_births: Vec<Box<dyn PreBirth<T>>>) {
428 self.pre_births = pre_births;
429 }
430
431 pub fn set_stop_checker(&mut self, stop_checker: Box<dyn StopChecker<T>>) {
433 self.stop_checker = stop_checker;
434 }
435
436 fn run_pairing(&mut self) -> Vec<T> {
437 let pairs: Vec<Vec<usize>> = self.pairing.get_pairs(&self.population);
438 let mut new_chromosomes: Vec<T> = Vec::with_capacity(pairs.len());
439
440 for pair in pairs {
441 let mut cross_chromosomes = Vec::with_capacity(pair.len());
442 for i in pair {
443 cross_chromosomes.push(self.population[i].get_chromosomes());
444 }
445
446 let mut child_chromosomes = self.cross.cross(&cross_chromosomes);
447 new_chromosomes.append(&mut child_chromosomes);
448 }
449
450 new_chromosomes
451 }
452}
453
454impl<'a, T: Clone> IterativeOptimizer<T> for GeneticOptimizer<'a, T> {
455 fn next_iterations(&mut self) -> Option<Solution<T>> {
457 for logger in &mut self.loggers {
458 logger.resume(&self.population);
459 }
460
461 while !self.stop_checker.can_stop(&self.population) {
462 let mut children_chromo_list = self.run_pairing();
464
465 let mut children_mutants: Vec<T> = children_chromo_list
467 .iter_mut()
468 .map(|chromo| self.mutation.mutation(chromo))
469 .collect();
470
471 for pre_birth in &mut self.pre_births {
473 pre_birth.pre_birth(&self.population, &mut children_mutants);
474 }
475
476 self.population.append(children_mutants);
478
479 for selection in &mut self.selections {
481 selection.kill(&mut self.population);
482 }
483
484 self.population.remove_dead();
485
486 self.population.update_best_worst_individuals();
487
488 self.population.next_iteration();
489
490 for logger in &mut self.loggers {
491 logger.next_iteration(&self.population);
492 }
493 }
494
495 for logger in &mut self.loggers {
496 logger.finish(&self.population);
497 }
498
499 match &self.population.best_individual {
500 None => None,
501 Some(individual) => Some((individual.chromosomes.clone(), individual.fitness)),
502 }
503 }
504}
505
506impl<'a, T: Clone> Optimizer<T> for GeneticOptimizer<'a, T> {
507 fn find_min(&mut self) -> Option<(T, f64)> {
509 self.population.reset();
510 let start_chromo_list = self.creator.create();
511
512 self.population.append(start_chromo_list);
514
515 for logger in &mut self.loggers {
516 logger.start(&self.population);
517 }
518
519 self.next_iterations()
520 }
521}