scarlet_queen_core/
replenisher.rs

1//! Mod for `ReplenishIndividualTrait`
2
3use crate::each_crate_individual::EachCrateIndividual;
4
5/// A trait for a individual having a method for creating new individuals with which replenishing a group.
6///
7/// The process corresponds the "Replenish" step of `GroupTrait`.
8///
9/// * `N` - The number of individuals.
10/// * `R` - The number of individuals after individuals are reduced by selector.
11///
12/// # Example
13/// ```
14/// use std::rc::Rc;
15///
16/// use scarlet_queen_core::{EachCrateIndividual, Individual, ReplenisherIndividualTrait};
17///
18/// struct Replenisher<const N: usize, const R: usize>(Rc<Individual<u8>>);
19///
20/// impl<const N: usize, const R: usize> Replenisher<N, R> {
21///     fn new_for_test(id: usize, value: u8) -> Replenisher<N, R> {
22///         Replenisher(Rc::new(Individual::new_with_id(id, value)))
23///     }
24/// }
25///
26/// impl<const N: usize, const R: usize> EachCrateIndividual for Replenisher<N, R> {
27///     type Item = u8;
28///
29///     fn new(individual: &Rc<Individual<Self::Item>>) -> Self {
30///         Replenisher(Rc::clone(individual))
31///     }
32///
33///     fn get_individual(&self) -> &Individual<Self::Item> {
34///         &self.0
35///     }
36/// }
37///
38/// impl<const N: usize, const R: usize> ReplenisherIndividualTrait<N, R> for Replenisher<N, R> {
39///     fn replenish<'a, G>(group: G) -> Vec<<Self as EachCrateIndividual>::Item>
40///         where
41///             G: IntoIterator<Item = &'a Self>,
42///             Self: 'a {
43///         group
44///             .into_iter()
45///             .map(|v| *v.get_value())
46///             .collect::<Vec<u8>>()
47///             .into_iter()
48///             .cycle()
49///             .take(N - R)
50///             .collect::<Vec<u8>>()
51///     }
52/// }
53///
54/// let sample = vec![
55///     Replenisher::<15, 12>::new_for_test(11, 20),
56///     Replenisher::<15, 12>::new_for_test(4, 19),
57///     Replenisher::<15, 12>::new_for_test(1, 17),
58///     Replenisher::<15, 12>::new_for_test(8, 15),
59///     Replenisher::<15, 12>::new_for_test(14, 14),
60///     Replenisher::<15, 12>::new_for_test(10, 12),
61///     Replenisher::<15, 12>::new_for_test(12, 11),
62///     Replenisher::<15, 12>::new_for_test(9, 10),
63///     Replenisher::<15, 12>::new_for_test(13, 9),
64///     Replenisher::<15, 12>::new_for_test(2, 7),
65///     Replenisher::<15, 12>::new_for_test(0, 5),
66///     Replenisher::<15, 12>::new_for_test(6, 2),
67/// ];
68/// assert_eq!(<Replenisher<15, 12> as ReplenisherIndividualTrait<15, 12>>::replenish(&sample), vec![20, 19, 17])
69/// ```
70pub trait ReplenisherIndividualTrait<const N: usize, const R: usize>: EachCrateIndividual {
71    /// Return individuals replenishing a group with.
72    ///
73    /// The elements of `group` must be assigned a number to.
74    /// Also, by a method `next`, `group` must return individuals in order of the fitness.
75    ///
76    /// * `'a` - A lifetime of group.
77    /// * `G` - A type of group.
78    /// * `group` - A value which you are able to get `Self` from. Return values in order of the fitness by a method `next`.
79    fn replenish<'a, G>(group: G) -> Vec<<Self as EachCrateIndividual>::Item>
80    where
81        G: IntoIterator<Item = &'a Self>,
82        Self: 'a;
83}