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
use crate::utils::compare_floats;
use std::cmp::Ordering;
use std::sync::Arc;
pub trait Objective {
type Solution;
fn total_order(&self, a: &Self::Solution, b: &Self::Solution) -> Ordering {
let fitness_a = self.fitness(a);
let fitness_b = self.fitness(b);
compare_floats(fitness_a, fitness_b)
}
fn distance(&self, a: &Self::Solution, b: &Self::Solution) -> f64 {
let fitness_a = self.fitness(a);
let fitness_b = self.fitness(b);
fitness_a - fitness_b
}
fn fitness(&self, solution: &Self::Solution) -> f64;
}
pub trait MultiObjective: Objective {
fn objectives<'a>(
&'a self,
) -> Box<dyn Iterator<Item = &'a (dyn Objective<Solution = Self::Solution> + Send + Sync)> + 'a>;
}
pub fn dominance_order<T>(a: &T, b: &T, objectives: &[Arc<dyn Objective<Solution = T> + 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
}
}