1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#[cfg(test)]
#[path = "../../tests/unit/solver/population/population_test.rs"]
mod population_test;
use crate::algorithms::nsga2::{select_and_rank, Objective};
use crate::models::Problem;
use crate::solver::{Individual, Population};
use crate::utils::compare_floats;
use std::cmp::Ordering::Equal;
use std::sync::Arc;
pub struct DominancePopulation {
problem: Arc<Problem>,
max_population_size: usize,
individuals: Vec<Individual>,
ranks: Vec<usize>,
}
impl DominancePopulation {
pub fn new(problem: Arc<Problem>, max_population_size: usize) -> Self {
assert!(max_population_size > 0);
Self { problem, max_population_size, individuals: vec![], ranks: vec![] }
}
}
impl Population for DominancePopulation {
fn add_all(&mut self, individuals: Vec<Individual>) {
individuals.into_iter().for_each(|individual| {
self.add_individual(individual);
});
self.ensure_max_population_size();
}
fn add(&mut self, individual: Individual) {
self.add_individual(individual);
self.ensure_max_population_size();
}
fn ranked<'a>(&'a self) -> Box<dyn Iterator<Item = (&Individual, usize)> + 'a> {
Box::new(self.individuals.iter().zip(self.ranks.iter().cloned()))
}
fn size(&self) -> usize {
self.individuals.len()
}
}
impl DominancePopulation {
fn add_individual(&mut self, individual: Individual) {
self.individuals.push(individual);
self.ranks.push(0);
let mut best_order =
select_and_rank(self.individuals.as_slice(), self.individuals.len(), self.problem.objective.as_ref())
.iter()
.map(|acd| {
(
acd.rank,
acd.index,
acd.crowding_distance,
self.problem.objective.fitness(self.individuals.get(acd.index).unwrap()),
)
})
.collect::<Vec<_>>();
if !best_order.is_empty() {
best_order.dedup_by(|(_, _, a_cd, a_cost), (_, _, b_cd, b_cost)| {
compare_floats(*a_cd, *b_cd) == Equal && compare_floats(*a_cost, *b_cost) == Equal
});
self.individuals = best_order.iter().map(|(_, idx, _, _)| self.individuals[*idx].deep_copy()).collect();
self.ranks = best_order.iter().map(|(rank, _, _, _)| *rank).collect();
}
debug_assert!(self.individuals.len() == self.ranks.len())
}
fn ensure_max_population_size(&mut self) {
if self.individuals.len() > self.max_population_size {
self.individuals.truncate(self.max_population_size);
self.ranks.truncate(self.max_population_size);
}
}
}