NeatSelectionPolicyHandler.java

1
package net.bmahe.genetics4j.neat.selection;
2
3
import java.util.random.RandomGenerator;
4
5
import org.apache.commons.lang3.Validate;
6
import org.apache.logging.log4j.LogManager;
7
import org.apache.logging.log4j.Logger;
8
9
import net.bmahe.genetics4j.core.selection.SelectionPolicyHandler;
10
import net.bmahe.genetics4j.core.selection.SelectionPolicyHandlerResolver;
11
import net.bmahe.genetics4j.core.selection.Selector;
12
import net.bmahe.genetics4j.core.spec.AbstractEAConfiguration;
13
import net.bmahe.genetics4j.core.spec.AbstractEAExecutionContext;
14
import net.bmahe.genetics4j.core.spec.selection.SelectionPolicy;
15
import net.bmahe.genetics4j.neat.SpeciesIdGenerator;
16
import net.bmahe.genetics4j.neat.spec.selection.NeatSelection;
17
18
/**
19
 * Selection policy handler for NEAT (NeuroEvolution of Augmenting Topologies) species-based selection.
20
 * 
21
 * <p>NeatSelectionPolicyHandler implements the species-based selection mechanism that is fundamental to the NEAT
22
 * algorithm. It organizes the population into species based on genetic compatibility, applies fitness sharing within
23
 * species, and manages reproduction allocation across species to maintain population diversity and protect innovative
24
 * topologies.
25
 * 
26
 * <p>Key responsibilities:
27
 * <ul>
28
 * <li><strong>Species formation</strong>: Groups genetically similar individuals into species</li>
29
 * <li><strong>Fitness sharing</strong>: Adjusts individual fitness based on species membership</li>
30
 * <li><strong>Reproduction allocation</strong>: Distributes offspring across species based on average fitness</li>
31
 * <li><strong>Diversity preservation</strong>: Protects innovative topologies from elimination by established
32
 * forms</li>
33
 * </ul>
34
 * 
35
 * <p>NEAT species-based selection process:
36
 * <ol>
37
 * <li><strong>Compatibility calculation</strong>: Measure genetic distance between individuals</li>
38
 * <li><strong>Species assignment</strong>: Assign individuals to species based on compatibility thresholds</li>
39
 * <li><strong>Fitness adjustment</strong>: Apply fitness sharing within each species</li>
40
 * <li><strong>Species evaluation</strong>: Calculate average fitness for each species</li>
41
 * <li><strong>Reproduction allocation</strong>: Determine offspring count for each species</li>
42
 * <li><strong>Within-species selection</strong>: Select parents within each species for reproduction</li>
43
 * </ol>
44
 * 
45
 * <p>Species management features:
46
 * <ul>
47
 * <li><strong>Dynamic speciation</strong>: Species boundaries adjust as population evolves</li>
48
 * <li><strong>Species extinction</strong>: Poor-performing species are eliminated</li>
49
 * <li><strong>Representative tracking</strong>: Maintains species representatives for compatibility testing</li>
50
 * <li><strong>Population diversity</strong>: Prevents single topology from dominating</li>
51
 * </ul>
52
 * 
53
 * <p>Common usage patterns:
54
 * 
55
 * <pre>{@code
56
 * // Create NEAT selection policy handler
57
 * RandomGenerator randomGen = RandomGenerator.getDefault();
58
 * SpeciesIdGenerator speciesIdGen = new SpeciesIdGenerator();
59
 * 
60
 * NeatSelectionPolicyHandler<Double> handler = new NeatSelectionPolicyHandler<>(randomGen, speciesIdGen);
61
 * 
62
 * // Configure NEAT selection policy
63
 * NeatSelection<Double> neatSelection = NeatSelection.<Double>builder()
64
 * 		.compatibilityThreshold(3.0)
65
 * 		.speciesSelection(new TournamentSelection(3)) // Within-species selection
66
 * 		.build();
67
 * 
68
 * // Resolve selector for EA execution
69
 * Selector<Double> selector = handler.resolve(executionContext, configuration, resolverRegistry, neatSelection);
70
 * }</pre>
71
 * 
72
 * <p>Integration with genetic operators:
73
 * <ul>
74
 * <li><strong>Crossover compatibility</strong>: Species ensure genetic compatibility for meaningful recombination</li>
75
 * <li><strong>Mutation guidance</strong>: Species composition influences structural mutation rates</li>
76
 * <li><strong>Innovation protection</strong>: New topologies get time to optimize within their species</li>
77
 * <li><strong>Diversity maintenance</strong>: Multiple species explore different regions of topology space</li>
78
 * </ul>
79
 * 
80
 * <p>Performance considerations:
81
 * <ul>
82
 * <li><strong>Compatibility caching</strong>: Genetic distances cached for efficiency</li>
83
 * <li><strong>Species reuse</strong>: Species structures maintained across generations</li>
84
 * <li><strong>Parallel processing</strong>: Species-based selection enables concurrent evaluation</li>
85
 * <li><strong>Memory management</strong>: Efficient species membership tracking</li>
86
 * </ul>
87
 * 
88
 * <p>Selection policy delegation:
89
 * <ul>
90
 * <li><strong>Within-species selection</strong>: Delegates to standard selection policies (tournament, roulette,
91
 * etc.)</li>
92
 * <li><strong>Composable policies</strong>: Can combine with any standard selection mechanism</li>
93
 * <li><strong>Flexible configuration</strong>: Different species can use different selection strategies</li>
94
 * <li><strong>Performance optimization</strong>: Leverages existing high-performance selectors</li>
95
 * </ul>
96
 * 
97
 * @param <T> the fitness value type (typically Double)
98
 * @see NeatSelection
99
 * @see NeatSelectorImpl
100
 * @see Species
101
 * @see SpeciesIdGenerator
102
 * @see SelectionPolicyHandler
103
 */
104
public class NeatSelectionPolicyHandler<T extends Number & Comparable<T>> implements SelectionPolicyHandler<T> {
105
	public static final Logger logger = LogManager.getLogger(NeatSelectionPolicyHandler.class);
106
107
	private final RandomGenerator randomGenerator;
108
	private final SpeciesIdGenerator speciesIdGenerator;
109
110
	/**
111
	 * Constructs a new NEAT selection policy handler with the specified components.
112
	 * 
113
	 * <p>The random generator is used for stochastic operations during species formation and selection. The species ID
114
	 * generator provides unique identifiers for newly created species throughout the evolutionary process.
115
	 * 
116
	 * @param _randomGenerator    random number generator for stochastic operations
117
	 * @param _speciesIdGenerator generator for unique species identifiers
118
	 * @throws IllegalArgumentException if randomGenerator or speciesIdGenerator is null
119
	 */
120
	public NeatSelectionPolicyHandler(final RandomGenerator _randomGenerator,
121
			final SpeciesIdGenerator _speciesIdGenerator) {
122
		Validate.notNull(_randomGenerator);
123
		Validate.notNull(_speciesIdGenerator);
124
125 1 1. <init> : Removed assignment to member variable randomGenerator → KILLED
		this.randomGenerator = _randomGenerator;
126 1 1. <init> : Removed assignment to member variable speciesIdGenerator → KILLED
		this.speciesIdGenerator = _speciesIdGenerator;
127
	}
128
129
	/**
130
	 * Determines whether this handler can process the given selection policy.
131
	 * 
132
	 * <p>This handler specifically processes NeatSelection policies, which configure species-based selection with
133
	 * compatibility thresholds and within-species selection strategies.
134
	 * 
135
	 * @param selectionPolicy the selection policy to check
136
	 * @return true if the policy is a NeatSelection instance, false otherwise
137
	 * @throws IllegalArgumentException if selectionPolicy is null
138
	 */
139
	@Override
140
	public boolean canHandle(final SelectionPolicy selectionPolicy) {
141
		Validate.notNull(selectionPolicy);
142
143 2 1. canHandle : replaced boolean return with true for net/bmahe/genetics4j/neat/selection/NeatSelectionPolicyHandler::canHandle → KILLED
2. canHandle : replaced boolean return with false for net/bmahe/genetics4j/neat/selection/NeatSelectionPolicyHandler::canHandle → KILLED
		return selectionPolicy instanceof NeatSelection;
144
	}
145
146
	/**
147
	 * Resolves a NEAT selection policy into a concrete selector implementation.
148
	 * 
149
	 * <p>This method creates a NeatSelectorImpl that implements the species-based selection mechanism. It resolves the
150
	 * within-species selection policy using the provided resolver and configures the selector with the necessary NEAT
151
	 * components.
152
	 * 
153
	 * <p>Resolution process:
154
	 * <ol>
155
	 * <li>Extract the within-species selection policy from the NEAT selection configuration</li>
156
	 * <li>Resolve the within-species selection policy to a concrete selector</li>
157
	 * <li>Create a NeatSelectorImpl with all necessary components</li>
158
	 * <li>Return the configured selector ready for use in evolution</li>
159
	 * </ol>
160
	 * 
161
	 * @param eaExecutionContext             the execution context for the evolutionary algorithm
162
	 * @param eaConfiguration                the configuration for the evolutionary algorithm
163
	 * @param selectionPolicyHandlerResolver resolver for nested selection policies
164
	 * @param selectionPolicy                the NEAT selection policy to resolve
165
	 * @return a configured selector implementing NEAT species-based selection
166
	 * @throws IllegalArgumentException if selectionPolicy is null or not a NeatSelection
167
	 */
168
	@Override
169
	public Selector<T> resolve(final AbstractEAExecutionContext<T> eaExecutionContext,
170
			final AbstractEAConfiguration<T> eaConfiguration,
171
			final SelectionPolicyHandlerResolver<T> selectionPolicyHandlerResolver,
172
			final SelectionPolicy selectionPolicy) {
173
		Validate.notNull(selectionPolicy);
174
		Validate.isInstanceOf(NeatSelection.class, selectionPolicy);
175
176
		final NeatSelection<T> neatSelection = (NeatSelection<T>) selectionPolicy;
177
178 1 1. resolve : removed call to net/bmahe/genetics4j/neat/spec/selection/NeatSelection::speciesSelection → SURVIVED
		final SelectionPolicy speciesSelection = neatSelection.speciesSelection();
179
		final SelectionPolicyHandler<T> speciesSelectionPolicyHandler = selectionPolicyHandlerResolver
180 1 1. resolve : removed call to net/bmahe/genetics4j/core/selection/SelectionPolicyHandlerResolver::resolve → KILLED
				.resolve(speciesSelection);
181
		final Selector<T> speciesSelector = speciesSelectionPolicyHandler
182 1 1. resolve : removed call to net/bmahe/genetics4j/core/selection/SelectionPolicyHandler::resolve → KILLED
				.resolve(eaExecutionContext, eaConfiguration, selectionPolicyHandlerResolver, speciesSelection);
183
184 2 1. resolve : replaced return value with null for net/bmahe/genetics4j/neat/selection/NeatSelectionPolicyHandler::resolve → KILLED
2. resolve : removed call to net/bmahe/genetics4j/neat/selection/NeatSelectorImpl::<init> → KILLED
		return new NeatSelectorImpl<>(randomGenerator, neatSelection, speciesIdGenerator, speciesSelector);
185
	}
186
}

Mutations

125

1.1
Location : <init>
Killed by : net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest]/[method:resolve()]
Removed assignment to member variable randomGenerator → KILLED

126

1.1
Location : <init>
Killed by : net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest]/[method:resolve()]
Removed assignment to member variable speciesIdGenerator → KILLED

143

1.1
Location : canHandle
Killed by : net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest]/[method:canHandle()]
replaced boolean return with true for net/bmahe/genetics4j/neat/selection/NeatSelectionPolicyHandler::canHandle → KILLED

2.2
Location : canHandle
Killed by : net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest]/[method:canHandle()]
replaced boolean return with false for net/bmahe/genetics4j/neat/selection/NeatSelectionPolicyHandler::canHandle → KILLED

178

1.1
Location : resolve
Killed by : none
removed call to net/bmahe/genetics4j/neat/spec/selection/NeatSelection::speciesSelection → SURVIVED
Covering tests

180

1.1
Location : resolve
Killed by : net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest]/[method:resolve()]
removed call to net/bmahe/genetics4j/core/selection/SelectionPolicyHandlerResolver::resolve → KILLED

182

1.1
Location : resolve
Killed by : net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest]/[method:resolve()]
removed call to net/bmahe/genetics4j/core/selection/SelectionPolicyHandler::resolve → KILLED

184

1.1
Location : resolve
Killed by : net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest]/[method:resolve()]
replaced return value with null for net/bmahe/genetics4j/neat/selection/NeatSelectionPolicyHandler::resolve → KILLED

2.2
Location : resolve
Killed by : net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandlerTest]/[method:resolve()]
removed call to net/bmahe/genetics4j/neat/selection/NeatSelectorImpl::<init> → KILLED

Active mutators

Tests examined


Report generated by PIT 1.20.3