1 package net.bmahe.genetics4j.moo.spea2.spec.replacement;
2
3 import java.util.Comparator;
4 import java.util.Optional;
5 import java.util.function.BiFunction;
6
7 import org.immutables.value.Value;
8
9 import net.bmahe.genetics4j.core.Genotype;
10 import net.bmahe.genetics4j.core.spec.replacement.ReplacementStrategy;
11 import net.bmahe.genetics4j.moo.FitnessVector;
12
13 @Value.Immutable
14 public abstract class SPEA2Replacement<T extends Comparable<T>> implements ReplacementStrategy {
15
16
17
18
19
20
21 @Value.Default
22 public Comparator<T> dominance() {
23 return java.lang.Comparable::compareTo;
24 }
25
26
27
28
29
30
31
32 @Value.Default
33 public Optional<Comparator<Genotype>> deduplicate() {
34 return Optional.empty();
35 }
36
37
38
39
40
41
42
43 @Value.Default
44 public Optional<Integer> k() {
45 return Optional.empty();
46 }
47
48
49
50
51
52
53 @Value.Parameter
54 public abstract BiFunction<T, T, Double> distance();
55
56 public static class Builder<T extends Comparable<T>> extends ImmutableSPEA2Replacement.Builder<T> {
57 }
58
59 public static <U extends Comparable<U>> Builder<U> builder() {
60 return new Builder<>();
61 }
62
63
64
65
66
67
68
69
70 public static <U extends Number & Comparable<U>> SPEA2Replacement<FitnessVector<U>> ofFitnessVector(
71 final Comparator<Genotype> deduplicate) {
72
73 final var builder = new Builder<FitnessVector<U>>();
74 builder.deduplicate(Optional.ofNullable(deduplicate));
75
76 builder.distance((fv1, fv2) -> {
77
78 final int dimensions = fv1.dimensions();
79
80 double sum = 0.0;
81 for (int i = 0; i < dimensions; i++) {
82 final double v1 = fv1.get(i).doubleValue();
83 final double v2 = fv2.get(i).doubleValue();
84
85 sum += (v2 - v1) * (v2 - v1);
86 }
87
88 return Math.sqrt(sum);
89 });
90
91 return builder.build();
92 }
93
94
95
96
97
98
99
100 public static <U extends Number & Comparable<U>> SPEA2Replacement<FitnessVector<U>> ofFitnessVector() {
101
102 return ofFitnessVector(null);
103 }
104 }