scarlet_queen_generation/
group.rs1use crate::{error::GenerationError, individual::GenerationIndividual};
2use scarlet_queen_core::{
3 each_individual::{
4 EachCrateIndividual, FitnessIndividualTrait, Individual, ReplenisherIndividualTrait,
5 SelectorIndividualTrait,
6 },
7 group::GroupTrait,
8};
9use scarlet_queen_fitness::pokemon_type::FitnessPokemonType;
10use scarlet_queen_replenisher::from_top::FromTopReplenisherIndividual;
11use scarlet_queen_selector::rank::RankSelectorIndividual;
12use std::{
13 collections::{HashMap, HashSet},
14 fmt::Debug,
15 mem::swap,
16 rc::Rc,
17 slice::Iter,
18};
19
20pub struct Group<T, FI, SI, RI, const N: usize, const R: usize>
21where
22 T: Clone,
23 FI: EachCrateIndividual<Item = T> + FitnessIndividualTrait,
24 SI: EachCrateIndividual<Item = T> + SelectorIndividualTrait<R>,
25 RI: EachCrateIndividual<Item = T> + ReplenisherIndividualTrait<N, R>,
26{
27 data: Vec<GenerationIndividual<T, FI, SI, RI, N, R>>,
28}
29
30impl<T, FI, SI, RI, const N: usize, const R: usize> GroupTrait<T, N, R>
31 for Group<T, FI, SI, RI, N, R>
32where
33 T: Clone + Debug,
34 FI: EachCrateIndividual<Item = T> + FitnessIndividualTrait,
35 SI: EachCrateIndividual<Item = T> + SelectorIndividualTrait<R>,
36 RI: EachCrateIndividual<Item = T> + ReplenisherIndividualTrait<N, R>,
37{
38 type Err = GenerationError;
39
40 fn new(data: [T; N]) -> Self {
41 Group {
42 data: data
43 .into_iter()
44 .enumerate()
45 .map(|(i, v)| GenerationIndividual::new(&Rc::new(Individual::new_with_id(i, v))))
46 .collect::<Vec<GenerationIndividual<T, FI, SI, RI, N, R>>>(),
47 }
48 }
49
50 fn one_cycle(&mut self) -> Result<(), Self::Err> {
51 let scores: HashMap<usize, usize> = GenerationIndividual::fitness_group(&*self);
52 let selector: HashSet<usize> = GenerationIndividual::selected_ids(&*self, scores)
53 .map_err(|v| GenerationError::SelectorError(format!("{v:?}")))?;
54 let mut data_for_edit: Vec<GenerationIndividual<T, FI, SI, RI, N, R>> = Vec::new();
55 swap(&mut data_for_edit, &mut self.data);
56 self.data = data_for_edit
57 .into_iter()
58 .filter_map(|v| {
59 if selector.contains(&v.get_id()) {
60 Some(v)
61 } else {
62 None
63 }
64 })
65 .collect::<Vec<GenerationIndividual<T, FI, SI, RI, N, R>>>();
66 let new_individuals: Vec<T> = GenerationIndividual::replenish(&*self);
67 self.data.extend(
68 new_individuals
69 .into_iter()
70 .map(|v| GenerationIndividual::new(&Rc::new(Individual::new_with_id(0, v)))),
71 );
72 self.reset_id();
73 Ok(())
74 }
75
76 fn one_cycle_out<W>(&mut self, out: &mut W) -> Result<(), Self::Err>
77 where
78 W: std::io::Write,
79 {
80 writeln!(out, "=== GROUP ===")?;
81 self.data
82 .iter()
83 .try_for_each(|v| writeln!(out, "id: {}, value: {:?}", v.get_id(), v.get_value()))?;
84 let scores: HashMap<usize, usize> = GenerationIndividual::fitness_group(&*self);
85
86 let scores_vec: Vec<usize> = (0..N)
87 .map(|i| *scores.get(&i).unwrap())
88 .collect::<Vec<usize>>();
89 writeln!(out, "=== SCORE ===")?;
90 scores_vec
91 .iter()
92 .enumerate()
93 .try_for_each(|(i, v)| writeln!(out, "id: {i}, value: {v:?}"))?;
94
95 let selector: HashSet<usize> = GenerationIndividual::selected_ids(&*self, scores)
96 .map_err(|v| GenerationError::SelectorError(format!("{v:?}")))?;
97 let mut data_for_edit: Vec<GenerationIndividual<T, FI, SI, RI, N, R>> = Vec::new();
98 swap(&mut data_for_edit, &mut self.data);
99 self.data = data_for_edit
100 .into_iter()
101 .filter_map(|v| {
102 if selector.contains(&v.get_id()) {
103 Some(v)
104 } else {
105 None
106 }
107 })
108 .collect::<Vec<GenerationIndividual<T, FI, SI, RI, N, R>>>();
109
110 let new_individuals: Vec<T> = GenerationIndividual::replenish(&*self);
111 self.data.extend(
112 new_individuals
113 .into_iter()
114 .map(|v| GenerationIndividual::new(&Rc::new(Individual::new_with_id(0, v)))),
115 );
116 self.reset_id();
117 writeln!(out)?;
118 Ok(())
119 }
120
121 fn iter<'a>(&'a self) -> impl Iterator<Item = &'a Individual<T>>
122 where
123 T: 'a,
124 {
125 self.data.iter().map(|v| v.get_individual())
126 }
127}
128
129impl<'a, T, FI, SI, RI, const N: usize, const R: usize> IntoIterator
130 for &'a Group<T, FI, SI, RI, N, R>
131where
132 T: Clone,
133 FI: EachCrateIndividual<Item = T> + FitnessIndividualTrait,
134 SI: EachCrateIndividual<Item = T> + SelectorIndividualTrait<R>,
135 RI: EachCrateIndividual<Item = T> + ReplenisherIndividualTrait<N, R>,
136{
137 type IntoIter = Iter<'a, GenerationIndividual<T, FI, SI, RI, N, R>>;
138 type Item = &'a GenerationIndividual<T, FI, SI, RI, N, R>;
139
140 fn into_iter(self) -> Self::IntoIter {
141 self.data.iter()
142 }
143}
144
145pub type PokemonTypeGroup<P, const N: usize, const R: usize> = Group<
146 P,
147 FitnessPokemonType<P>,
148 RankSelectorIndividual<P, R>,
149 FromTopReplenisherIndividual<P, N, R>,
150 N,
151 R,
152>;
153
154#[cfg(test)]
155mod tests {
156 #[test]
157 fn test_group_grouptrait_oneloop() {}
158}