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}