DoubleTournament.java

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
Location : doFitnessFirst
Killed by : net.bmahe.genetics4j.gp.selection.DoubleTournamentSelectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.gp.selection.DoubleTournamentSelectionPolicyHandlerTest]/[method:selectMaximize()]
replaced boolean return with false for net/bmahe/genetics4j/gp/spec/selection/DoubleTournament::doFitnessFirst → KILLED

2.2
Location : doFitnessFirst
Killed by : net.bmahe.genetics4j.gp.selection.DoubleTournamentSelectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.gp.selection.DoubleTournamentSelectionPolicyHandlerTest]/[method:selectMaximize()]
Substituted 1 with 0 → KILLED

118

1.1
Location : of
Killed by : net.bmahe.genetics4j.gp.selection.DoubleTournamentSelectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.gp.selection.DoubleTournamentSelectionPolicyHandlerTest]/[method:canHandle()]
removed call to net/bmahe/genetics4j/gp/spec/selection/ImmutableDoubleTournament::of → KILLED

2.2
Location : of
Killed by : net.bmahe.genetics4j.gp.selection.DoubleTournamentSelectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.gp.selection.DoubleTournamentSelectionPolicyHandlerTest]/[method:canHandle()]
replaced return value with null for net/bmahe/genetics4j/gp/spec/selection/DoubleTournament::of → KILLED

Active mutators

Tests examined


Report generated by PIT 1.20.3