AddConnectionPolicyHandler.java

1
package net.bmahe.genetics4j.neat.mutation;
2
3
import java.util.random.RandomGenerator;
4
5
import org.apache.commons.lang3.Validate;
6
7
import net.bmahe.genetics4j.core.chromosomes.Chromosome;
8
import net.bmahe.genetics4j.core.mutation.GenericMutatorImpl;
9
import net.bmahe.genetics4j.core.mutation.MutationPolicyHandler;
10
import net.bmahe.genetics4j.core.mutation.MutationPolicyHandlerResolver;
11
import net.bmahe.genetics4j.core.mutation.Mutator;
12
import net.bmahe.genetics4j.core.mutation.chromosome.ChromosomeMutationHandler;
13
import net.bmahe.genetics4j.core.spec.AbstractEAConfiguration;
14
import net.bmahe.genetics4j.core.spec.AbstractEAExecutionContext;
15
import net.bmahe.genetics4j.core.spec.mutation.MutationPolicy;
16
import net.bmahe.genetics4j.core.util.ChromosomeResolverUtils;
17
import net.bmahe.genetics4j.neat.spec.mutation.AddConnection;
18
19
/**
20
 * Mutation policy handler for NEAT (NeuroEvolution of Augmenting Topologies) add-connection mutations.
21
 * 
22
 * <p>AddConnectionPolicyHandler manages the structural mutation that adds new connections between existing nodes in
23
 * NEAT neural networks. This is one of the fundamental structural mutations that enables NEAT to explore different
24
 * network topologies by increasing connectivity complexity.
25
 * 
26
 * <p>Add-connection mutation process:
27
 * <ol>
28
 * <li><strong>Node selection</strong>: Choose source and target nodes for the new connection</li>
29
 * <li><strong>Validity checking</strong>: Ensure connection doesn't already exist and doesn't create cycles</li>
30
 * <li><strong>Innovation assignment</strong>: Assign unique innovation number to the new connection</li>
31
 * <li><strong>Weight initialization</strong>: Set initial weight for the new connection</li>
32
 * <li><strong>Connection creation</strong>: Add enabled connection to the chromosome</li>
33
 * </ol>
34
 * 
35
 * <p>Key characteristics:
36
 * <ul>
37
 * <li><strong>Structural evolution</strong>: Increases network connectivity without adding nodes</li>
38
 * <li><strong>Innovation tracking</strong>: New connections receive unique innovation numbers</li>
39
 * <li><strong>Topology exploration</strong>: Enables discovery of useful connection patterns</li>
40
 * <li><strong>Gradual complexity</strong>: Incrementally increases network complexity</li>
41
 * </ul>
42
 * 
43
 * <p>Integration with NEAT algorithm:
44
 * <ul>
45
 * <li><strong>Innovation management</strong>: Coordinates with InnovationManager for tracking</li>
46
 * <li><strong>Chromosome mutation</strong>: Delegates to NeatChromosomeAddConnection handler</li>
47
 * <li><strong>Population evolution</strong>: Applied based on configured mutation probability</li>
48
 * <li><strong>Genetic diversity</strong>: Maintains structural diversity in the population</li>
49
 * </ul>
50
 * 
51
 * <p>Common usage patterns:
52
 * 
53
 * <pre>{@code
54
 * // Create add-connection mutation policy
55
 * AddConnection addConnectionPolicy = AddConnection.of(0.1); // 10% mutation rate
56
 * 
57
 * // Create policy handler
58
 * RandomGenerator randomGen = RandomGenerator.getDefault();
59
 * AddConnectionPolicyHandler<Double> handler = new AddConnectionPolicyHandler<>(randomGen);
60
 * 
61
 * // Check if handler can process the policy
62
 * boolean canHandle = handler.canHandle(resolver, addConnectionPolicy);
63
 * 
64
 * // Create mutator for the policy
65
 * Mutator mutator = handler.createMutator(executionContext, configuration, resolver, addConnectionPolicy);
66
 * 
67
 * // Apply mutation to population
68
 * List<Individual<Double>> mutatedPopulation = mutator.mutate(configuration, population);
69
 * }</pre>
70
 * 
71
 * <p>Mutation policy configuration:
72
 * <ul>
73
 * <li><strong>Population probability</strong>: Fraction of population to apply mutation to</li>
74
 * <li><strong>Individual probability</strong>: Probability of mutating each selected individual</li>
75
 * <li><strong>Connection constraints</strong>: Rules governing valid connection additions</li>
76
 * <li><strong>Weight initialization</strong>: Strategy for setting initial connection weights</li>
77
 * </ul>
78
 * 
79
 * <p>Structural constraints:
80
 * <ul>
81
 * <li><strong>Duplicate prevention</strong>: Avoids creating connections that already exist</li>
82
 * <li><strong>Cycle detection</strong>: Prevents creation of cycles in feed-forward networks</li>
83
 * <li><strong>Node validity</strong>: Ensures source and target nodes exist in the network</li>
84
 * <li><strong>Self-connection handling</strong>: May prevent or allow self-connections based on policy</li>
85
 * </ul>
86
 * 
87
 * <p>Performance considerations:
88
 * <ul>
89
 * <li><strong>Innovation caching</strong>: Leverages InnovationManager for efficient number assignment</li>
90
 * <li><strong>Connection checking</strong>: Efficient algorithms for duplicate and cycle detection</li>
91
 * <li><strong>Memory efficiency</strong>: Minimal allocation during mutation operations</li>
92
 * <li><strong>Concurrent safety</strong>: Thread-safe for parallel mutation application</li>
93
 * </ul>
94
 * 
95
 * @param <T> the fitness value type (typically Double)
96
 * @see AddConnection
97
 * @see net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeAddConnection
98
 * @see MutationPolicyHandler
99
 * @see InnovationManager
100
 */
101
public class AddConnectionPolicyHandler<T extends Comparable<T>> implements MutationPolicyHandler<T> {
102
103
	private final RandomGenerator randomGenerator;
104
105
	/**
106
	 * Constructs a new add-connection policy handler with the specified random generator.
107
	 * 
108
	 * <p>The random generator is used for stochastic decisions during mutation application, including selection of
109
	 * individuals to mutate and choices within the mutation process.
110
	 * 
111
	 * @param _randomGenerator random number generator for stochastic mutation operations
112
	 * @throws IllegalArgumentException if randomGenerator is null
113
	 */
114
	public AddConnectionPolicyHandler(final RandomGenerator _randomGenerator) {
115
		Validate.notNull(_randomGenerator);
116
117 1 1. <init> : Removed assignment to member variable randomGenerator → KILLED
		this.randomGenerator = _randomGenerator;
118
	}
119
120
	/**
121
	 * Determines whether this handler can process the given mutation policy.
122
	 * 
123
	 * <p>This handler specifically processes AddConnection mutation policies, which configure the parameters for adding
124
	 * new connections to NEAT neural networks.
125
	 * 
126
	 * @param mutationPolicyHandlerResolver resolver for nested mutation policies
127
	 * @param mutationPolicy                the mutation policy to check
128
	 * @return true if the policy is an AddConnection instance, false otherwise
129
	 * @throws IllegalArgumentException if any parameter is null
130
	 */
131
	@Override
132
	public boolean canHandle(final MutationPolicyHandlerResolver<T> mutationPolicyHandlerResolver,
133
			final MutationPolicy mutationPolicy) {
134
		Validate.notNull(mutationPolicyHandlerResolver);
135
		Validate.notNull(mutationPolicy);
136
137 2 1. canHandle : replaced boolean return with false for net/bmahe/genetics4j/neat/mutation/AddConnectionPolicyHandler::canHandle → KILLED
2. canHandle : replaced boolean return with true for net/bmahe/genetics4j/neat/mutation/AddConnectionPolicyHandler::canHandle → KILLED
		return mutationPolicy instanceof AddConnection;
138
	}
139
140
	/**
141
	 * Creates a concrete mutator for add-connection mutations.
142
	 * 
143
	 * <p>This method resolves the appropriate chromosome mutation handlers for NEAT chromosomes and creates a generic
144
	 * mutator that applies add-connection mutations according to the specified policy parameters.
145
	 * 
146
	 * <p>Mutator creation process:
147
	 * <ol>
148
	 * <li>Extract population mutation probability from the policy</li>
149
	 * <li>Resolve chromosome-specific mutation handlers</li>
150
	 * <li>Create generic mutator with resolved components</li>
151
	 * <li>Return configured mutator ready for population application</li>
152
	 * </ol>
153
	 * 
154
	 * @param eaExecutionContext            execution context containing NEAT-specific components
155
	 * @param eaConfiguration               evolutionary algorithm configuration
156
	 * @param mutationPolicyHandlerResolver resolver for chromosome mutation handlers
157
	 * @param mutationPolicy                the add-connection mutation policy
158
	 * @return a configured mutator for applying add-connection mutations
159
	 * @throws IllegalArgumentException if any parameter is null
160
	 */
161
	@Override
162
	public Mutator createMutator(final AbstractEAExecutionContext<T> eaExecutionContext,
163
			final AbstractEAConfiguration<T> eaConfiguration,
164
			final MutationPolicyHandlerResolver<T> mutationPolicyHandlerResolver, MutationPolicy mutationPolicy) {
165
		Validate.notNull(eaExecutionContext);
166
		Validate.notNull(eaConfiguration);
167
		Validate.notNull(mutationPolicy);
168
		Validate.notNull(mutationPolicyHandlerResolver);
169
170
		final AddConnection addConnectionMutationPolicy = (AddConnection) mutationPolicy;
171 1 1. createMutator : removed call to net/bmahe/genetics4j/neat/spec/mutation/AddConnection::populationMutationProbability → SURVIVED
		final double populationMutationProbability = addConnectionMutationPolicy.populationMutationProbability();
172
173
		final ChromosomeMutationHandler<? extends Chromosome>[] chromosomeMutationHandlers = ChromosomeResolverUtils
174 1 1. createMutator : removed call to net/bmahe/genetics4j/core/util/ChromosomeResolverUtils::resolveChromosomeMutationHandlers → KILLED
				.resolveChromosomeMutationHandlers(eaExecutionContext, eaConfiguration, mutationPolicy);
175
176 2 1. createMutator : removed call to net/bmahe/genetics4j/core/mutation/GenericMutatorImpl::<init> → KILLED
2. createMutator : replaced return value with null for net/bmahe/genetics4j/neat/mutation/AddConnectionPolicyHandler::createMutator → KILLED
		return new GenericMutatorImpl(randomGenerator,
177
				chromosomeMutationHandlers,
178
				mutationPolicy,
179
				populationMutationProbability);
180
	}
181
}

Mutations

117

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

137

1.1
Location : canHandle
Killed by : net.bmahe.genetics4j.neat.mutation.AddConnectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.mutation.AddConnectionPolicyHandlerTest]/[method:canHandleRequireMutation()]
replaced boolean return with false for net/bmahe/genetics4j/neat/mutation/AddConnectionPolicyHandler::canHandle → KILLED

2.2
Location : canHandle
Killed by : net.bmahe.genetics4j.neat.mutation.AddConnectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.mutation.AddConnectionPolicyHandlerTest]/[method:canHandleRequireMutation()]
replaced boolean return with true for net/bmahe/genetics4j/neat/mutation/AddConnectionPolicyHandler::canHandle → KILLED

171

1.1
Location : createMutator
Killed by : none
removed call to net/bmahe/genetics4j/neat/spec/mutation/AddConnection::populationMutationProbability → SURVIVED
Covering tests

174

1.1
Location : createMutator
Killed by : net.bmahe.genetics4j.neat.mutation.AddConnectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.mutation.AddConnectionPolicyHandlerTest]/[method:createMutator()]
removed call to net/bmahe/genetics4j/core/util/ChromosomeResolverUtils::resolveChromosomeMutationHandlers → KILLED

176

1.1
Location : createMutator
Killed by : net.bmahe.genetics4j.neat.mutation.AddConnectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.mutation.AddConnectionPolicyHandlerTest]/[method:createMutator()]
removed call to net/bmahe/genetics4j/core/mutation/GenericMutatorImpl::<init> → KILLED

2.2
Location : createMutator
Killed by : net.bmahe.genetics4j.neat.mutation.AddConnectionPolicyHandlerTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.mutation.AddConnectionPolicyHandlerTest]/[method:createMutator()]
replaced return value with null for net/bmahe/genetics4j/neat/mutation/AddConnectionPolicyHandler::createMutator → KILLED

Active mutators

Tests examined


Report generated by PIT 1.20.3