NeatSelectionPolicyHandler.java

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

Mutations

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 randomGenerator → KILLED

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 speciesIdGenerator → KILLED

144

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

179

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

181

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

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/SelectionPolicyHandler::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()]
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.25.7 support