Skip to main content

radiate_core/genome/
population.rs

1use super::phenotype::Phenotype;
2use crate::species::SpeciesId;
3use crate::{Chromosome, Score};
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6use std::fmt::Debug;
7use std::ops::{Index, IndexMut, Range};
8
9/// A [Population] is a collection of [Phenotype] instances.
10///
11/// This struct is the core collection of individuals
12/// being evolved by the `GeneticEngine`. It can be thought of as a Vec of `Phenotype`s and
13/// is essentially a light wrapper around such a Vec. The [Population] struct, however, has some
14/// additional functionality that allows for sorting and iteration over the individuals in the population.
15///
16/// Note: Although the [Population] offers mut methods to mut the individuals in the population, the [Population]
17/// itself offers no way to increase or decrease the number of individuals in the population. As such, the [Population]
18/// should be thought of as an 'immutable' data structure. If you need to add or remove individuals from the population,
19/// you should create a new [Population] instance with the new individuals. To further facilitate this way of
20/// thinking, the [Population] struct and everything it contains implements the `Clone` trait.
21///
22/// # Type Parameters
23/// - `C`: The type of chromosome used in the genotype, which must implement the `Chromosome` trait.
24#[derive(Default, PartialEq)]
25pub struct Population<C: Chromosome> {
26    individuals: Vec<Phenotype<C>>,
27}
28
29impl<C: Chromosome> Population<C> {
30    pub fn new(individuals: Vec<Phenotype<C>>) -> Self {
31        Population { individuals }
32    }
33
34    pub fn empty() -> Self {
35        Population {
36            individuals: Vec::new(),
37        }
38    }
39
40    pub fn with_capacity(capacity: usize) -> Self {
41        Population {
42            individuals: Vec::with_capacity(capacity),
43        }
44    }
45
46    pub fn get(&self, index: usize) -> Option<&Phenotype<C>> {
47        self.individuals.get(index)
48    }
49
50    pub fn get_mut(&mut self, index: usize) -> Option<&mut Phenotype<C>> {
51        self.individuals.get_mut(index)
52    }
53
54    pub fn push(&mut self, individual: Phenotype<C>) {
55        self.individuals.push(individual);
56    }
57
58    pub fn iter(&self) -> impl Iterator<Item = &Phenotype<C>> {
59        self.individuals.iter()
60    }
61
62    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Phenotype<C>> {
63        self.individuals.iter_mut()
64    }
65
66    #[inline]
67    pub fn iter_scores(&self) -> impl Iterator<Item = &Score> {
68        self.individuals
69            .iter()
70            .filter_map(|individual| individual.score())
71    }
72
73    pub fn iter_species(&self, species_id: SpeciesId) -> impl Iterator<Item = &Phenotype<C>> {
74        self.individuals
75            .iter()
76            .filter(move |val| val.species() == species_id)
77    }
78
79    pub fn sort_by<F>(&mut self, compare: F)
80    where
81        F: FnMut(&Phenotype<C>, &Phenotype<C>) -> std::cmp::Ordering,
82    {
83        self.individuals.sort_unstable_by(compare);
84    }
85
86    pub fn len(&self) -> usize {
87        self.individuals.len()
88    }
89
90    pub fn clear(&mut self) {
91        self.individuals.clear();
92    }
93
94    pub fn is_empty(&self) -> bool {
95        self.individuals.is_empty()
96    }
97
98    pub fn extend(&mut self, other: Self) {
99        self.individuals.extend(other.individuals);
100    }
101
102    pub fn swap_remove(&mut self, index: usize) -> Phenotype<C> {
103        self.individuals.swap_remove(index)
104    }
105
106    pub fn get_pair_mut(
107        &mut self,
108        first: usize,
109        second: usize,
110    ) -> Option<(&mut Phenotype<C>, &mut Phenotype<C>)> {
111        if first == second {
112            None
113        } else if first < second {
114            let (left, right) = self.individuals.split_at_mut(second);
115            Some((&mut left[first], &mut right[0]))
116        } else {
117            let (left, right) = self.individuals.split_at_mut(first);
118            Some((&mut right[0], &mut left[second]))
119        }
120    }
121}
122
123impl<C: Chromosome + Clone> From<&Population<C>> for Population<C> {
124    fn from(population: &Population<C>) -> Self {
125        population.clone()
126    }
127}
128
129impl<C: Chromosome> From<Vec<Phenotype<C>>> for Population<C> {
130    fn from(individuals: Vec<Phenotype<C>>) -> Self {
131        Population { individuals }
132    }
133}
134
135impl<C: Chromosome> AsRef<[Phenotype<C>]> for Population<C> {
136    fn as_ref(&self) -> &[Phenotype<C>] {
137        self.individuals.as_slice()
138    }
139}
140
141impl<C: Chromosome> AsMut<[Phenotype<C>]> for Population<C> {
142    fn as_mut(&mut self) -> &mut [Phenotype<C>] {
143        self.individuals.as_mut()
144    }
145}
146
147impl<C: Chromosome> Index<Range<usize>> for Population<C> {
148    type Output = [Phenotype<C>];
149    fn index(&self, index: Range<usize>) -> &Self::Output {
150        &self.individuals[index]
151    }
152}
153
154impl<C: Chromosome> Index<usize> for Population<C> {
155    type Output = Phenotype<C>;
156
157    fn index(&self, index: usize) -> &Self::Output {
158        &self.individuals[index]
159    }
160}
161
162impl<C: Chromosome> IndexMut<Range<usize>> for Population<C> {
163    fn index_mut(&mut self, index: Range<usize>) -> &mut Self::Output {
164        &mut self.individuals[index]
165    }
166}
167
168impl<C: Chromosome> IndexMut<usize> for Population<C> {
169    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
170        &mut self.individuals[index]
171    }
172}
173
174impl<C: Chromosome + Clone> IntoIterator for Population<C> {
175    type Item = Phenotype<C>;
176    type IntoIter = std::vec::IntoIter<Phenotype<C>>;
177
178    fn into_iter(self) -> Self::IntoIter {
179        self.individuals.into_iter()
180    }
181}
182
183impl<C: Chromosome> FromIterator<Phenotype<C>> for Population<C> {
184    fn from_iter<I: IntoIterator<Item = Phenotype<C>>>(iter: I) -> Self {
185        Population {
186            individuals: iter.into_iter().collect(),
187        }
188    }
189}
190
191/// Create a new instance of the Population from the given size and closure.
192/// This will iterate the given closure `size` times and collect
193/// the results into a Vec of new individuals.
194impl<C: Chromosome, F> From<(usize, F)> for Population<C>
195where
196    F: Fn() -> Phenotype<C>,
197{
198    fn from((size, f): (usize, F)) -> Self {
199        let mut individuals = Vec::with_capacity(size);
200        for _ in 0..size {
201            individuals.push(f());
202        }
203
204        Population { individuals }
205    }
206}
207
208impl<C: Chromosome + Clone> Clone for Population<C> {
209    fn clone(&self) -> Self {
210        Population {
211            individuals: self.individuals.clone(),
212        }
213    }
214}
215
216impl<C: Chromosome + Debug> Debug for Population<C> {
217    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
218        writeln!(f, "Population [")?;
219        for individual in &self.individuals {
220            writeln!(f, "{:?}, ", individual)?;
221        }
222        write!(f, "]")
223    }
224}
225
226#[cfg(feature = "serde")]
227impl<C: Chromosome + Serialize> Serialize for Population<C> {
228    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
229    where
230        S: serde::Serializer,
231    {
232        let phenotypes: Vec<&Phenotype<C>> = self.individuals.iter().collect();
233        phenotypes.serialize(serializer)
234    }
235}
236
237#[cfg(feature = "serde")]
238impl<'de, C: Chromosome + Deserialize<'de>> Deserialize<'de> for Population<C> {
239    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
240    where
241        D: serde::Deserializer<'de>,
242    {
243        let phenotypes = Vec::<Phenotype<C>>::deserialize(deserializer)?;
244
245        Ok(Population {
246            individuals: phenotypes.into_iter().collect(),
247        })
248    }
249}
250
251#[cfg(test)]
252mod test {
253    use super::*;
254    use crate::{CharChromosome, FloatChromosome, Score, objectives::Optimize};
255
256    #[test]
257    fn test_new() {
258        let population = Population::<CharChromosome>::default();
259        assert_eq!(population.len(), 0);
260    }
261
262    #[test]
263    fn test_from_vec() {
264        let individuals = vec![
265            Phenotype::from((vec![CharChromosome::from("hello")], 0)),
266            Phenotype::from((vec![CharChromosome::from("world")], 0)),
267        ];
268
269        let population = Population::new(individuals.clone());
270        assert_eq!(population.len(), individuals.len());
271    }
272
273    #[test]
274    fn test_from_fn() {
275        let population = Population::from((10, || {
276            Phenotype::from((vec![CharChromosome::from("hello")], 0))
277        }));
278
279        assert_eq!(population.len(), 10);
280
281        for individual in population.iter() {
282            assert_eq!(individual.genotype().len(), 1);
283            assert_eq!(individual.genotype().iter().next().unwrap().len(), 5);
284        }
285    }
286
287    #[test]
288    fn test_is_empty() {
289        let population = Population::<CharChromosome>::default();
290        assert!(population.is_empty());
291    }
292
293    #[test]
294    fn test_sort_by() {
295        let mut population = Population::from((10, || {
296            Phenotype::from((vec![FloatChromosome::from((10, -10.0..10.0))], 0))
297        }));
298
299        for i in 0..population.len() {
300            population[i].set_score(Some(Score::from(i)));
301        }
302
303        // deep clone population
304        let mut minimize_population = population.clone();
305        let mut maximize_population = population.clone();
306
307        Optimize::Minimize.sort(&mut minimize_population);
308        Optimize::Maximize.sort(&mut maximize_population);
309
310        for i in 0..population.len() {
311            assert_eq!(minimize_population[i].score().unwrap().as_usize(), i);
312            assert_eq!(
313                maximize_population[i].score().unwrap().as_usize(),
314                population.len() - i - 1
315            );
316        }
317    }
318
319    #[test]
320    fn test_population_get() {
321        let population = Population::new(vec![
322            Phenotype::from((vec![CharChromosome::from("hello")], 0)),
323            Phenotype::from((vec![CharChromosome::from("world")], 0)),
324        ]);
325
326        assert_eq!(population.get(0).unwrap().genotype().len(), 1);
327        assert_eq!(population.get(1).unwrap().genotype().len(), 1);
328        assert_eq!(population.get(0).unwrap().genotype()[0].len(), 5);
329        assert_eq!(population.get(1).unwrap().genotype()[0].len(), 5);
330    }
331
332    #[test]
333    fn test_population_get_mut() {
334        let mut population = Population::new(vec![
335            Phenotype::from((vec![CharChromosome::from("hello")], 0)),
336            Phenotype::from((vec![CharChromosome::from("world")], 0)),
337        ]);
338
339        if let Some(individual) = population.get_mut(0) {
340            individual.set_score(Some(Score::from(1.0)));
341        }
342
343        if let Some(individual) = population.get_mut(1) {
344            individual.set_score(Some(Score::from(2.0)));
345        }
346
347        assert_eq!(population.get(0).unwrap().score().unwrap().as_f32(), 1.0);
348        assert_eq!(population.get(1).unwrap().score().unwrap().as_f32(), 2.0);
349    }
350
351    #[test]
352    #[cfg(feature = "serde")]
353    fn test_population_can_serialize() {
354        let individuals = vec![
355            Phenotype::from((vec![CharChromosome::from("hello")], 0)),
356            Phenotype::from((vec![CharChromosome::from("world")], 0)),
357        ];
358        let population = Population::new(individuals.clone());
359
360        let serialized =
361            serde_json::to_string(&population).expect("Failed to serialize Population");
362        let deserialized: Population<CharChromosome> =
363            serde_json::from_str(&serialized).expect("Failed to deserialize Population");
364
365        assert_eq!(population, deserialized);
366    }
367}