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

Mutations

127

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

128

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

146

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

181

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

183

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

185

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

187

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.19.6