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
use std::cmp::Ordering;
pub trait Objective {
type Solution;
fn total_order(&self, a: &Self::Solution, b: &Self::Solution) -> Ordering;
fn distance(&self, a: &Self::Solution, b: &Self::Solution) -> f64;
fn fitness(&self, solution: &Self::Solution) -> f64;
}
pub trait MultiObjective: Objective {
fn objectives<'a>(
&'a self,
) -> Box<dyn Iterator<Item = &Box<dyn Objective<Solution = Self::Solution> + Send + Sync>> + 'a>;
}
pub fn dominance_order<S>(a: &S, b: &S, objectives: &[Box<dyn Objective<Solution = S> + Send + Sync>]) -> Ordering {
let mut less_cnt = 0;
let mut greater_cnt = 0;
for objective in objectives.iter() {
match objective.total_order(a, b) {
Ordering::Less => {
less_cnt += 1;
}
Ordering::Greater => {
greater_cnt += 1;
}
Ordering::Equal => {}
}
}
if less_cnt > 0 && greater_cnt == 0 {
Ordering::Less
} else if greater_cnt > 0 && less_cnt == 0 {
Ordering::Greater
} else {
debug_assert!((less_cnt > 0 && greater_cnt > 0) || (less_cnt == 0 && greater_cnt == 0));
Ordering::Equal
}
}