1use std::marker::PhantomData;
3
4use crate::common::*;
5use crate::fitness::*;
6use crate::individual::*;
7#[derive(Clone, Debug)]
12pub struct Population<G>
13where
14 G: Genome,
15{
16 individuals: Vec<Individual<G>>,
18
19 size_limit: usize,
21
22 fitness_values: Vec<f64>,
24}
25
26impl<G> Population<G>
27where
28 G: Genome,
29{
30 pub fn individuals(&self) -> &[Individual<G>] {
32 &self.individuals
33 }
34
35 pub fn size(&self) -> usize {
37 self.individuals.len()
38 }
39
40 pub fn is_oversized(&self) -> bool {
42 self.size() > self.size_limit
43 }
44
45 pub fn size_limit(&self) -> usize {
47 self.size_limit
48 }
49
50 pub fn evaluate_with<F: EvaluateFitness<G>>(&mut self, fitness: &mut F) {
52 self.fitness_values = evaluate_individuals(&self.individuals, fitness);
53 }
54
55 pub fn weight_with(&mut self, weight: f64) {
57 for fitness in self.fitness_values.iter_mut() {
58 *fitness *= weight;
59 }
60 }
61
62 pub fn build<F>(indvs: Vec<Individual<G>>, fitness: &mut F) -> Self
65 where
66 F: EvaluateFitness<G>,
67 {
68 let nlimit = indvs.len();
69 let fitness_values = evaluate_individuals(&indvs, fitness);
70
71 Self {
72 individuals: indvs,
73 fitness_values,
74 size_limit: nlimit,
75 }
76 }
77
78 pub fn with_size_limit(mut self, limit: usize) -> Self {
80 self.size_limit = limit;
81 self
82 }
83}
84
85fn evaluate_individuals<G, F>(indvs: &[Individual<G>], fitness: &mut F) -> Vec<f64>
87where
88 G: Genome,
89 F: EvaluateFitness<G>,
90{
91 let fitness_values = fitness.evaluate(indvs);
92 assert_eq!(
93 fitness_values.len(),
94 indvs.len(),
95 "fitness values is not equal to the number of individuals!"
96 );
97 fitness_values
98}
99#[derive(Debug, Clone)]
105pub struct Member<'a, G>
106where
107 G: Genome,
108{
109 pub individual: &'a Individual<G>,
110 fitness: f64,
111}
112
113pub trait SortMember {
114 fn sort_by_fitness(&mut self);
115}
116
117impl<'a, G> Member<'a, G>
118where
119 G: Genome,
120{
121 pub fn objective_value(&self) -> f64 {
123 self.individual.objective_value()
124 }
125
126 pub fn fitness_value(&self) -> f64 {
128 self.fitness
129 }
130
131 pub fn genome(&self) -> &G {
133 self.individual.genome()
134 }
135}
136
137impl<'a, G> SortMember for [Member<'a, G>]
138where
139 G: Genome,
140{
141 fn sort_by_fitness(&mut self) {
142 self.sort_by(|mi, mj| {
143 let (fi, fj) = (mi.fitness, mj.fitness);
144 float_ordering_maximize(&fi, &fj)
146 });
147 }
148}
149
150impl<'a, G> std::fmt::Display for Member<'a, G>
152where
153 G: Genome + std::fmt::Display,
154{
155 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
156 write!(
157 f,
158 "indv {}: fitness = {:5.2} objective value = {}",
159 self.individual.genome(),
160 self.fitness,
161 self.individual.objective_value(),
162 )
163 }
164}
165
166impl<G> Population<G>
167where
168 G: Genome,
169{
170 pub fn members(&self) -> impl Iterator<Item = Member<G>> {
172 self.individuals
173 .iter()
174 .zip(self.fitness_values.iter())
175 .map(|(individual, &fitness)| Member { individual, fitness })
176 }
177
178 pub fn best_member(&self) -> Option<Member<G>> {
180 self.fitness_values.iter().imax().and_then(|(i, fitness)| {
181 let best = Member {
182 individual: &self.individuals[i],
183 fitness,
184 };
185 Some(best)
186 })
187 }
188}
189impl<G> Population<G>
193where
194 G: Genome,
195{
196 pub fn survive(&mut self) -> usize {
204 if self.is_oversized() {
205 let n_old = self.size();
206 let mut members: Vec<_> = self.members().collect();
207 members.sort_by_fitness();
208 let to_keep: Vec<_> = members.into_iter().take(self.size_limit).collect();
209
210 let mut indvs = vec![];
211 let mut values = vec![];
212 for m in to_keep {
213 indvs.push(m.individual.to_owned());
214 values.push(m.fitness_value());
215 }
216
217 self.individuals = indvs;
218 self.fitness_values = values;
219 n_old - self.size()
220 } else {
221 0
222 }
223 }
224}
225#[cfg(test)]
229mod test {
230 use super::*;
231 use crate::encoding::Binary;
232
233 #[test]
234 fn test() {
235 let keys: Vec<_> = vec!["10110", "01010", "11011"].iter().map(|x| Binary::from_str(x)).collect();
236
237 let mut fitness = crate::fitness::Maximize;
238 let indvs = crate::individual::OneMax.create(keys);
239 let pop = Population::build(indvs, &mut fitness).with_size_limit(10);
240
241 assert!(!pop.is_oversized());
242
243 let mut members: Vec<_> = pop.members().collect();
244 members.sort_by_fitness();
245
246 for m in members.iter() {
247 }
249
250 let m = pop.best_member().unwrap();
251 assert_eq!(m.genome().to_string(), "11011");
252 }
253}
254