radiate_core/genome/
ecosystem.rs

1use super::{Chromosome, Genotype, Phenotype, Population, Species};
2use crate::{Objective, Score, random_provider};
3
4#[derive(Clone, Debug)]
5pub struct Ecosystem<C: Chromosome> {
6    pub population: Population<C>,
7    pub species: Option<Vec<Species<C>>>,
8    pub is_sorted: bool,
9}
10
11impl<C: Chromosome> Ecosystem<C> {
12    pub fn new(population: Population<C>) -> Self {
13        Ecosystem {
14            population,
15            species: None,
16            is_sorted: false,
17        }
18    }
19
20    pub fn population(&self) -> &Population<C> {
21        &self.population
22    }
23
24    pub fn population_mut(&mut self) -> &mut Population<C> {
25        &mut self.population
26    }
27
28    pub fn species(&self) -> Option<&Vec<Species<C>>> {
29        self.species.as_ref()
30    }
31
32    pub fn species_mut(&mut self) -> Option<&mut Vec<Species<C>>> {
33        self.species.as_mut()
34    }
35
36    pub fn get_phenotype(&self, index: usize) -> Option<&Phenotype<C>> {
37        self.population.get(index)
38    }
39
40    pub fn get_phenotype_mut(&mut self, index: usize) -> Option<&mut Phenotype<C>> {
41        self.population.get_mut(index)
42    }
43
44    pub fn get_genotype(&self, index: usize) -> Option<&Genotype<C>> {
45        self.population.get(index).map(|p| p.genotype())
46    }
47
48    pub fn get_genotype_mut(&mut self, index: usize) -> Option<&mut Genotype<C>> {
49        self.population.get_mut(index).map(|p| p.genotype_mut())
50    }
51
52    pub fn get_species(&self, index: usize) -> Option<&Species<C>> {
53        self.species.as_ref().and_then(|s| s.get(index))
54    }
55
56    pub fn get_species_mut(&mut self, index: usize) -> Option<&mut Species<C>> {
57        self.species.as_mut().and_then(|s| s.get_mut(index))
58    }
59
60    pub fn species_mascots(&self) -> Vec<&Phenotype<C>> {
61        self.species
62            .as_ref()
63            .map(|s| s.iter().map(|spec| spec.mascot()).collect())
64            .unwrap_or_default()
65    }
66
67    pub fn push_species(&mut self, species: Species<C>) {
68        if let Some(species_list) = &mut self.species {
69            species_list.push(species);
70        } else {
71            self.species = Some(vec![species]);
72        }
73    }
74
75    pub fn add_species_member(&mut self, species_idx: usize, member_idx: usize) {
76        if let Some(species) = &mut self.species {
77            if let Some(spec) = species.get_mut(species_idx) {
78                if let Some(member) = self.population.get_cell(member_idx) {
79                    spec.population.push(member.clone());
80                }
81            }
82        }
83    }
84
85    pub fn generate_mascots(&mut self) {
86        if let Some(species) = &mut self.species {
87            for spec in species {
88                let mascot = random_provider::choose(&spec.population.as_ref());
89                spec.mascot = mascot.get().clone();
90                spec.population.clear();
91            }
92        }
93    }
94
95    pub fn fitness_share(&mut self, objective: &Objective) {
96        if let Some(species) = &mut self.species {
97            let mut scores = Vec::with_capacity(species.len());
98            for spec in species.iter() {
99                scores.push(Self::adjust_scores(spec).iter().sum::<Score>());
100            }
101
102            let total_score = scores.iter().sum::<Score>();
103            for (i, spec) in species.iter_mut().enumerate() {
104                let spec_score = scores[i].clone();
105                let adjusted_score = spec_score / total_score.clone();
106                spec.update_score(adjusted_score, objective);
107            }
108
109            objective.sort(species);
110        }
111    }
112
113    fn adjust_scores(species: &Species<C>) -> Vec<Score> {
114        species
115            .population
116            .get_scores()
117            .iter()
118            .map(|score| (*score).clone() / species.len() as f32)
119            .collect()
120    }
121}