View Javadoc
1   package net.bmahe.genetics4j.moo.nsga2.spec;
2   
3   import java.util.Comparator;
4   import java.util.Optional;
5   import java.util.function.Function;
6   
7   import org.immutables.value.Value;
8   
9   import net.bmahe.genetics4j.core.Genotype;
10  import net.bmahe.genetics4j.core.spec.selection.SelectionPolicy;
11  import net.bmahe.genetics4j.moo.FitnessVector;
12  import net.bmahe.genetics4j.moo.ObjectiveDistance;
13  
14  /**
15   * NSGA2 Selection specification
16   * <p>
17   * Select individuals based on their NSGA2 score, going from the most dominating
18   * ones to the lesser ones
19   * 
20   * @param <T> Type of the fitness measurement
21   */
22  @Value.Immutable
23  public abstract class NSGA2Selection<T extends Comparable<T>> implements SelectionPolicy {
24  
25  	/**
26  	 * Number of objectives
27  	 * 
28  	 * @return
29  	 */
30  	@Value.Parameter
31  	public abstract int numberObjectives();
32  
33  	/**
34  	 * Override the dominance operator.
35  	 * <p>
36  	 * If not specified, it assumes the default comparator conforms to the Pareto
37  	 * dominance relation
38  	 * 
39  	 * @return
40  	 */
41  	@Value.Default
42  	public Comparator<T> dominance() {
43  		return (a, b) -> a.compareTo(b);
44  	}
45  
46  	/**
47  	 * Comparator used for deduplication of solution prior to processing
48  	 * <p>
49  	 * If not specified, it defaults to not do any deduplication
50  	 * 
51  	 * @return
52  	 */
53  	@Value.Default
54  	public Optional<Comparator<Genotype>> deduplicate() {
55  		return Optional.empty();
56  	}
57  
58  	/**
59  	 * Sort T based on the objective passed as a parameter
60  	 * 
61  	 * @return
62  	 */
63  	@Value.Parameter
64  	public abstract Function<Integer, Comparator<T>> objectiveComparator();
65  
66  	/**
67  	 * Define how to compute distances between fitness scores along their objectives
68  	 * 
69  	 * @return Distance computation method
70  	 */
71  	@Value.Parameter
72  	public abstract ObjectiveDistance<T> distance();
73  
74  	public static class Builder<T extends Comparable<T>> extends ImmutableNSGA2Selection.Builder<T> {
75  	}
76  
77  	public static <U extends Comparable<U>> Builder<U> builder() {
78  		return new Builder<U>();
79  	}
80  
81  	/**
82  	 * Factory method to instantiate a NSGA2Selection when fitness is defined as a
83  	 * FitnessVector of a Number
84  	 * 
85  	 * @param <U>              Type of the fitness measurement
86  	 * @param numberObjectives Number of objectives and dimensions of the
87  	 *                         FitnessVector
88  	 * @param deduplicate      Deduplicator comparator. Null value with disable
89  	 *                         deduplication
90  	 * @return A new instance of NSGA2Selection
91  	 */
92  	public static <U extends Number & Comparable<U>> NSGA2Selection<FitnessVector<U>>
93  			ofFitnessVector(final int numberObjectives, final Comparator<Genotype> deduplicate) {
94  
95  		final var builder = new Builder<FitnessVector<U>>();
96  
97  		builder.objectiveComparator((m) -> (a, b) -> Double.compare(a.get(m).doubleValue(), b.get(m).doubleValue()))
98  				.distance((a, b, m) -> Math.abs(b.get(m).doubleValue() - a.get(m).doubleValue()))
99  				.numberObjectives(numberObjectives)
100 				.deduplicate(Optional.ofNullable(deduplicate));
101 
102 		return builder.build();
103 	}
104 
105 	/**
106 	 * Factory method to instantiate a NSGA2Selection when fitness is defined as a
107 	 * FitnessVector of a Number
108 	 * 
109 	 * @param <U>              Type of the fitness measurement
110 	 * @param numberObjectives Number of objectives and dimensions of the
111 	 *                         FitnessVector
112 	 * @return A new instance of NSGA2Selection
113 	 */
114 	public static <U extends Number & Comparable<U>> NSGA2Selection<FitnessVector<U>>
115 			ofFitnessVector(final int numberObjectives) {
116 
117 		return ofFitnessVector(numberObjectives, null);
118 	}
119 }