1use scarlet_queen_core::each_individual::{
2 EachCrateIndividual, FitnessIndividualTrait, Individual, ReplenisherIndividualTrait,
3 SelectorIndividualTrait,
4};
5use std::{
6 collections::{HashMap, HashSet},
7 rc::Rc,
8};
9
10pub trait GenerationIndividualTrait<T, const N: usize, const R: usize>:
11 EachCrateIndividual<Item = T>
12 + FitnessIndividualTrait
13 + SelectorIndividualTrait<R>
14 + ReplenisherIndividualTrait<N, R>
15{
16}
17
18#[derive(Clone, PartialEq, Eq, Debug)]
19pub struct GenerationIndividual<T, FI, SI, RI, const N: usize, const R: usize>
20where
21 FI: EachCrateIndividual<Item = T> + FitnessIndividualTrait,
22 SI: EachCrateIndividual<Item = T> + SelectorIndividualTrait<R>,
23 RI: EachCrateIndividual<Item = T> + ReplenisherIndividualTrait<N, R>,
24{
25 #[allow(dead_code)]
26 individual: Rc<Individual<T>>,
27 fitness_individual: FI,
28 selector_individual: SI,
29 replenisher_individual: RI,
30}
31
32impl<T, FI, SI, RI, const N: usize, const R: usize> GenerationIndividual<T, FI, SI, RI, N, R>
33where
34 FI: EachCrateIndividual<Item = T> + FitnessIndividualTrait,
35 SI: EachCrateIndividual<Item = T> + SelectorIndividualTrait<R>,
36 RI: EachCrateIndividual<Item = T> + ReplenisherIndividualTrait<N, R>,
37{
38 pub fn get_individual(&self) -> &Individual<T> {
39 &self.individual
40 }
41
42 pub fn get_fitness_individual(&self) -> &FI {
43 &self.fitness_individual
44 }
45
46 pub fn get_selector_individual(&self) -> &SI {
47 &self.selector_individual
48 }
49
50 pub fn get_replenisher_individual(&self) -> &RI {
51 &self.replenisher_individual
52 }
53}
54
55impl<T, FI, SI, RI, const N: usize, const R: usize> EachCrateIndividual
56 for GenerationIndividual<T, FI, SI, RI, N, R>
57where
58 FI: EachCrateIndividual<Item = T> + FitnessIndividualTrait,
59 SI: EachCrateIndividual<Item = T> + SelectorIndividualTrait<R>,
60 RI: EachCrateIndividual<Item = T> + ReplenisherIndividualTrait<N, R>,
61{
62 type Item = T;
63
64 fn new(individual: &Rc<Individual<T>>) -> Self {
65 GenerationIndividual {
66 individual: Rc::clone(individual),
67 fitness_individual: FI::new(individual),
68 selector_individual: SI::new(individual),
69 replenisher_individual: RI::new(individual),
70 }
71 }
72
73 fn get_individual(&self) -> &Individual<T> {
74 &self.individual
75 }
76}
77
78impl<T, FI, SI, RI, const N: usize, const R: usize> FitnessIndividualTrait
79 for GenerationIndividual<T, FI, SI, RI, N, R>
80where
81 FI: EachCrateIndividual<Item = T> + FitnessIndividualTrait,
82 SI: EachCrateIndividual<Item = T> + SelectorIndividualTrait<R>,
83 RI: EachCrateIndividual<Item = T> + ReplenisherIndividualTrait<N, R>,
84{
85 fn fitness(&self, other: &Self) -> usize {
86 self.fitness_individual.fitness(&other.fitness_individual)
87 }
88}
89
90impl<T, FI, SI, RI, const N: usize, const R: usize> SelectorIndividualTrait<R>
91 for GenerationIndividual<T, FI, SI, RI, N, R>
92where
93 FI: EachCrateIndividual<Item = T> + FitnessIndividualTrait,
94 SI: EachCrateIndividual<Item = T> + SelectorIndividualTrait<R>,
95 RI: EachCrateIndividual<Item = T> + ReplenisherIndividualTrait<N, R>,
96{
97 type Err = <SI as SelectorIndividualTrait<R>>::Err;
98
99 fn selected_ids<'a, U>(
100 group: U,
101 score: HashMap<usize, usize>,
102 ) -> Result<HashSet<usize>, Self::Err>
103 where
104 U: IntoIterator<Item = &'a Self>,
105 Self: 'a,
106 {
107 SI::selected_ids(group.into_iter().map(|v| &v.selector_individual), score)
108 }
109}
110
111impl<T, FI, SI, RI, const N: usize, const R: usize> ReplenisherIndividualTrait<N, R>
112 for GenerationIndividual<T, FI, SI, RI, N, R>
113where
114 FI: EachCrateIndividual<Item = T> + FitnessIndividualTrait,
115 SI: EachCrateIndividual<Item = T> + SelectorIndividualTrait<R>,
116 RI: EachCrateIndividual<Item = T> + ReplenisherIndividualTrait<N, R>,
117{
118 fn replenish<'a, U>(group: U) -> Vec<T>
119 where
120 U: IntoIterator<Item = &'a Self>,
121 Self: 'a,
122 {
123 RI::replenish(group.into_iter().map(|v| &v.replenisher_individual))
124 }
125}
126
127impl<T, FI, SI, RI, const N: usize, const R: usize> GenerationIndividualTrait<T, N, R>
128 for GenerationIndividual<T, FI, SI, RI, N, R>
129where
130 FI: EachCrateIndividual<Item = T> + FitnessIndividualTrait,
131 SI: EachCrateIndividual<Item = T> + SelectorIndividualTrait<R>,
132 RI: EachCrateIndividual<Item = T> + ReplenisherIndividualTrait<N, R>,
133{
134}
135
136#[cfg(test)]
137mod tests {
138 use crate::individual::GenerationIndividual;
139 use scarlet_queen_core::each_individual::{
140 EachCrateIndividual, FitnessIndividualTrait, Individual, ReplenisherIndividualTrait,
141 SelectorIndividualTrait,
142 };
143 use scarlet_queen_selector::error::SelectorError;
144 use std::{
145 collections::{HashMap, HashSet},
146 rc::Rc,
147 };
148
149 #[derive(PartialEq, Eq, Debug)]
150 struct FITraitSample {
151 value: Rc<Individual<u8>>,
152 }
153 impl EachCrateIndividual for FITraitSample {
154 type Item = u8;
155 fn new(individual: &Rc<Individual<u8>>) -> Self {
156 FITraitSample {
157 value: Rc::clone(individual),
158 }
159 }
160 fn get_individual(&self) -> &Individual<u8> {
161 &self.value
162 }
163 }
164 impl FitnessIndividualTrait for FITraitSample {
165 fn fitness(&self, other: &Self) -> usize {
166 if self.get_value() >= other.get_value() {
167 1
168 } else {
169 0
170 }
171 }
172 }
173 #[derive(PartialEq, Eq, Debug)]
174 struct SITraitSample<const R: usize> {
175 value: Rc<Individual<u8>>,
176 }
177 impl<const R: usize> EachCrateIndividual for SITraitSample<R> {
178 type Item = u8;
179 fn new(individual: &Rc<Individual<u8>>) -> Self {
180 SITraitSample {
181 value: Rc::clone(individual),
182 }
183 }
184 fn get_individual(&self) -> &Individual<u8> {
185 &self.value
186 }
187 }
188 impl<const R: usize> SelectorIndividualTrait<R> for SITraitSample<R> {
189 type Err = SelectorError;
190 fn selected_ids<'a, U>(
191 group: U,
192 scores: HashMap<usize, usize>,
193 ) -> Result<HashSet<usize>, Self::Err>
194 where
195 U: IntoIterator<Item = &'a Self>,
196 Self: 'a,
197 {
198 let mut set: HashSet<usize> = HashSet::new();
199 let mut group_and_scores: Vec<(usize, usize)> = group
200 .into_iter()
201 .map(|v| {
202 let id: usize = v.get_id();
203 scores
204 .get(&id)
205 .map_or(Err(SelectorError::BadScoreDataError), |v| Ok((id, *v)))
206 })
207 .collect::<Result<Vec<(usize, usize)>, SelectorError>>()?;
208 group_and_scores.sort_by_key(|&(_, v)| -(v as isize));
209 for (id, _) in group_and_scores.iter().take(group_and_scores.len() / 2) {
210 set.insert(*id);
211 }
212 Ok(set)
213 }
214 }
215 #[derive(PartialEq, Eq, Debug)]
216 struct RITraitSample<const N: usize, const R: usize> {
217 value: Rc<Individual<u8>>,
218 }
219 impl<const N: usize, const R: usize> EachCrateIndividual for RITraitSample<N, R> {
220 type Item = u8;
221 fn new(individual: &Rc<Individual<u8>>) -> Self {
222 RITraitSample {
223 value: Rc::clone(individual),
224 }
225 }
226 fn get_individual(&self) -> &Individual<u8> {
227 &self.value
228 }
229 }
230 impl<const N: usize, const R: usize> ReplenisherIndividualTrait<N, R> for RITraitSample<N, R> {
231 fn replenish<'a, U>(group: U) -> Vec<u8>
232 where
233 U: IntoIterator<Item = &'a Self>,
234 Self: 'a,
235 {
236 let group: Vec<u8> = group.into_iter().map(|v| *v.get_value()).collect();
237 group.into_iter().cycle().take(N - R).collect::<Vec<u8>>()
238 }
239 }
240 type GenerationIndividualSample<const N: usize, const R: usize> =
241 GenerationIndividual<u8, FITraitSample, SITraitSample<R>, RITraitSample<N, R>, N, R>;
242
243 #[test]
244 fn test_generationindividual_getfitnessindividual() {
245 let testcases: Vec<(GenerationIndividualSample<10, 8>, FITraitSample)> = vec![
246 (
247 GenerationIndividual::new(&Rc::new(Individual::new_with_id(0, 8))),
248 FITraitSample::new(&Rc::new(Individual::new_with_id(0, 8))),
249 ),
250 (
251 GenerationIndividual::new(&Rc::new(Individual::new_with_id(0, 0))),
252 FITraitSample::new(&Rc::new(Individual::new_with_id(0, 0))),
253 ),
254 (
255 GenerationIndividual::new(&Rc::new(Individual::new_with_id(1, 12))),
256 FITraitSample::new(&Rc::new(Individual::new_with_id(1, 12))),
257 ),
258 ];
259 for (arg, result) in testcases.into_iter() {
260 assert_eq!(arg.get_fitness_individual(), &result);
261 }
262 }
263
264 #[test]
265 fn test_generationindividual_getselectorindividual() {
266 let testcases: Vec<(GenerationIndividualSample<10, 8>, SITraitSample<8>)> = vec![
267 (
268 GenerationIndividual::new(&Rc::new(Individual::new_with_id(0, 8))),
269 SITraitSample::new(&Rc::new(Individual::new_with_id(0, 8))),
270 ),
271 (
272 GenerationIndividual::new(&Rc::new(Individual::new_with_id(0, 0))),
273 SITraitSample::new(&Rc::new(Individual::new_with_id(0, 0))),
274 ),
275 (
276 GenerationIndividual::new(&Rc::new(Individual::new_with_id(1, 12))),
277 SITraitSample::new(&Rc::new(Individual::new_with_id(1, 12))),
278 ),
279 ];
280 for (arg, result) in testcases.into_iter() {
281 assert_eq!(arg.get_selector_individual(), &result);
282 }
283 }
284
285 #[test]
286 fn test_generationindividual_getreplenisherindividual() {
287 let testcases: Vec<(GenerationIndividualSample<10, 8>, RITraitSample<10, 8>)> = vec![
288 (
289 GenerationIndividual::new(&Rc::new(Individual::new_with_id(0, 8))),
290 RITraitSample::new(&Rc::new(Individual::new_with_id(0, 8))),
291 ),
292 (
293 GenerationIndividual::new(&Rc::new(Individual::new_with_id(0, 0))),
294 RITraitSample::new(&Rc::new(Individual::new_with_id(0, 0))),
295 ),
296 (
297 GenerationIndividual::new(&Rc::new(Individual::new_with_id(1, 12))),
298 RITraitSample::new(&Rc::new(Individual::new_with_id(1, 12))),
299 ),
300 ];
301 for (arg, result) in testcases.into_iter() {
302 assert_eq!(arg.get_replenisher_individual(), &result);
303 }
304 }
305
306 #[test]
307 fn test_generationindividual_eachcrateindividual_new() {
308 let testcases: Vec<(Rc<Individual<u8>>, GenerationIndividualSample<10, 8>)> = vec![
309 (
310 Rc::new(Individual::new_with_id(0, 8)),
311 GenerationIndividualSample {
312 individual: Rc::new(Individual::new_with_id(0, 8)),
313 fitness_individual: FITraitSample::new(&Rc::new(Individual::new_with_id(0, 8))),
314 selector_individual: SITraitSample::new(&Rc::new(Individual::new_with_id(
315 0, 8,
316 ))),
317 replenisher_individual: RITraitSample::new(&Rc::new(Individual::new_with_id(
318 0, 8,
319 ))),
320 },
321 ),
322 (
323 Rc::new(Individual::new_with_id(0, 0)),
324 GenerationIndividualSample {
325 individual: Rc::new(Individual::new_with_id(0, 0)),
326 fitness_individual: FITraitSample::new(&Rc::new(Individual::new_with_id(0, 0))),
327 selector_individual: SITraitSample::new(&Rc::new(Individual::new_with_id(
328 0, 0,
329 ))),
330 replenisher_individual: RITraitSample::new(&Rc::new(Individual::new_with_id(
331 0, 0,
332 ))),
333 },
334 ),
335 (
336 Rc::new(Individual::new_with_id(1, 12)),
337 GenerationIndividualSample {
338 individual: Rc::new(Individual::new_with_id(1, 12)),
339 fitness_individual: FITraitSample::new(&Rc::new(Individual::new_with_id(
340 1, 12,
341 ))),
342 selector_individual: SITraitSample::new(&Rc::new(Individual::new_with_id(
343 1, 12,
344 ))),
345 replenisher_individual: RITraitSample::new(&Rc::new(Individual::new_with_id(
346 1, 12,
347 ))),
348 },
349 ),
350 ];
351 for (arg, result) in testcases.into_iter() {
352 assert_eq!(GenerationIndividualSample::new(&arg), result);
353 }
354 }
355
356 #[test]
357 fn test_generationindividual_eachcrateindividual_getid() {
358 let testcases: Vec<(GenerationIndividualSample<10, 8>, usize)> = vec![
359 (
360 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(0, 8))),
361 0,
362 ),
363 (
364 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(0, 0))),
365 0,
366 ),
367 (
368 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(1, 12))),
369 1,
370 ),
371 ];
372 for (arg, result) in testcases.into_iter() {
373 assert_eq!(arg.get_id(), result);
374 }
375 }
376
377 #[test]
378 fn test_generationindividual_eachcrateindividual_getvalue() {
379 let testcases: Vec<(GenerationIndividualSample<10, 8>, u8)> = vec![
380 (
381 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(0, 8))),
382 8,
383 ),
384 (
385 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(0, 0))),
386 0,
387 ),
388 (
389 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(1, 12))),
390 12,
391 ),
392 ];
393 for (arg, result) in testcases.into_iter() {
394 assert_eq!(arg.get_value(), &result);
395 }
396 }
397
398 #[test]
399 fn test_generationindividual_fitnessindividual_fitness() {
400 let testcases: Vec<(
401 GenerationIndividualSample<10, 8>,
402 GenerationIndividualSample<10, 8>,
403 )> = vec![
404 (
405 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(0, 8))),
406 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(1, 6))),
407 ),
408 (
409 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(0, 8))),
410 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(1, 10))),
411 ),
412 (
413 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(0, 6))),
414 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(1, 6))),
415 ),
416 (
417 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(0, 0))),
418 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(1, 0))),
419 ),
420 (
421 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(0, 13))),
422 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(1, 19))),
423 ),
424 ];
425 for (arg_1, arg_2) in testcases.into_iter() {
426 assert_eq!(
427 <GenerationIndividualSample<10, 8> as FitnessIndividualTrait>::fitness(
428 &arg_1, &arg_2
429 ),
430 <FITraitSample as FitnessIndividualTrait>::fitness(
431 arg_1.get_fitness_individual(),
432 arg_2.get_fitness_individual()
433 )
434 )
435 }
436 }
437
438 #[test]
439 fn test_generationindividual_selectorindividual_makeselector() {
440 {
441 let mut testcase: Vec<GenerationIndividualSample<5, 4>> = vec![
442 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(0, 6))),
443 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(1, 12))),
444 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(2, 8))),
445 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(3, 8))),
446 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(4, 2))),
447 ];
448 let score: HashMap<usize, usize> = GenerationIndividualSample::fitness_group(&testcase);
449 assert_eq!(
450 <GenerationIndividualSample<5, 4> as SelectorIndividualTrait<4>>::selected_ids(
451 &testcase,
452 score.clone()
453 ),
454 <SITraitSample<4> as SelectorIndividualTrait<4>>::selected_ids(
455 testcase.iter_mut().map(|v| &v.selector_individual),
456 score
457 )
458 )
459 }
460 {
461 let mut testcase: Vec<GenerationIndividualSample<0, 0>> = vec![];
462 let score: HashMap<usize, usize> = GenerationIndividualSample::fitness_group(&testcase);
463 assert_eq!(
464 <GenerationIndividualSample<0, 0> as SelectorIndividualTrait<0>>::selected_ids(
465 &testcase,
466 score.clone()
467 ),
468 <SITraitSample<0> as SelectorIndividualTrait<0>>::selected_ids(
469 testcase.iter_mut().map(|v| &v.selector_individual),
470 score
471 )
472 )
473 }
474 {
475 let mut testcase: Vec<GenerationIndividualSample<10, 8>> = vec![
476 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(0, 7))),
477 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(1, 12))),
478 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(2, 4))),
479 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(3, 6))),
480 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(4, 3))),
481 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(5, 10))),
482 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(6, 6))),
483 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(7, 8))),
484 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(8, 19))),
485 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(9, 7))),
486 ];
487 let score: HashMap<usize, usize> = GenerationIndividualSample::fitness_group(&testcase);
488 assert_eq!(
489 <GenerationIndividualSample<10, 8> as SelectorIndividualTrait<8>>::selected_ids(
490 &testcase,
491 score.clone()
492 ),
493 <SITraitSample<8> as SelectorIndividualTrait<8>>::selected_ids(
494 testcase.iter_mut().map(|v| &v.selector_individual),
495 score
496 )
497 )
498 }
499 }
500
501 #[test]
502 fn test_generationindividual_replenisherindividual_replenisher() {
503 {
504 let testcase: Vec<GenerationIndividualSample<5, 2>> = vec![
505 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(0, 12))),
506 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(1, 8))),
507 ];
508 assert_eq!(
509 <GenerationIndividualSample<5, 2> as ReplenisherIndividualTrait<5, 2>>::replenish(
510 &testcase
511 ),
512 <RITraitSample<5, 2> as ReplenisherIndividualTrait<5, 2>>::replenish(
513 testcase.iter().map(|v| v.get_replenisher_individual())
514 )
515 )
516 }
517 {
518 let testcase: Vec<GenerationIndividualSample<0, 0>> = vec![];
519 assert_eq!(
520 <GenerationIndividualSample<0, 0> as ReplenisherIndividualTrait<0, 0>>::replenish(
521 &testcase
522 ),
523 <RITraitSample<0, 0> as ReplenisherIndividualTrait<0, 0>>::replenish(
524 testcase.iter().map(|v| v.get_replenisher_individual())
525 )
526 )
527 }
528 {
529 let testcase: Vec<GenerationIndividualSample<10, 8>> = vec![
530 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(0, 7))),
531 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(1, 12))),
532 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(2, 10))),
533 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(3, 8))),
534 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(4, 19))),
535 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(5, 3))),
536 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(6, 8))),
537 GenerationIndividualSample::new(&Rc::new(Individual::new_with_id(7, 12))),
538 ];
539 assert_eq!(
540 <GenerationIndividualSample<10, 8> as ReplenisherIndividualTrait<10, 8>>::replenish(
541 &testcase
542 ),
543 <RITraitSample<10, 8> as ReplenisherIndividualTrait<10, 8>>::replenish(
544 testcase.iter().map(|v| v.get_replenisher_individual())
545 )
546 )
547 }
548 }
549}