1 | package net.bmahe.genetics4j.gp.spec.selection; | |
2 | ||
3 | import java.util.Comparator; | |
4 | ||
5 | import org.apache.commons.lang3.Validate; | |
6 | import org.immutables.value.Value; | |
7 | ||
8 | import net.bmahe.genetics4j.core.Individual; | |
9 | import net.bmahe.genetics4j.core.spec.selection.SelectionPolicy; | |
10 | import net.bmahe.genetics4j.core.spec.selection.Tournament; | |
11 | ||
12 | /** | |
13 | * Double tournament selection strategy that combines fitness-based and parsimony-based selection to control bloat in | |
14 | * genetic programming and other evolutionary algorithms. | |
15 | * | |
16 | * <p>Double tournament selection operates in two modes: | |
17 | * <ul> | |
18 | * <li><b>Fitness First Mode</b> (default): Performs two independent fitness tournaments, then applies parsimony | |
19 | * selection between the winners to select the less complex individual</li> | |
20 | * <li><b>Parsimony First Mode</b>: For each tournament candidate, performs parsimony selection on random pairs first, | |
21 | * then selects the fittest among the parsimony winners</li> | |
22 | * </ul> | |
23 | * | |
24 | * <p>The parsimony tournament uses a probabilistic approach where the parsimony tournament size parameter controls the | |
25 | * selection pressure toward less complex individuals: | |
26 | * <ul> | |
27 | * <li>Size 0.0: Always selects randomly (no parsimony pressure)</li> | |
28 | * <li>Size 1.0: Balanced selection between complexity preferences</li> | |
29 | * <li>Size 2.0: Always selects the less complex individual</li> | |
30 | * </ul> | |
31 | * | |
32 | * <p>This selection method is particularly effective in genetic programming where it helps prevent code bloat while | |
33 | * maintaining competitive fitness levels. | |
34 | * | |
35 | * @param <T> the fitness type, must be Comparable | |
36 | * | |
37 | * @see DoubleTournamentSelector | |
38 | * @see Tournament | |
39 | */ | |
40 | @Value.Immutable | |
41 | public abstract class DoubleTournament<T extends Comparable<T>> implements SelectionPolicy { | |
42 | ||
43 | /** | |
44 | * The fitness tournament configuration used for selecting individuals based on fitness. This tournament determines | |
45 | * how many candidates compete in each fitness-based selection round. | |
46 | * | |
47 | * @return the tournament configuration for fitness-based selection | |
48 | */ | |
49 | @Value.Parameter | |
50 | public abstract Tournament<T> fitnessTournament(); | |
51 | ||
52 | /** | |
53 | * Comparator used to evaluate parsimony (complexity) between individuals. Typically compares individuals based on | |
54 | * size, depth, or other complexity metrics. The comparator should return: | |
55 | * <ul> | |
56 | * <li>Negative value if first individual is less complex than second</li> | |
57 | * <li>Zero if both individuals have equal complexity</li> | |
58 | * <li>Positive value if first individual is more complex than second</li> | |
59 | * </ul> | |
60 | * | |
61 | * @return the comparator for evaluating individual complexity | |
62 | */ | |
63 | @Value.Parameter | |
64 | public abstract Comparator<Individual<T>> parsimonyComparator(); | |
65 | ||
66 | /** | |
67 | * Controls the selection pressure toward less complex individuals in parsimony tournaments. Must be between 0.0 and | |
68 | * 2.0 inclusive. | |
69 | * <ul> | |
70 | * <li>0.0: No parsimony pressure, selection is random</li> | |
71 | * <li>1.0: Balanced parsimony pressure</li> | |
72 | * <li>2.0: Maximum parsimony pressure, always selects less complex individual</li> | |
73 | * </ul> | |
74 | * | |
75 | * @return the parsimony tournament size parameter | |
76 | */ | |
77 | @Value.Parameter | |
78 | public abstract double parsimonyTournamentSize(); | |
79 | ||
80 | /** | |
81 | * Determines the order of selection operations. | |
82 | * <ul> | |
83 | * <li>{@code true} (default): Fitness first mode - perform fitness tournaments first, then apply parsimony selection | |
84 | * between winners</li> | |
85 | * <li>{@code false}: Parsimony first mode - apply parsimony selection to random pairs first, then perform fitness | |
86 | * tournament among parsimony winners</li> | |
87 | * </ul> | |
88 | * | |
89 | * @return true for fitness-first mode, false for parsimony-first mode | |
90 | */ | |
91 | @Value.Default | |
92 | public boolean doFitnessFirst() { | |
93 |
2
1. doFitnessFirst : replaced boolean return with false for net/bmahe/genetics4j/gp/spec/selection/DoubleTournament::doFitnessFirst → KILLED 2. doFitnessFirst : Substituted 1 with 0 → KILLED |
return true; |
94 | } | |
95 | ||
96 | /** | |
97 | * Validates that the parsimony tournament size is within the allowed range [0.0, 2.0]. | |
98 | * | |
99 | * @throws IllegalArgumentException if parsimony tournament size is outside valid range | |
100 | */ | |
101 | @Value.Check | |
102 | public void check() { | |
103 | Validate.inclusiveBetween(0.0d, 2.0d, parsimonyTournamentSize()); | |
104 | } | |
105 | ||
106 | /** | |
107 | * Creates a new DoubleTournament selection policy with fitness-first mode enabled. | |
108 | * | |
109 | * @param <U> the fitness type, must be Comparable | |
110 | * @param fitnessTournament the tournament configuration for fitness-based selection | |
111 | * @param parsimonyComparator comparator for evaluating individual complexity | |
112 | * @param parsimonyTournamentSize selection pressure parameter, must be between 0.0 and 2.0 | |
113 | * @return a new DoubleTournament instance with the specified parameters | |
114 | * @throws IllegalArgumentException if parsimony tournament size is outside valid range | |
115 | */ | |
116 | public static <U extends Comparable<U>> DoubleTournament<U> of(final Tournament<U> fitnessTournament, | |
117 | final Comparator<Individual<U>> parsimonyComparator, final double parsimonyTournamentSize) { | |
118 |
2
1. of : removed call to net/bmahe/genetics4j/gp/spec/selection/ImmutableDoubleTournament::of → KILLED 2. of : replaced return value with null for net/bmahe/genetics4j/gp/spec/selection/DoubleTournament::of → KILLED |
return ImmutableDoubleTournament.of(fitnessTournament, parsimonyComparator, parsimonyTournamentSize); |
119 | } | |
120 | } | |
Mutations | ||
93 |
1.1 2.2 |
|
118 |
1.1 2.2 |