scarlet_queen_core/
selector.rs

1//! Mod for `SelectorIndividualTrait`
2
3use std::{
4    collections::{HashMap, HashSet},
5    fmt::Debug,
6};
7
8use crate::each_crate_individual::EachCrateIndividual;
9
10/// A trait for a individual having a method for selecting individuals based on fitness scores.
11///
12/// The process corresponds the "Select" step of `GroupTrait`.
13///
14/// * `R` - The number of individuals after individuals are reduced by selector.
15///
16/// # Example
17/// ```
18/// use std::{collections::{HashMap, HashSet}, rc::Rc};
19///
20/// use scarlet_queen_core::{EachCrateIndividual, Individual, SelectorIndividualTrait};
21/// struct Selector<const R: usize>(Rc<Individual<u8>>);
22///
23/// impl<const R: usize> Selector<R> {
24///     fn new_for_test(id: usize, value: u8) -> Selector<R> {
25///         Selector(Rc::new(Individual::new_with_id(id, value)))
26///     }
27/// }
28///
29/// impl<const R: usize> EachCrateIndividual for Selector<R> {
30///     type Item = u8;
31///
32///     fn new(individual: &Rc<Individual<Self::Item>>) -> Self {
33///         Selector(Rc::clone(individual))
34///     }
35///
36///     fn get_individual(&self) -> &Individual<Self::Item> {
37///         &self.0
38///     }
39/// }
40///
41/// impl<const R: usize> SelectorIndividualTrait<R> for Selector<R> {
42///     type Err = String;
43///
44///     fn selected_ids<'a, G>(
45///         group: G,
46///         _scores: std::collections::HashMap<usize, usize>,
47///     ) -> Result<std::collections::HashSet<usize>, Self::Err>
48///         where
49///             G: IntoIterator<Item = &'a Self>,
50///             Self: 'a {
51///         let group: Vec<&Selector<R>> = group.into_iter().collect::<Vec<&Selector<R>>>();
52///         if group.len() < R {
53///             return Err(String::from("The size of group is not enough."));
54///         };
55///
56///         Ok(
57///             group
58///                 .into_iter()
59///                 .map(|(v)| v.get_id())
60///                 .take(R)
61///                 .collect::<HashSet<usize>>()
62///         )
63///     }
64/// }
65///
66///
67/// let sample: Vec<Selector<12>> = vec![
68///     Selector::<12>::new_for_test(11, 20),
69///     Selector::<12>::new_for_test(4, 19),
70///     Selector::<12>::new_for_test(1, 17),
71///     Selector::<12>::new_for_test(8, 15),
72///     Selector::<12>::new_for_test(14, 14),
73///     Selector::<12>::new_for_test(10, 12),
74///     Selector::<12>::new_for_test(12, 11),
75///     Selector::<12>::new_for_test(9, 10),
76///     Selector::<12>::new_for_test(13, 9),
77///     Selector::<12>::new_for_test(2, 7),
78///     Selector::<12>::new_for_test(0, 5),
79///     Selector::<12>::new_for_test(6, 2),
80///     Selector::<12>::new_for_test(5, 1),
81///     Selector::<12>::new_for_test(7, 1),
82///     Selector::<12>::new_for_test(3, 0),
83/// ];
84/// let scores: HashMap<usize, usize> = vec![
85///     (0, 4),
86///     (1, 12),
87///     (2, 5),
88///     (3, 0),
89///     (4, 13),
90///     (5, 1),
91///     (6, 2),
92///     (7, 1),
93///     (8, 11),
94///     (9, 7),
95///     (10, 9),
96///     (11, 14),
97///     (12, 8),
98///     (13, 6),
99///     (14, 10),
100/// ].into_iter().collect::<HashMap<usize, usize>>();
101/// assert_eq!(<Selector<12> as SelectorIndividualTrait<12>>::selected_ids(&sample, scores), Ok(vec![0usize, 1, 2, 4, 6, 8, 9, 10, 11, 12, 13, 14].into_iter().collect::<HashSet<usize>>()));
102/// ```
103pub trait SelectorIndividualTrait<const R: usize>: EachCrateIndividual {
104    /// An error of selector.
105    /// This is occurred when bad scores are given to this.
106    type Err: Debug;
107
108    /// Select individuals. Return ids of selected individuals.
109    ///
110    /// The elements of `group` must be assigned a number to.
111    /// Also, by a method `next`, `group` must return individuals in order of the fitness.
112    ///
113    /// * `'a` - A lifetime of group.
114    /// * `G` - A type of group.
115    /// * `group` - A value which you are able to get `Self` from. Return values in order of the fitnes by a method `next`s.
116    /// * `scores` - Fitness scores. The key is an id of individual, and the value is a fitness score.
117    fn selected_ids<'a, G>(
118        group: G,
119        scores: HashMap<usize, usize>,
120    ) -> Result<HashSet<usize>, Self::Err>
121    where
122        G: IntoIterator<Item = &'a Self>,
123        Self: 'a;
124}