scarlet_queen_core/
each_individual.rs

1//! Mod for `Individual`, `EachCrateIndividual`, `FitnessIndividualTrait`, `SelectorIndividualTrait`, `ReplenisherIndividualTrait`.
2
3use std::{
4    collections::{HashMap, HashSet},
5    fmt::Debug,
6};
7
8pub use each_crate_individual::EachCrateIndividual;
9pub use fitness_individual::FitnessIndividualTrait;
10pub use individual::Individual;
11
12mod individual {
13    //! Mod for `Individual`.
14    use std::cell::RefCell;
15
16    #[derive(Debug, Clone, PartialEq, Eq)]
17    /// Individual for `Group`.
18    /// A target value with id.
19    /// * `T` - A type of value.
20    ///
21    /// # Example
22    /// ```
23    /// use scarlet_queen_core::each_individual::Individual;
24    ///
25    /// let sample: Individual<u8> = Individual::new(5);
26    ///
27    /// assert_eq!(sample.get_id(), 0usize);
28    /// assert_eq!(sample.get_value(), &5u8);
29    ///
30    /// sample.set_id(1);
31    ///
32    /// assert_eq!(sample.get_id(), 1usize);
33    /// ```
34    pub struct Individual<T> {
35        /// The individual of id.
36        id: RefCell<usize>,
37        /// The individual of value.
38        value: T,
39    }
40
41    impl<T> Individual<T> {
42        /// Make individual from value.
43        /// * `value` - A target value.
44        pub fn new(value: T) -> Individual<T> {
45            Self::new_with_id(0, value)
46        }
47
48        /// Make individual from value and id.
49        /// * `id` - An id.
50        /// * `value` - A target value.
51        pub fn new_with_id(id: usize, value: T) -> Individual<T> {
52            Individual {
53                id: RefCell::new(id),
54                value,
55            }
56        }
57
58        /// Get this id.
59        pub fn get_id(&self) -> usize {
60            *self.id.borrow()
61        }
62
63        /// Set this id.
64        ///
65        /// This method does not require mutable borrow.
66        /// * `id` - Id to be set.
67        pub fn set_id(&self, id: usize) {
68            *self.id.borrow_mut() = id;
69        }
70
71        /// Get this value.
72        pub fn get_value(&self) -> &T {
73            &self.value
74        }
75    }
76
77    #[cfg(test)]
78    mod tests {
79        use std::cell::RefCell;
80
81        use super::Individual;
82
83        #[test]
84        fn test_individual_new() {
85            let testcases: Vec<(u8, Individual<u8>)> = vec![
86                (
87                    5u8,
88                    Individual::<u8> {
89                        id: RefCell::new(0),
90                        value: 5,
91                    },
92                ),
93                (
94                    0u8,
95                    Individual::<u8> {
96                        id: RefCell::new(0),
97                        value: 0,
98                    },
99                ),
100                (
101                    13u8,
102                    Individual::<u8> {
103                        id: RefCell::new(0),
104                        value: 13,
105                    },
106                ),
107            ];
108            for (arg, result) in testcases.into_iter() {
109                assert_eq!(Individual::<u8>::new(arg), result)
110            }
111        }
112
113        #[test]
114        fn test_individual_newwithid() {
115            let testcases: Vec<((usize, u8), Individual<u8>)> = vec![
116                (
117                    (6usize, 5u8),
118                    Individual::<u8> {
119                        id: RefCell::new(6),
120                        value: 5,
121                    },
122                ),
123                (
124                    (10usize, 0u8),
125                    Individual::<u8> {
126                        id: RefCell::new(10),
127                        value: 0,
128                    },
129                ),
130                (
131                    (0usize, 13u8),
132                    Individual::<u8> {
133                        id: RefCell::new(0),
134                        value: 13,
135                    },
136                ),
137            ];
138            for ((arg_1, arg_2), result) in testcases.into_iter() {
139                assert_eq!(Individual::<u8>::new_with_id(arg_1, arg_2), result)
140            }
141        }
142
143        #[test]
144        fn test_individual_getid() {
145            let testcases: Vec<(Individual<u8>, usize)> = vec![
146                (Individual::new_with_id(6usize, 5u8), 6usize),
147                (Individual::new_with_id(10usize, 0u8), 10usize),
148                (Individual::new_with_id(0usize, 13u8), 0usize),
149            ];
150            for (arg, result) in testcases.into_iter() {
151                assert_eq!(Individual::<u8>::get_id(&arg), result)
152            }
153        }
154
155        #[test]
156        fn test_individual_setid() {
157            let testcases: Vec<(Individual<u8>, usize)> = vec![
158                (Individual::new_with_id(6usize, 5u8), 10usize),
159                (Individual::new_with_id(10usize, 0u8), 0usize),
160                (Individual::new_with_id(0usize, 13u8), 6usize),
161            ];
162            for (arg_1, arg_2) in testcases.into_iter() {
163                arg_1.set_id(arg_2);
164                assert_eq!(Individual::<u8>::get_id(&arg_1), arg_2)
165            }
166        }
167
168        #[test]
169        fn test_individual_getvalue() {
170            let testcases: Vec<(Individual<u8>, u8)> = vec![
171                (Individual::new_with_id(6usize, 5u8), 5u8),
172                (Individual::new_with_id(10usize, 0u8), 0u8),
173                (Individual::new_with_id(0usize, 13u8), 13u8),
174            ];
175            for (arg_1, arg_2) in testcases.into_iter() {
176                assert_eq!(Individual::<u8>::get_value(&arg_1), &arg_2)
177            }
178        }
179    }
180}
181
182mod each_crate_individual {
183    //! Mod for `EachCrateIndividual`.
184    use std::rc::Rc;
185
186    use super::Individual;
187
188    /// A trait for inividual defined by each crete.
189    ///
190    /// A struct implmented this must have `Rc<Individual<T>>`.
191    /// * `T` - A type of value.
192    ///
193    /// # Example
194    /// ```
195    /// use std::rc::Rc;
196    /// use scarlet_queen_core::each_individual::{Individual, EachCrateIndividual};
197    ///
198    /// #[derive(PartialEq, Eq, Debug)]
199    /// struct SampleIndividual(Rc<Individual<u8>>);
200    ///
201    /// impl EachCrateIndividual for SampleIndividual {
202    ///     type Item = u8;
203    ///
204    ///     fn new(individual: &Rc<Individual<Self::Item>>) -> Self {
205    ///         SampleIndividual(Rc::clone(&individual))
206    ///     }
207    ///
208    ///     fn get_individual(&self) -> &Individual<Self::Item> {
209    ///         self.0.as_ref()
210    ///     }
211    /// }
212    ///
213    /// let r: Rc<Individual<u8>> = Rc::new(Individual::new(5u8));
214    /// let sample: SampleIndividual = SampleIndividual::new(&r);
215    ///
216    /// assert_eq!(sample.get_individual(), r.as_ref());
217    /// assert_eq!(sample.get_id(), r.get_id());
218    /// assert_eq!(sample.get_value(), r.get_value());
219    /// ```
220    pub trait EachCrateIndividual {
221        type Item;
222
223        /// Make individual from base individual.
224        /// * `individual` - A base individual.
225        fn new(individual: &Rc<Individual<Self::Item>>) -> Self;
226
227        /// Get this individual.
228        fn get_individual(&self) -> &Individual<Self::Item>;
229
230        /// Get an id of this individual.
231        fn get_id(&self) -> usize {
232            self.get_individual().get_id()
233        }
234
235        /// Get a value of this individual.
236        fn get_value(&self) -> &Self::Item {
237            self.get_individual().get_value()
238        }
239    }
240
241    #[cfg(test)]
242    mod tests {
243        use std::rc::Rc;
244
245        use super::EachCrateIndividual;
246        use crate::each_individual::Individual;
247
248        #[derive(PartialEq, Eq, Debug)]
249        struct SampleIndividual(Rc<Individual<u8>>);
250        impl EachCrateIndividual for SampleIndividual {
251            type Item = u8;
252            fn new(individual: &Rc<Individual<Self::Item>>) -> Self {
253                SampleIndividual(Rc::clone(individual))
254            }
255            fn get_individual(&self) -> &Individual<Self::Item> {
256                self.0.as_ref()
257            }
258        }
259
260        #[test]
261        fn test_eachcrateindividual_new() {
262            let base: Vec<Rc<Individual<u8>>> = vec![
263                Rc::new(Individual::new(5u8)),
264                Rc::new(Individual::new(0u8)),
265                Rc::new(Individual::new_with_id(5usize, 13u8)),
266            ];
267            let testcases: Vec<(Rc<Individual<u8>>, SampleIndividual)> = vec![
268                (Rc::clone(&base[0]), SampleIndividual(Rc::clone(&base[0]))),
269                (Rc::clone(&base[1]), SampleIndividual(Rc::clone(&base[1]))),
270                (Rc::clone(&base[2]), SampleIndividual(Rc::clone(&base[2]))),
271            ];
272            for (arg, result) in testcases.into_iter() {
273                assert_eq!(SampleIndividual::new(&arg), result);
274            }
275        }
276
277        #[test]
278        fn test_eachcrateindividual_getindividual() {
279            let base: Vec<Rc<Individual<u8>>> = vec![
280                Rc::new(Individual::new(5u8)),
281                Rc::new(Individual::new(0u8)),
282                Rc::new(Individual::new_with_id(5usize, 13u8)),
283            ];
284            let testcases: Vec<(SampleIndividual, &Individual<u8>)> = vec![
285                (SampleIndividual::new(&base[0]), &base[0]),
286                (SampleIndividual::new(&base[1]), &base[1]),
287                (SampleIndividual::new(&base[2]), &base[2]),
288            ];
289            for (arg, result) in testcases.into_iter() {
290                assert_eq!(
291                    <SampleIndividual as EachCrateIndividual>::get_individual(&arg),
292                    result
293                );
294            }
295        }
296
297        #[test]
298        fn test_eachcrateindividual_getid() {
299            let base: Vec<Rc<Individual<u8>>> = vec![
300                Rc::new(Individual::new(5u8)),
301                Rc::new(Individual::new(0u8)),
302                Rc::new(Individual::new_with_id(5usize, 13u8)),
303            ];
304            let testcases: Vec<(SampleIndividual, usize)> = vec![
305                (SampleIndividual::new(&base[0]), 0usize),
306                (SampleIndividual::new(&base[1]), 0usize),
307                (SampleIndividual::new(&base[2]), 5usize),
308            ];
309            for (arg, result) in testcases.into_iter() {
310                assert_eq!(
311                    <SampleIndividual as EachCrateIndividual>::get_id(&arg),
312                    result
313                );
314            }
315        }
316
317        #[test]
318        fn test_eachcrateindividual_getvalue() {
319            let base: Vec<Rc<Individual<u8>>> = vec![
320                Rc::new(Individual::new(5u8)),
321                Rc::new(Individual::new(0u8)),
322                Rc::new(Individual::new_with_id(5usize, 13u8)),
323            ];
324            let testcases: Vec<(SampleIndividual, &u8)> = vec![
325                (SampleIndividual::new(&base[0]), &5u8),
326                (SampleIndividual::new(&base[1]), &0u8),
327                (SampleIndividual::new(&base[2]), &13u8),
328            ];
329            for (arg, result) in testcases.into_iter() {
330                assert_eq!(
331                    <SampleIndividual as EachCrateIndividual>::get_value(&arg),
332                    result
333                );
334            }
335        }
336    }
337}
338
339mod fitness_individual {
340    //! Mod for `FitnessIndividualTrait`.
341    use std::collections::HashMap;
342
343    use super::EachCrateIndividual;
344
345    /// A trait for individual defined by fitness crate.
346    /// * `T` - A type of value.
347    ///
348    /// # Example
349    /// ```
350    /// use std::{collections::HashMap, rc::Rc};
351    ///
352    /// use scarlet_queen_core::each_individual::{Individual, EachCrateIndividual, FitnessIndividualTrait};
353    ///
354    /// struct FITraitSample {
355    ///     individual: Rc<Individual<u8>>
356    /// }
357    ///
358    /// impl EachCrateIndividual for FITraitSample {
359    ///     type Item = u8;
360    ///
361    ///     fn new(individual: &std::rc::Rc<Individual<u8>>) -> Self {
362    ///         FITraitSample {
363    ///             individual: Rc::clone(individual)
364    ///         }
365    ///     }
366    ///
367    ///     fn get_individual(&self) -> &Individual<u8> {
368    ///         &self.individual
369    ///     }
370    /// }
371    ///
372    /// impl FitnessIndividualTrait for FITraitSample {
373    ///     fn fitness(&self, other: &Self) -> usize {
374    ///         if self.get_value() >= other.get_value() {
375    ///             1
376    ///         } else {
377    ///             0
378    ///         }
379    ///     }
380    /// }
381    ///
382    /// let r_1: Rc<Individual<u8>> = Rc::new(Individual::new_with_id(0, 13));
383    /// let sample_1: FITraitSample = FITraitSample::new(&r_1);
384    ///
385    /// assert_eq!(sample_1.get_individual(), r_1.as_ref());
386    /// assert_eq!(sample_1.get_id(), 0usize);
387    /// assert_eq!(sample_1.get_value(), &13u8);
388    ///
389    /// let sample_2: FITraitSample = FITraitSample::new(&Rc::new(Individual::new_with_id(1, 5)));
390    ///
391    /// assert_eq!(sample_1.fitness(&sample_2), 1);
392    ///
393    /// let sample: Vec<FITraitSample> = vec![
394    ///     sample_1,
395    ///     sample_2,
396    ///     FITraitSample::new(&Rc::new(Individual::new_with_id(2, 15)))
397    /// ];
398    ///
399    /// assert_eq!(FITraitSample::fitness_group(&sample), vec![(0, 1), (1, 0), (2, 2)].into_iter().collect::<HashMap<usize, usize>>());
400    /// ```
401    pub trait FitnessIndividualTrait: EachCrateIndividual {
402        /// Calculate a fitness to an other individual.
403        /// * `other` - A target of fitness.
404        fn fitness(&self, other: &Self) -> usize;
405
406        /// Calculate a fitness to a group.
407        ///
408        /// A fitness to a group is the sum of fitnesses to other individuals.
409        /// * `'a` - A Lifetime of group.
410        /// * `G` - A type of group.
411        /// * `group` - A value which you are able to get `Self` from.
412        fn fitness_group<'a, G>(group: G) -> HashMap<usize, usize>
413        where
414            G: IntoIterator<Item = &'a Self>,
415            Self: 'a,
416        {
417            // get group
418            let group_vec: Vec<&Self> = group.into_iter().collect::<Vec<&Self>>();
419
420            // calculate a sum of fitnesses to other individuals
421            group_vec
422                .iter()
423                .map(|v| {
424                    (
425                        v.get_id(),
426                        group_vec.iter().map(|u| v.fitness(u)).sum::<usize>() - v.fitness(v),
427                    )
428                })
429                .collect::<HashMap<usize, usize>>()
430        }
431    }
432
433    #[cfg(test)]
434    mod tests {
435        use std::{collections::HashMap, rc::Rc};
436
437        use super::FitnessIndividualTrait;
438        use crate::each_individual::{EachCrateIndividual, Individual};
439
440        struct FITraitSample {
441            individual: Rc<Individual<u8>>,
442        }
443        impl FITraitSample {
444            fn new_for_test(id: usize, value: u8) -> Self {
445                FITraitSample {
446                    individual: Rc::new(Individual::new_with_id(id, value)),
447                }
448            }
449        }
450        impl EachCrateIndividual for FITraitSample {
451            type Item = u8;
452            fn new(individual: &std::rc::Rc<Individual<u8>>) -> Self {
453                FITraitSample {
454                    individual: Rc::clone(individual),
455                }
456            }
457            fn get_individual(&self) -> &Individual<u8> {
458                &self.individual
459            }
460        }
461        impl FitnessIndividualTrait for FITraitSample {
462            fn fitness(&self, other: &Self) -> usize {
463                if self.get_value() >= other.get_value() {
464                    1
465                } else {
466                    0
467                }
468            }
469        }
470
471        #[test]
472        fn test_fitnessindividualtrait_fitnessgroup() {
473            let testcases: Vec<(Vec<FITraitSample>, HashMap<usize, usize>)> = vec![
474                (
475                    vec![
476                        FITraitSample::new_for_test(0, 10),
477                        FITraitSample::new_for_test(1, 10),
478                        FITraitSample::new_for_test(2, 7),
479                        FITraitSample::new_for_test(3, 7),
480                        FITraitSample::new_for_test(4, 7),
481                        FITraitSample::new_for_test(5, 4),
482                        FITraitSample::new_for_test(6, 3),
483                        FITraitSample::new_for_test(7, 2),
484                        FITraitSample::new_for_test(8, 2),
485                        FITraitSample::new_for_test(9, 1),
486                    ],
487                    vec![
488                        (0, 9),
489                        (1, 9),
490                        (2, 7),
491                        (3, 7),
492                        (4, 7),
493                        (5, 4),
494                        (6, 3),
495                        (7, 2),
496                        (8, 2),
497                        (9, 0),
498                    ]
499                    .into_iter()
500                    .collect::<HashMap<usize, usize>>(),
501                ),
502                (
503                    vec![
504                        FITraitSample::new_for_test(0, 3),
505                        FITraitSample::new_for_test(1, 1),
506                        FITraitSample::new_for_test(2, 1),
507                        FITraitSample::new_for_test(3, 1),
508                    ],
509                    vec![(0, 3), (1, 2), (2, 2), (3, 2)]
510                        .into_iter()
511                        .collect::<HashMap<usize, usize>>(),
512                ),
513                (
514                    vec![FITraitSample::new_for_test(0, 1)],
515                    vec![(0, 0)].into_iter().collect::<HashMap<usize, usize>>(),
516                ),
517                (
518                    vec![],
519                    vec![].into_iter().collect::<HashMap<usize, usize>>(),
520                ),
521                (
522                    vec![
523                        FITraitSample::new_for_test(0, 17),
524                        FITraitSample::new_for_test(1, 2),
525                        FITraitSample::new_for_test(2, 20),
526                        FITraitSample::new_for_test(3, 20),
527                        FITraitSample::new_for_test(4, 16),
528                        FITraitSample::new_for_test(5, 16),
529                        FITraitSample::new_for_test(6, 12),
530                        FITraitSample::new_for_test(7, 19),
531                        FITraitSample::new_for_test(8, 1),
532                        FITraitSample::new_for_test(9, 4),
533                        FITraitSample::new_for_test(10, 14),
534                        FITraitSample::new_for_test(11, 10),
535                        FITraitSample::new_for_test(12, 8),
536                        FITraitSample::new_for_test(13, 2),
537                        FITraitSample::new_for_test(14, 8),
538                        FITraitSample::new_for_test(15, 16),
539                        FITraitSample::new_for_test(16, 16),
540                        FITraitSample::new_for_test(17, 10),
541                        FITraitSample::new_for_test(18, 4),
542                        FITraitSample::new_for_test(19, 1),
543                    ],
544                    vec![
545                        (0, 16),
546                        (1, 3),
547                        (2, 19),
548                        (3, 19),
549                        (4, 15),
550                        (5, 15),
551                        (6, 10),
552                        (7, 17),
553                        (8, 1),
554                        (9, 5),
555                        (10, 11),
556                        (11, 9),
557                        (12, 7),
558                        (13, 3),
559                        (14, 7),
560                        (15, 15),
561                        (16, 15),
562                        (17, 9),
563                        (18, 5),
564                        (19, 1),
565                    ]
566                    .into_iter()
567                    .collect::<HashMap<usize, usize>>(),
568                ),
569            ];
570            for (arg, result) in testcases.into_iter() {
571                assert_eq!(FITraitSample::fitness_group(&arg), result);
572            }
573        }
574    }
575}
576
577/// A trait for individual defined by selector crate.
578/// * `T` - A type of value.
579/// * `R` - The number of individuals after individuals are reduced by selector.
580pub trait SelectorIndividualTrait<const R: usize>: EachCrateIndividual {
581    /// An error of selector.
582    /// This is occurred when bad scores are given to this.
583    type Err: Debug;
584
585    /// Select individuals.
586    /// * `'a` - A lifetime of group.
587    /// * `G` - A type of group.
588    /// * `group` - A value which you are able to get `Self` from.
589    /// * `fitnesses` - Scores of fitness crate.
590    fn selected_ids<'a, G>(
591        group: G,
592        fitnesses: HashMap<usize, usize>,
593    ) -> Result<HashSet<usize>, Self::Err>
594    where
595        G: IntoIterator<Item = &'a Self>,
596        Self: 'a;
597}
598
599/// A trait for individual defined by replenisher crate.
600/// * `T` - A type of value.
601/// * `N` - The number of individuals.
602/// * `R` - The number of individuals after individuals are reduced by selector.
603pub trait ReplenisherIndividualTrait<const N: usize, const R: usize>: EachCrateIndividual {
604    /// Replenish individuals.
605    /// * `'a` - A lifetime of group.
606    /// * `G` - A type of group.
607    /// * `group` - A value which you are able to get `Self` from.
608    fn replenish<'a, G>(group: G) -> Vec<<Self as EachCrateIndividual>::Item>
609    where
610        G: IntoIterator<Item = &'a Self>,
611        Self: 'a;
612}