radiate_core/genome/
ecosystem.rs1use super::{Chromosome, Genotype, Phenotype, Population, Species};
2#[cfg(feature = "serde")]
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Default)]
27#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
28pub struct Ecosystem<C: Chromosome> {
29 pub population: Population<C>,
30 pub species: Option<Vec<Species<C>>>,
31}
32
33impl<C: Chromosome> Ecosystem<C> {
34 pub fn new(population: Population<C>) -> Self {
35 Ecosystem {
36 population,
37 species: None,
38 }
39 }
40
41 pub fn clone_ref(other: &Ecosystem<C>) -> Self
49 where
50 C: Clone,
51 {
52 Ecosystem {
53 population: Population::clone_ref(&other.population),
54 species: other.species.as_ref().map(|specs| {
55 specs
56 .iter()
57 .map(|species| Species::clone_ref(species))
58 .collect()
59 }),
60 }
61 }
62
63 pub fn shared_count(&self) -> usize {
69 self.population.shared_count()
70 }
71
72 pub fn is_shared(&self) -> bool {
77 self.shared_count() > 0
78 }
79
80 pub fn population(&self) -> &Population<C> {
81 &self.population
82 }
83
84 pub fn population_mut(&mut self) -> &mut Population<C> {
85 &mut self.population
86 }
87
88 pub fn species(&self) -> Option<&Vec<Species<C>>> {
89 self.species.as_ref()
90 }
91
92 pub fn species_mut(&mut self) -> Option<&mut Vec<Species<C>>> {
93 self.species.as_mut()
94 }
95
96 pub fn get_phenotype(&self, index: usize) -> Option<&Phenotype<C>> {
97 self.population.get(index)
98 }
99
100 pub fn get_phenotype_mut(&mut self, index: usize) -> Option<&mut Phenotype<C>> {
101 self.population.get_mut(index)
102 }
103
104 pub fn get_genotype(&self, index: usize) -> Option<&Genotype<C>> {
105 self.population.get(index).map(|p| p.genotype())
106 }
107
108 pub fn get_genotype_mut(&mut self, index: usize) -> Option<&mut Genotype<C>> {
109 self.population.get_mut(index).map(|p| p.genotype_mut())
110 }
111
112 pub fn get_species(&self, index: usize) -> Option<&Species<C>> {
113 self.species.as_ref().and_then(|s| s.get(index))
114 }
115
116 pub fn get_species_mut(&mut self, index: usize) -> Option<&mut Species<C>> {
117 self.species.as_mut().and_then(|s| s.get_mut(index))
118 }
119
120 pub fn species_mascots(&self) -> Vec<&Phenotype<C>> {
121 self.species
122 .as_ref()
123 .map(|s| s.iter().map(|spec| spec.mascot()).collect())
124 .unwrap_or_default()
125 }
126
127 pub fn push_species(&mut self, species: Species<C>) {
128 if let Some(species_list) = &mut self.species {
129 species_list.push(species);
130 } else {
131 self.species = Some(vec![species]);
132 }
133 }
134
135 pub fn add_species_member(&mut self, species_idx: usize, member_idx: usize)
142 where
143 C: Clone,
144 {
145 if let Some(species) = &mut self.species {
146 if let Some(spec) = species.get_mut(species_idx) {
147 if let Some(member) = self.population.ref_clone_member(member_idx) {
148 spec.population.push(member);
149 }
150 }
151 }
152 }
153
154 pub fn remvove_dead_species(&mut self) -> usize {
155 if let Some(species) = &mut self.species {
156 let initial_len = species.len();
157 species.retain(|spec| spec.len() > 0);
158 initial_len - species.len()
159 } else {
160 0
161 }
162 }
163}
164
165impl<C: Chromosome + Clone> Clone for Ecosystem<C> {
166 fn clone(&self) -> Self {
167 Ecosystem {
168 population: self.population.clone(),
169 species: self.species.clone(),
170 }
171 }
172}
173
174impl<C: Chromosome> From<Vec<Phenotype<C>>> for Ecosystem<C> {
175 fn from(phenotypes: Vec<Phenotype<C>>) -> Self {
176 Ecosystem {
177 population: Population::from(phenotypes),
178 species: None,
179 }
180 }
181}
182
183impl<C: Chromosome> From<Population<C>> for Ecosystem<C> {
184 fn from(population: Population<C>) -> Self {
185 Ecosystem {
186 population,
187 species: None,
188 }
189 }
190}
191
192#[cfg(test)]
193mod tests {
194 use super::*;
195 use crate::*;
196
197 #[test]
198 fn test_create_ecosystem() {
199 let codec = FloatCodec::vector(5, 0.0..1.0);
200 let phenotypes = (0..10)
201 .map(|_| Phenotype::from((codec.encode(), 0)))
202 .collect::<Vec<_>>();
203
204 let ecosystem = Ecosystem::from(phenotypes);
205 assert_eq!(ecosystem.population.len(), 10);
206 assert!(ecosystem.species.is_none());
207 }
208}