NeatCombinationHandler.java

1
package net.bmahe.genetics4j.neat.combination;
2
3
import java.util.Optional;
4
import java.util.random.RandomGenerator;
5
6
import org.apache.commons.lang3.Validate;
7
8
import net.bmahe.genetics4j.core.combination.ChromosomeCombinator;
9
import net.bmahe.genetics4j.core.combination.ChromosomeCombinatorHandler;
10
import net.bmahe.genetics4j.core.combination.ChromosomeCombinatorResolver;
11
import net.bmahe.genetics4j.core.spec.chromosome.ChromosomeSpec;
12
import net.bmahe.genetics4j.core.spec.combination.CombinationPolicy;
13
import net.bmahe.genetics4j.neat.combination.parentcompare.ParentComparisonHandler;
14
import net.bmahe.genetics4j.neat.combination.parentcompare.ParentComparisonHandlerLocator;
15
import net.bmahe.genetics4j.neat.spec.NeatChromosomeSpec;
16
import net.bmahe.genetics4j.neat.spec.combination.NeatCombination;
17
import net.bmahe.genetics4j.neat.spec.combination.parentcompare.ParentComparisonPolicy;
18
19
/**
20
 * Chromosome combinator handler for NEAT (NeuroEvolution of Augmenting Topologies) genetic crossover.
21
 * 
22
 * <p>NeatCombinationHandler manages the genetic recombination process for NEAT neural networks, implementing
23
 * innovation-number-based gene alignment and parent comparison strategies. This handler resolves NEAT-specific
24
 * combination policies into concrete chromosome combinators that understand neural network topology and can perform
25
 * meaningful genetic crossover between different network structures.
26
 * 
27
 * <p>Key responsibilities:
28
 * <ul>
29
 * <li><strong>Policy resolution</strong>: Converts NeatCombination policies into executable combinators</li>
30
 * <li><strong>Parent comparison</strong>: Manages strategies for determining genetic inheritance patterns</li>
31
 * <li><strong>Innovation alignment</strong>: Ensures proper gene alignment using innovation numbers</li>
32
 * <li><strong>Topology crossover</strong>: Handles recombination of different network topologies</li>
33
 * </ul>
34
 * 
35
 * <p>NEAT genetic crossover features:
36
 * <ul>
37
 * <li><strong>Innovation-based alignment</strong>: Genes matched by innovation number for meaningful recombination</li>
38
 * <li><strong>Matching genes</strong>: Genes with same innovation number can be inherited from either parent</li>
39
 * <li><strong>Disjoint genes</strong>: Genes unique to one parent in middle innovation number ranges</li>
40
 * <li><strong>Excess genes</strong>: Genes beyond the highest innovation number of less fit parent</li>
41
 * </ul>
42
 * 
43
 * <p>Parent comparison strategies:
44
 * <ul>
45
 * <li><strong>Fitness-based inheritance</strong>: More fit parent contributes disjoint and excess genes</li>
46
 * <li><strong>Equal fitness handling</strong>: Special rules when parents have equal fitness</li>
47
 * <li><strong>Random inheritance</strong>: Stochastic gene inheritance for matching genes</li>
48
 * <li><strong>Topology preservation</strong>: Ensures offspring have valid network topologies</li>
49
 * </ul>
50
 * 
51
 * <p>Common usage patterns:
52
 * 
53
 * <pre>{@code
54
 * // Create NEAT combination handler
55
 * RandomGenerator randomGen = RandomGenerator.getDefault();
56
 * NeatCombinationHandler<Double> handler = new NeatCombinationHandler<>(randomGen);
57
 * 
58
 * // Check if handler can process combination policy
59
 * NeatCombination policy = NeatCombination.builder()
60
 * 		.parentComparisonPolicy(new FitnessComparison())
61
 * 		.build();
62
 * NeatChromosomeSpec spec = NeatChromosomeSpec.of(3, 2, -1.0f, 1.0f);
63
 * 
64
 * boolean canHandle = handler.canHandle(resolver, policy, spec);
65
 * 
66
 * // Resolve to concrete combinator
67
 * ChromosomeCombinator<Double> combinator = handler.resolve(resolver, policy, spec);
68
 * }</pre>
69
 * 
70
 * <p>Integration with genetic algorithm framework:
71
 * <ul>
72
 * <li><strong>Handler registration</strong>: Registered in EA execution context for automatic resolution</li>
73
 * <li><strong>Policy-driven configuration</strong>: Behavior controlled by NeatCombination specifications</li>
74
 * <li><strong>Resolver integration</strong>: Works with chromosome combinator resolver system</li>
75
 * <li><strong>Type safety</strong>: Ensures compatibility between policies and chromosome specifications</li>
76
 * </ul>
77
 * 
78
 * <p>Parent comparison handler management:
79
 * <ul>
80
 * <li><strong>Handler locator</strong>: Uses ParentComparisonHandlerLocator for strategy resolution</li>
81
 * <li><strong>Strategy flexibility</strong>: Supports different parent comparison approaches</li>
82
 * <li><strong>Extensibility</strong>: New comparison strategies can be easily added</li>
83
 * <li><strong>Policy validation</strong>: Ensures configured strategies are available</li>
84
 * </ul>
85
 * 
86
 * <p>Performance considerations:
87
 * <ul>
88
 * <li><strong>Handler caching</strong>: Parent comparison handlers cached for reuse</li>
89
 * <li><strong>Innovation sorting</strong>: Leverages pre-sorted connection lists for efficiency</li>
90
 * <li><strong>Memory efficiency</strong>: Minimal memory allocation during crossover</li>
91
 * <li><strong>Parallel processing</strong>: Thread-safe operations for concurrent crossover</li>
92
 * </ul>
93
 * 
94
 * @param <T> the fitness value type (typically Double)
95
 * @see NeatCombination
96
 * @see NeatChromosomeCombinator
97
 * @see ParentComparisonHandler
98
 * @see ChromosomeCombinatorHandler
99
 */
100
public class NeatCombinationHandler<T extends Comparable<T>> implements ChromosomeCombinatorHandler<T> {
101
102
	private final RandomGenerator randomGenerator;
103
	private final ParentComparisonHandlerLocator parentComparisonHandlerLocator;
104
105
	/**
106
	 * Constructs a new NEAT combination handler with the specified random generator.
107
	 * 
108
	 * <p>The random generator is used for stochastic decisions during genetic crossover, such as choosing which parent
109
	 * contributes genes when multiple options are available. A parent comparison handler locator is automatically
110
	 * created to manage comparison strategies.
111
	 * 
112
	 * @param _randomGenerator random number generator for stochastic crossover operations
113
	 * @throws IllegalArgumentException if randomGenerator is null
114
	 */
115
	public NeatCombinationHandler(final RandomGenerator _randomGenerator) {
116
		Validate.notNull(_randomGenerator);
117
118 1 1. <init> : Removed assignment to member variable randomGenerator → KILLED
		this.randomGenerator = _randomGenerator;
119 2 1. <init> : Removed assignment to member variable parentComparisonHandlerLocator → KILLED
2. <init> : removed call to net/bmahe/genetics4j/neat/combination/parentcompare/ParentComparisonHandlerLocator::<init> → KILLED
		this.parentComparisonHandlerLocator = new ParentComparisonHandlerLocator();
120
	}
121
122
	/**
123
	 * Determines whether this handler can process the given combination policy and chromosome specification.
124
	 * 
125
	 * <p>This handler specifically processes NeatCombination policies applied to NeatChromosomeSpec specifications,
126
	 * ensuring type compatibility for NEAT neural network genetic crossover.
127
	 * 
128
	 * @param chromosomeCombinatorResolver resolver for nested combination policies
129
	 * @param combinationPolicy            the combination policy to check
130
	 * @param chromosome                   the chromosome specification to check
131
	 * @return true if policy is NeatCombination and chromosome is NeatChromosomeSpec, false otherwise
132
	 * @throws IllegalArgumentException if any parameter is null
133
	 */
134
	@Override
135
	public boolean canHandle(final ChromosomeCombinatorResolver<T> chromosomeCombinatorResolver,
136
			final CombinationPolicy combinationPolicy, final ChromosomeSpec chromosome) {
137
		Validate.notNull(chromosomeCombinatorResolver);
138
		Validate.notNull(combinationPolicy);
139
		Validate.notNull(chromosome);
140
141 9 1. canHandle : Substituted 0 with 1 → KILLED
2. canHandle : removed conditional - replaced equality check with true → KILLED
3. canHandle : replaced boolean return with true for net/bmahe/genetics4j/neat/combination/NeatCombinationHandler::canHandle → KILLED
4. canHandle : removed conditional - replaced equality check with true → KILLED
5. canHandle : Substituted 1 with 0 → KILLED
6. canHandle : removed conditional - replaced equality check with false → KILLED
7. canHandle : negated conditional → KILLED
8. canHandle : negated conditional → KILLED
9. canHandle : removed conditional - replaced equality check with false → KILLED
		return combinationPolicy instanceof NeatCombination && chromosome instanceof NeatChromosomeSpec;
142
	}
143
144
	/**
145
	 * Resolves a NEAT combination policy into a concrete chromosome combinator.
146
	 * 
147
	 * <p>This method creates a NeatChromosomeCombinator configured with the appropriate parent comparison strategy. The
148
	 * parent comparison policy is resolved using the handler locator to determine how genetic inheritance should be
149
	 * managed during crossover.
150
	 * 
151
	 * <p>Resolution process:
152
	 * <ol>
153
	 * <li>Extract parent comparison policy from the NEAT combination configuration</li>
154
	 * <li>Locate appropriate parent comparison handler for the policy</li>
155
	 * <li>Create NeatChromosomeCombinator with resolved components</li>
156
	 * <li>Return configured combinator ready for genetic crossover</li>
157
	 * </ol>
158
	 * 
159
	 * @param chromosomeCombinatorResolver resolver for nested combination policies
160
	 * @param combinationPolicy            the NEAT combination policy to resolve
161
	 * @param chromosome                   the NEAT chromosome specification
162
	 * @return a configured chromosome combinator for NEAT genetic crossover
163
	 * @throws IllegalArgumentException if any parameter is null or of wrong type
164
	 * @throws IllegalStateException    if no parent comparison handler found for the policy
165
	 */
166
	@Override
167
	public ChromosomeCombinator<T> resolve(final ChromosomeCombinatorResolver<T> chromosomeCombinatorResolver,
168
			final CombinationPolicy combinationPolicy, final ChromosomeSpec chromosome) {
169
		Validate.notNull(chromosomeCombinatorResolver);
170
		Validate.notNull(combinationPolicy);
171
		Validate.notNull(chromosome);
172
		Validate.isInstanceOf(NeatCombination.class, combinationPolicy);
173
		Validate.isInstanceOf(NeatChromosomeSpec.class, chromosome);
174
175
		final var neatCombination = (NeatCombination) combinationPolicy;
176
177 1 1. resolve : removed call to net/bmahe/genetics4j/neat/spec/combination/NeatCombination::parentComparisonPolicy → KILLED
		final ParentComparisonPolicy parentComparisonPolicy = neatCombination.parentComparisonPolicy();
178
		final Optional<ParentComparisonHandler> parentComparisonHandlerOpt = parentComparisonHandlerLocator
179 1 1. resolve : removed call to net/bmahe/genetics4j/neat/combination/parentcompare/ParentComparisonHandlerLocator::find → KILLED
				.find(parentComparisonPolicy);
180
		final ParentComparisonHandler parentComparisonHandler = parentComparisonHandlerOpt
181 4 1. lambda$resolve$0 : removed call to java/lang/IllegalStateException::<init> → NO_COVERAGE
2. lambda$resolve$0 : removed call to java/lang/String::valueOf → NO_COVERAGE
3. lambda$resolve$0 : replaced return value with null for net/bmahe/genetics4j/neat/combination/NeatCombinationHandler::lambda$resolve$0 → NO_COVERAGE
4. resolve : removed call to java/util/Optional::orElseThrow → KILLED
				.orElseThrow(() -> new IllegalStateException(
182
						"Could not find a parent comparison handler for policy: " + parentComparisonPolicy));
183
184 2 1. resolve : replaced return value with null for net/bmahe/genetics4j/neat/combination/NeatCombinationHandler::resolve → KILLED
2. resolve : removed call to net/bmahe/genetics4j/neat/combination/NeatChromosomeCombinator::<init> → KILLED
		return new NeatChromosomeCombinator<>(randomGenerator, neatCombination, parentComparisonHandler);
185
	}
186
}

Mutations

118

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

119

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

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

141

1.1
Location : canHandle
Killed by : net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest]/[method:canTest()]
Substituted 0 with 1 → KILLED

2.2
Location : canHandle
Killed by : net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest]/[method:canTest()]
removed conditional - replaced equality check with true → KILLED

3.3
Location : canHandle
Killed by : net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest]/[method:canTest()]
replaced boolean return with true for net/bmahe/genetics4j/neat/combination/NeatCombinationHandler::canHandle → KILLED

4.4
Location : canHandle
Killed by : net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest]/[method:canTest()]
removed conditional - replaced equality check with true → KILLED

5.5
Location : canHandle
Killed by : net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest]/[method:canTest()]
Substituted 1 with 0 → KILLED

6.6
Location : canHandle
Killed by : net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest]/[method:canTest()]
removed conditional - replaced equality check with false → KILLED

7.7
Location : canHandle
Killed by : net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest]/[method:canTest()]
negated conditional → KILLED

8.8
Location : canHandle
Killed by : net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest]/[method:canTest()]
negated conditional → KILLED

9.9
Location : canHandle
Killed by : net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest]/[method:canTest()]
removed conditional - replaced equality check with false → KILLED

177

1.1
Location : resolve
Killed by : net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest]/[method:resolve()]
removed call to net/bmahe/genetics4j/neat/spec/combination/NeatCombination::parentComparisonPolicy → KILLED

179

1.1
Location : resolve
Killed by : net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest]/[method:resolve()]
removed call to net/bmahe/genetics4j/neat/combination/parentcompare/ParentComparisonHandlerLocator::find → KILLED

181

1.1
Location : lambda$resolve$0
Killed by : none
removed call to java/lang/IllegalStateException::<init> → NO_COVERAGE

2.2
Location : resolve
Killed by : net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatCombinationHandlerTest]/[method:resolve()]
removed call to java/util/Optional::orElseThrow → KILLED

3.3
Location : lambda$resolve$0
Killed by : none
removed call to java/lang/String::valueOf → NO_COVERAGE

4.4
Location : lambda$resolve$0
Killed by : none
replaced return value with null for net/bmahe/genetics4j/neat/combination/NeatCombinationHandler::lambda$resolve$0 → NO_COVERAGE

184

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

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

Active mutators

Tests examined


Report generated by PIT 1.20.3