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}