scarlet_queen_selector/
rank.rs

1use std::{
2    collections::{HashMap, HashSet},
3    rc::Rc,
4};
5
6use scarlet_queen_core::each_individual::{
7    EachCrateIndividual, Individual, SelectorIndividualTrait,
8};
9
10use crate::error::SelectorError;
11
12pub struct RankSelectorIndividual<T, const R: usize> {
13    individual: Rc<Individual<T>>,
14}
15
16impl<T, const R: usize> EachCrateIndividual for RankSelectorIndividual<T, R> {
17    type Item = T;
18
19    fn new(individual: &Rc<Individual<T>>) -> Self {
20        RankSelectorIndividual {
21            individual: Rc::clone(individual),
22        }
23    }
24
25    fn get_id(&self) -> usize {
26        self.individual.get_id()
27    }
28
29    fn get_value(&self) -> &T {
30        self.individual.get_value()
31    }
32
33    fn get_individual(&self) -> &Individual<T> {
34        &self.individual
35    }
36}
37
38impl<T, const R: usize> SelectorIndividualTrait<R> for RankSelectorIndividual<T, R> {
39    type Err = SelectorError;
40
41    fn selected_ids<'a, U>(
42        group: U,
43        scores: HashMap<usize, usize>,
44    ) -> Result<HashSet<usize>, Self::Err>
45    where
46        U: IntoIterator<Item = &'a Self>,
47        Self: 'a,
48    {
49        let group: Vec<&Self> = group.into_iter().collect::<Vec<&Self>>();
50
51        if group.len() < R {
52            return Err(SelectorError::TooFewGroupError);
53        };
54
55        let mut id_with_score: Vec<(usize, usize)> = group
56            .into_iter()
57            .map(|v| {
58                let id: usize = v.get_id();
59                scores
60                    .get(&id)
61                    .map_or(Err(SelectorError::BadScoreDataError), |&v| Ok((id, v)))
62            })
63            .collect::<Result<Vec<(usize, usize)>, SelectorError>>()?;
64
65        id_with_score.sort_by_key(|&(_, v)| -(v as isize));
66
67        Ok(id_with_score
68            .into_iter()
69            .take(R)
70            .map(|(id, _)| id)
71            .collect::<HashSet<usize>>())
72    }
73}