radiate_core/genome/
ecosystem.rs1use 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}