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
#[derive(Debug, Clone, Copy)]
pub enum PermutationProbF {
Uniform(f64),
Relative,
}
impl PermutationProbF {
pub(crate) fn get_probability(
&self,
subpopulation_fits: &Vec<f64>,
weight_fit: f64,
) -> f64 {
match self {
PermutationProbF::Uniform(p) => *p,
PermutationProbF::Relative => {
let mut min_fit: f64 = subpopulation_fits[0];
let mut max_fit: f64 = subpopulation_fits[0];
for f in subpopulation_fits {
if *f < min_fit {
min_fit = *f;
} else if *f > max_fit {
max_fit = *f;
}
}
1.0 - scale(min_fit, max_fit, 0.0, 1.0, weight_fit)
}
}
}
}
pub fn scale(from_min: f64, from_max: f64, to_min: f64, to_max: f64, value: f64) -> f64 {
to_min + ((value - from_min) * (to_max - to_min)) / (from_max - from_min)
}
#[cfg(test)]
mod tests {
use super::*;
use round::round;
#[test]
fn permutation_prob_f() {
let ppf = PermutationProbF::Uniform(1.0);
assert_eq!(ppf.get_probability(&vec![], 0.5), 1.0);
let ppf = PermutationProbF::Relative;
let spf: Vec<f64> = vec![0.1, 0.2, 0.5, -0.1, -0.2];
let weight_fit: f64 = spf[0];
let prob: f64 = ppf.get_probability(&spf, weight_fit);
assert_eq!(round(prob, 3), 0.571);
}
}