scarlet_queen_generation/
individual.rs

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}