rust_monster/ga/
ga_population.rs1use super::ga_core::GASolution;
4
5use std::cmp::Ordering;
6use std::iter::FromIterator;
7
8#[derive(Clone, Copy)]
10pub enum GAPopulationSortBasis
11{
12 Raw,
13 Scaled,
14}
15
16#[derive(Clone, Copy)]
19pub enum GAPopulationSortOrder
20{
21 LowIsBest,
22 HighIsBest,
23}
24
25pub struct GAPopulation<T: GASolution>
28{
29 population: Vec<T>,
30
31 sort_order: GAPopulationSortOrder,
32
33 population_order_raw: Vec<usize>,
35 is_raw_sorted: bool,
37
38 population_order_scaled: Vec<usize>,
40 is_scaled_sorted: bool,
42
43 }
46impl<T: GASolution> GAPopulation<T>
47{
48 pub fn new(p: Vec<T>, order: GAPopulationSortOrder) -> GAPopulation<T>
50 {
51 let gap = GAPopulation
52 {
53 population: p,
54 sort_order: order,
55 population_order_raw: vec![],
56 is_raw_sorted: false,
57 population_order_scaled: vec![],
58 is_scaled_sorted: false
59 };
60
61 gap
62 }
63
64 pub fn population(&mut self) -> &mut Vec<T>
65 {
66 return &mut self.population
67 }
68
69 pub fn evaluate(&mut self)
70 {
71 for ref mut ind in &mut self.population
72 {
73 ind.evaluate();
74 }
75 }
76
77 pub fn size(&self) -> usize
78 {
79 self.population.len()
80 }
81
82 pub fn order(&self) -> GAPopulationSortOrder
83 {
84 self.sort_order
88 }
89
90 pub fn select(&self) -> &T
92 {
93 self.individual(0, GAPopulationSortBasis::Scaled)
94 }
95
96 pub fn best(&self) -> &T
98 {
99 self.individual(0, GAPopulationSortBasis::Scaled)
102 }
103
104 pub fn worst(&self) -> &T
106 {
107 self.individual(self.size()-1, GAPopulationSortBasis::Scaled)
108 }
109
110 pub fn best_by_raw_score(&self) -> &T
111 {
112 self.individual(0, GAPopulationSortBasis::Raw)
113 }
114
115 pub fn worst_by_raw_score(&self) -> &T
116 {
117 self.individual(self.size()-1, GAPopulationSortBasis::Scaled)
118 }
119
120 pub fn best_by_scaled_score(&self) -> &T
121 {
122 self.individual(0, GAPopulationSortBasis::Raw)
123 }
124
125 pub fn worst_by_scaled_score(&self) -> &T
126 {
127 self.individual(self.size()-1, GAPopulationSortBasis::Scaled)
128 }
129
130 pub fn individual(&self, i : usize, sort_basis : GAPopulationSortBasis) -> &T
131 {
132 match sort_basis
134 {
135 GAPopulationSortBasis::Raw
136 => { &self.population[self.population_order_raw[i]] },
137 GAPopulationSortBasis::Scaled
138 => { &self.population[self.population_order_scaled[i]] },
139 }
140 }
141
142 pub fn sort(&mut self)
143 {
144 self.sort_int(false, GAPopulationSortBasis::Scaled);
145 self.sort_int(false, GAPopulationSortBasis::Raw);
146 }
147
148 pub fn sort_int(&mut self, force_sort: bool, sort_basis: GAPopulationSortBasis)
150 {
151 let mut ordered : Vec<usize> = Vec::from_iter(0..self.size());
152 match sort_basis
153 {
154 GAPopulationSortBasis::Raw
155 => if (!self.is_raw_sorted) || force_sort
156 {
157 match self.sort_order
158 {
159 GAPopulationSortOrder::LowIsBest =>
160 {
161 ordered.sort_by(|s1: &usize, s2: &usize|
162 self.population[*s1].score()
163 .partial_cmp(&self.population[*s2].score()).unwrap_or(Ordering::Equal));
164
165 },
166 GAPopulationSortOrder::HighIsBest =>
167 {
168 ordered.sort_by(|s1: &usize, s2: &usize|
169 self.population[*s2].score()
170 .partial_cmp(&self.population[*s1].score()).unwrap_or(Ordering::Equal));
171
172 },
173 };
174 self.population_order_raw = ordered;
175 self.is_raw_sorted = true;
176 },
177
178 GAPopulationSortBasis::Scaled
179 => if (!self.is_scaled_sorted) || force_sort
180 {
181 match self.sort_order
182 {
183 GAPopulationSortOrder::LowIsBest =>
184 {
185 ordered.sort_by(|s1: &usize, s2: &usize|
186 self.population[*s1].fitness()
187 .partial_cmp(&self.population[*s2].fitness()).unwrap_or(Ordering::Equal));
188 },
189
190 GAPopulationSortOrder::HighIsBest =>
191 {
192 ordered.sort_by(|s1: &usize, s2: &usize|
193 self.population[*s2].fitness()
194 .partial_cmp(&self.population[*s1].fitness()).unwrap_or(Ordering::Equal));
195 }
196 };
197 self.population_order_scaled = ordered;
198 self.is_scaled_sorted = true;
199 },
200 };
201 }
202}
203
204
205#[cfg(test)]
206mod test
207{
208}