scarlet_queen_selector/
tournament.rs1use std::{
2 collections::{HashMap, HashSet},
3 rc::Rc,
4};
5
6use scarlet_queen_core::{EachCrateIndividual, Individual, SelectorIndividualTrait};
7
8use crate::error::SelectorError;
9
10#[derive(Debug)]
11pub struct TournamentSelectorIndividual<T, const R: usize> {
12 individual: Rc<Individual<T>>,
13}
14
15impl<T, const R: usize> EachCrateIndividual for TournamentSelectorIndividual<T, R> {
16 type Item = T;
17
18 fn new(individual: &Rc<Individual<T>>) -> Self {
19 TournamentSelectorIndividual {
20 individual: Rc::clone(individual),
21 }
22 }
23
24 fn get_id(&self) -> usize {
25 self.individual.get_id()
26 }
27
28 fn get_value(&self) -> &T {
29 self.individual.get_value()
30 }
31
32 fn get_individual(&self) -> &Individual<T> {
33 &self.individual
34 }
35}
36
37impl<T, const R: usize> SelectorIndividualTrait<R> for TournamentSelectorIndividual<T, R> {
38 type Err = SelectorError;
39
40 fn selected_ids<'a, G>(
41 group: G,
42 scores: HashMap<usize, usize>,
43 ) -> Result<HashSet<usize>, Self::Err>
44 where
45 G: IntoIterator<Item = &'a Self>,
46 Self: 'a,
47 {
48 let group: Vec<&Self> = group.into_iter().collect::<Vec<&Self>>();
49
50 if group.len() < R {
51 return Err(SelectorError::TooFewGroupError);
52 };
53
54 let mut id_with_score: Vec<(usize, usize)> = group
55 .into_iter()
56 .map(|v| {
57 let id: usize = v.get_id();
58 scores
59 .get(&id)
60 .map_or(Err(SelectorError::BadScoreDataError), |&v| Ok((id, v)))
61 })
62 .collect::<Result<Vec<(usize, usize)>, SelectorError>>()?;
63
64 id_with_score.sort_by_key(|&(_, v)| -(v as isize));
65
66 Ok(id_with_score
67 .into_iter()
68 .take(R)
69 .map(|(id, _)| id)
70 .collect::<HashSet<usize>>())
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use std::{
77 collections::{HashMap, HashSet},
78 rc::Rc,
79 };
80
81 use scarlet_queen_core::{EachCrateIndividual, Individual, SelectorIndividualTrait};
82
83 use crate::tournament::TournamentSelectorIndividual;
84
85 #[test]
86 fn test_tournamentselectorindividual_selectorindividualtrait_selectedids() {
87 let group: Vec<TournamentSelectorIndividual<&'static str, 2>> = vec![
88 TournamentSelectorIndividual::new(&Rc::new(Individual::new_with_id(1, "A"))),
89 TournamentSelectorIndividual::new(&Rc::new(Individual::new_with_id(2, "A"))),
90 TournamentSelectorIndividual::new(&Rc::new(Individual::new_with_id(3, "B"))),
91 TournamentSelectorIndividual::new(&Rc::new(Individual::new_with_id(4, "B"))),
92 TournamentSelectorIndividual::new(&Rc::new(Individual::new_with_id(5, "C"))),
93 TournamentSelectorIndividual::new(&Rc::new(Individual::new_with_id(6, "C"))),
94 ];
95 let scores: HashMap<usize, usize> =
96 HashMap::from([(1, 10), (2, 10), (3, 20), (4, 20), (5, 30), (6, 30)]);
97
98 let selected = <TournamentSelectorIndividual<&'static str, 2> as SelectorIndividualTrait<
99 2,
100 >>::selected_ids(&group, scores)
101 .unwrap();
102 assert_eq!(selected, HashSet::from([5, 6]));
103 }
104}