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 | |
23 | * existing nodes in NEAT neural networks. This is one of the fundamental structural mutations that | |
24 | * enables NEAT to explore different 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 | * <pre>{@code | |
53 | * // Create add-connection mutation policy | |
54 | * AddConnection addConnectionPolicy = AddConnection.of(0.1); // 10% mutation rate | |
55 | * | |
56 | * // Create policy handler | |
57 | * RandomGenerator randomGen = RandomGenerator.getDefault(); | |
58 | * AddConnectionPolicyHandler<Double> handler = new AddConnectionPolicyHandler<>(randomGen); | |
59 | * | |
60 | * // Check if handler can process the policy | |
61 | * boolean canHandle = handler.canHandle(resolver, addConnectionPolicy); | |
62 | * | |
63 | * // Create mutator for the policy | |
64 | * Mutator mutator = handler.createMutator( | |
65 | * executionContext, configuration, resolver, addConnectionPolicy | |
66 | * ); | |
67 | * | |
68 | * // Apply mutation to population | |
69 | * List<Individual<Double>> mutatedPopulation = mutator.mutate( | |
70 | * configuration, population | |
71 | * ); | |
72 | * }</pre> | |
73 | * | |
74 | * <p>Mutation policy configuration: | |
75 | * <ul> | |
76 | * <li><strong>Population probability</strong>: Fraction of population to apply mutation to</li> | |
77 | * <li><strong>Individual probability</strong>: Probability of mutating each selected individual</li> | |
78 | * <li><strong>Connection constraints</strong>: Rules governing valid connection additions</li> | |
79 | * <li><strong>Weight initialization</strong>: Strategy for setting initial connection weights</li> | |
80 | * </ul> | |
81 | * | |
82 | * <p>Structural constraints: | |
83 | * <ul> | |
84 | * <li><strong>Duplicate prevention</strong>: Avoids creating connections that already exist</li> | |
85 | * <li><strong>Cycle detection</strong>: Prevents creation of cycles in feed-forward networks</li> | |
86 | * <li><strong>Node validity</strong>: Ensures source and target nodes exist in the network</li> | |
87 | * <li><strong>Self-connection handling</strong>: May prevent or allow self-connections based on policy</li> | |
88 | * </ul> | |
89 | * | |
90 | * <p>Performance considerations: | |
91 | * <ul> | |
92 | * <li><strong>Innovation caching</strong>: Leverages InnovationManager for efficient number assignment</li> | |
93 | * <li><strong>Connection checking</strong>: Efficient algorithms for duplicate and cycle detection</li> | |
94 | * <li><strong>Memory efficiency</strong>: Minimal allocation during mutation operations</li> | |
95 | * <li><strong>Concurrent safety</strong>: Thread-safe for parallel mutation application</li> | |
96 | * </ul> | |
97 | * | |
98 | * @param <T> the fitness value type (typically Double) | |
99 | * @see AddConnection | |
100 | * @see net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeAddConnection | |
101 | * @see MutationPolicyHandler | |
102 | * @see InnovationManager | |
103 | */ | |
104 | public class AddConnectionPolicyHandler<T extends Comparable<T>> implements MutationPolicyHandler<T> { | |
105 | ||
106 | private final RandomGenerator randomGenerator; | |
107 | ||
108 | /** | |
109 | * Constructs a new add-connection policy handler with the specified random generator. | |
110 | * | |
111 | * <p>The random generator is used for stochastic decisions during mutation application, | |
112 | * including selection of individuals to mutate and choices within the mutation process. | |
113 | * | |
114 | * @param _randomGenerator random number generator for stochastic mutation operations | |
115 | * @throws IllegalArgumentException if randomGenerator is null | |
116 | */ | |
117 | public AddConnectionPolicyHandler(final RandomGenerator _randomGenerator) { | |
118 | Validate.notNull(_randomGenerator); | |
119 | ||
120 |
1
1. <init> : Removed assignment to member variable randomGenerator → KILLED |
this.randomGenerator = _randomGenerator; |
121 | } | |
122 | ||
123 | /** | |
124 | * Determines whether this handler can process the given mutation policy. | |
125 | * | |
126 | * <p>This handler specifically processes AddConnection mutation policies, which configure | |
127 | * the parameters for adding new connections to NEAT neural networks. | |
128 | * | |
129 | * @param mutationPolicyHandlerResolver resolver for nested mutation policies | |
130 | * @param mutationPolicy the mutation policy to check | |
131 | * @return true if the policy is an AddConnection instance, false otherwise | |
132 | * @throws IllegalArgumentException if any parameter is null | |
133 | */ | |
134 | @Override | |
135 | public boolean canHandle(final MutationPolicyHandlerResolver<T> mutationPolicyHandlerResolver, | |
136 | final MutationPolicy mutationPolicy) { | |
137 | Validate.notNull(mutationPolicyHandlerResolver); | |
138 | Validate.notNull(mutationPolicy); | |
139 | ||
140 |
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; |
141 | } | |
142 | ||
143 | /** | |
144 | * Creates a concrete mutator for add-connection mutations. | |
145 | * | |
146 | * <p>This method resolves the appropriate chromosome mutation handlers for NEAT chromosomes | |
147 | * and creates a generic mutator that applies add-connection mutations according to the | |
148 | * specified policy parameters. | |
149 | * | |
150 | * <p>Mutator creation process: | |
151 | * <ol> | |
152 | * <li>Extract population mutation probability from the policy</li> | |
153 | * <li>Resolve chromosome-specific mutation handlers</li> | |
154 | * <li>Create generic mutator with resolved components</li> | |
155 | * <li>Return configured mutator ready for population application</li> | |
156 | * </ol> | |
157 | * | |
158 | * @param eaExecutionContext execution context containing NEAT-specific components | |
159 | * @param eaConfiguration evolutionary algorithm configuration | |
160 | * @param mutationPolicyHandlerResolver resolver for chromosome mutation handlers | |
161 | * @param mutationPolicy the add-connection mutation policy | |
162 | * @return a configured mutator for applying add-connection mutations | |
163 | * @throws IllegalArgumentException if any parameter is null | |
164 | */ | |
165 | @Override | |
166 | public Mutator createMutator(final AbstractEAExecutionContext<T> eaExecutionContext, | |
167 | final AbstractEAConfiguration<T> eaConfiguration, | |
168 | final MutationPolicyHandlerResolver<T> mutationPolicyHandlerResolver, MutationPolicy mutationPolicy) { | |
169 | Validate.notNull(eaExecutionContext); | |
170 | Validate.notNull(eaConfiguration); | |
171 | Validate.notNull(mutationPolicy); | |
172 | Validate.notNull(mutationPolicyHandlerResolver); | |
173 | ||
174 | final AddConnection addConnectionMutationPolicy = (AddConnection) mutationPolicy; | |
175 |
1
1. createMutator : removed call to net/bmahe/genetics4j/neat/spec/mutation/AddConnection::populationMutationProbability → SURVIVED |
final double populationMutationProbability = addConnectionMutationPolicy.populationMutationProbability(); |
176 | ||
177 | final ChromosomeMutationHandler<? extends Chromosome>[] chromosomeMutationHandlers = ChromosomeResolverUtils | |
178 |
1
1. createMutator : removed call to net/bmahe/genetics4j/core/util/ChromosomeResolverUtils::resolveChromosomeMutationHandlers → KILLED |
.resolveChromosomeMutationHandlers(eaExecutionContext, eaConfiguration, mutationPolicy); |
179 | ||
180 |
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, |
181 | chromosomeMutationHandlers, | |
182 | mutationPolicy, | |
183 | populationMutationProbability); | |
184 | } | |
185 | } | |
Mutations | ||
120 |
1.1 |
|
140 |
1.1 2.2 |
|
175 |
1.1 |
|
178 |
1.1 |
|
180 |
1.1 2.2 |