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