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
#[cfg(test)]
#[path = "../../../tests/unit/algorithms/nsga2/nsga2_sort_test.rs"]
mod nsga2_sort_test;
use super::*;
pub fn select_and_rank<'a, S: 'a>(
solutions: &'a [S],
n: usize,
multi_objective: &impl MultiObjective<Solution = S>,
) -> Vec<AssignedCrowdingDistance<'a, S>> {
let n = solutions.len().min(n);
debug_assert!(n <= solutions.len());
let mut result = Vec::with_capacity(n);
let mut missing_solutions = n;
let mut front = non_dominated_sort(solutions, multi_objective);
while !front.is_empty() {
let (mut assigned_crowding, _) = assign_crowding_distance(&front, multi_objective);
if assigned_crowding.len() > missing_solutions {
assigned_crowding.sort_by(|a, b| {
debug_assert_eq!(a.rank, b.rank);
a.crowding_distance.partial_cmp(&b.crowding_distance).unwrap().reverse()
});
}
let take = assigned_crowding.len().min(missing_solutions);
result.extend(assigned_crowding.into_iter().take(take));
missing_solutions -= take;
if missing_solutions == 0 {
break;
}
front = front.next_front();
}
debug_assert_eq!(n, result.len());
result
}