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}