rsgenetic/sim/select/
max.rs1#![allow(deprecated)]
18
19use super::*;
20use pheno::{Fitness, Phenotype};
21
22#[derive(Clone, Copy, Debug)]
24#[deprecated(
25 note = "The `MaximizeSelector` has bad performance due to sorting. For better performance with potentially different results, \
26 use the `UnstableMaximizeSelector`.",
27 since = "1.7.7"
28)]
29pub struct MaximizeSelector {
30 count: usize,
31}
32
33impl MaximizeSelector {
34 pub fn new(count: usize) -> MaximizeSelector {
41 MaximizeSelector { count }
42 }
43}
44
45impl<T, F> Selector<T, F> for MaximizeSelector
46where
47 T: Phenotype<F>,
48 F: Fitness,
49{
50 fn select<'a>(&self, population: &'a [T]) -> Result<Parents<&'a T>, String> {
51 if self.count == 0 || self.count % 2 != 0 || self.count * 2 >= population.len() {
52 return Err(format!(
53 "Invalid parameter `count`: {}. Should be larger than zero, a \
54 multiple of two and less than half the population size.",
55 self.count
56 ));
57 }
58
59 let mut borrowed: Vec<&T> = population.iter().collect();
60 borrowed.sort_by(|x, y| y.fitness().cmp(&x.fitness()));
61 let mut index = 0;
62 let mut result: Parents<&T> = Vec::new();
63 while index < self.count {
64 result.push((borrowed[index], borrowed[index + 1]));
65 index += 2;
66 }
67 Ok(result)
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use pheno::*;
74 use sim::select::*;
75 use test::Test;
76
77 #[test]
78 fn test_count_zero() {
79 let selector = MaximizeSelector::new(0);
80 let population: Vec<Test> = (0..100).map(|i| Test { f: i }).collect();
81 assert!(selector.select(&population).is_err());
82 }
83
84 #[test]
85 fn test_count_odd() {
86 let selector = MaximizeSelector::new(5);
87 let population: Vec<Test> = (0..100).map(|i| Test { f: i }).collect();
88 assert!(selector.select(&population).is_err());
89 }
90
91 #[test]
92 fn test_count_too_large() {
93 let selector = MaximizeSelector::new(100);
94 let population: Vec<Test> = (0..100).map(|i| Test { f: i }).collect();
95 assert!(selector.select(&population).is_err());
96 }
97
98 #[test]
99 fn test_result_size() {
100 let selector = MaximizeSelector::new(20);
101 let population: Vec<Test> = (0..100).map(|i| Test { f: i }).collect();
102 assert_eq!(20, selector.select(&population).unwrap().len() * 2);
103 }
104
105 #[test]
106 fn test_result_ok() {
107 let selector = MaximizeSelector::new(20);
108 let population: Vec<Test> = (0..100).map(|i| Test { f: i }).collect();
109 assert_eq!(selector.select(&population).unwrap()[0].0.fitness().f, 99);
111 }
112
113 #[test]
114 fn test_contains_best() {
115 let selector = MaximizeSelector::new(2);
116 let population: Vec<Test> = (0..100).map(|i| Test { f: i }).collect();
117 let parents = selector.select(&population).unwrap()[0];
118 assert_eq!(
119 parents.0.fitness(),
120 population
121 .iter()
122 .max_by_key(|x| x.fitness())
123 .unwrap()
124 .fitness()
125 );
126 }
127}