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.NeatConnectionWeight; | |
18 | ||
19 | /** | |
20 | * Mutation policy handler for NEAT (NeuroEvolution of Augmenting Topologies) connection weight mutations. | |
21 | * | |
22 | * <p>NeatConnectionWeightPolicyHandler manages weight mutations for NEAT neural network connections, | |
23 | * which are essential for fine-tuning network behavior and optimizing performance. Weight mutations | |
24 | * are typically the most frequent type of mutation in NEAT evolution, applied to existing connections | |
25 | * to improve network functionality. | |
26 | * | |
27 | * <p>Weight mutation strategies: | |
28 | * <ul> | |
29 | * <li><strong>Gaussian perturbation</strong>: Add small random values to existing weights</li> | |
30 | * <li><strong>Random replacement</strong>: Replace weights with new random values</li> | |
31 | * <li><strong>Creep mutation</strong>: Small incremental changes to weights</li> | |
32 | * <li><strong>Uniform perturbation</strong>: Add uniform random noise to weights</li> | |
33 | * </ul> | |
34 | * | |
35 | * <p>Key characteristics: | |
36 | * <ul> | |
37 | * <li><strong>Behavioral optimization</strong>: Fine-tunes network behavior without changing topology</li> | |
38 | * <li><strong>High frequency</strong>: Applied more often than structural mutations</li> | |
39 | * <li><strong>Bounded values</strong>: Respects chromosome weight bounds during mutation</li> | |
40 | * <li><strong>Continuous evolution</strong>: Enables continuous improvement of network performance</li> | |
41 | * </ul> | |
42 | * | |
43 | * <p>Integration with NEAT algorithm: | |
44 | * <ul> | |
45 | * <li><strong>Chromosome mutation</strong>: Delegates to NEAT chromosome weight mutation handlers</li> | |
46 | * <li><strong>Population evolution</strong>: Applied based on configured mutation probability</li> | |
47 | * <li><strong>Performance optimization</strong>: Primary mechanism for network performance tuning</li> | |
48 | * <li><strong>Genetic diversity</strong>: Maintains behavioral diversity in the population</li> | |
49 | * </ul> | |
50 | * | |
51 | * <p>Common usage patterns: | |
52 | * <pre>{@code | |
53 | * // Create weight mutation policy | |
54 | * NeatConnectionWeight weightPolicy = NeatConnectionWeight.builder() | |
55 | * .populationMutationProbability(0.8) // 80% of population | |
56 | * .chromosomeMutationProbability(0.9) // 90% of connections per chromosome | |
57 | * .mutationStandardDeviation(0.1) // Standard deviation for Gaussian perturbation | |
58 | * .build(); | |
59 | * | |
60 | * // Create policy handler | |
61 | * RandomGenerator randomGen = RandomGenerator.getDefault(); | |
62 | * NeatConnectionWeightPolicyHandler<Double> handler = | |
63 | * new NeatConnectionWeightPolicyHandler<>(randomGen); | |
64 | * | |
65 | * // Check if handler can process the policy | |
66 | * boolean canHandle = handler.canHandle(resolver, weightPolicy); | |
67 | * | |
68 | * // Create mutator for the policy | |
69 | * Mutator mutator = handler.createMutator( | |
70 | * executionContext, configuration, resolver, weightPolicy | |
71 | * ); | |
72 | * }</pre> | |
73 | * | |
74 | * <p>Weight mutation effects: | |
75 | * <ul> | |
76 | * <li><strong>Performance tuning</strong>: Optimizes network output for better fitness</li> | |
77 | * <li><strong>Exploration vs exploitation</strong>: Balances exploration of weight space with convergence</li> | |
78 | * <li><strong>Gradient-like behavior</strong>: Can simulate gradient-based optimization</li> | |
79 | * <li><strong>Population diversity</strong>: Maintains diverse behavioral patterns</li> | |
80 | * </ul> | |
81 | * | |
82 | * <p>Mutation policy configuration: | |
83 | * <ul> | |
84 | * <li><strong>Population probability</strong>: Fraction of population to apply mutations to</li> | |
85 | * <li><strong>Chromosome probability</strong>: Fraction of connections to mutate per chromosome</li> | |
86 | * <li><strong>Mutation magnitude</strong>: Size of weight perturbations</li> | |
87 | * <li><strong>Mutation type</strong>: Strategy for weight modification (Gaussian, uniform, etc.)</li> | |
88 | * </ul> | |
89 | * | |
90 | * <p>Performance considerations: | |
91 | * <ul> | |
92 | * <li><strong>High frequency application</strong>: Efficient implementation for frequent use</li> | |
93 | * <li><strong>Memory efficiency</strong>: Minimal allocation during weight modification</li> | |
94 | * <li><strong>Numerical stability</strong>: Maintains weight values within valid ranges</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 NeatConnectionWeight | |
100 | * @see net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeConnectionWeightMutationHandler | |
101 | * @see MutationPolicyHandler | |
102 | */ | |
103 | public class NeatConnectionWeightPolicyHandler<T extends Comparable<T>> implements MutationPolicyHandler<T> { | |
104 | ||
105 | private final RandomGenerator randomGenerator; | |
106 | ||
107 | /** | |
108 | * Constructs a new connection weight policy handler with the specified random generator. | |
109 | * | |
110 | * <p>The random generator is used for stochastic decisions during mutation application, | |
111 | * including selection of individuals to mutate and generation of weight perturbations. | |
112 | * | |
113 | * @param _randomGenerator random number generator for stochastic mutation operations | |
114 | * @throws IllegalArgumentException if randomGenerator is null | |
115 | */ | |
116 | public NeatConnectionWeightPolicyHandler(final RandomGenerator _randomGenerator) { | |
117 | Validate.notNull(_randomGenerator); | |
118 | ||
119 |
1
1. <init> : Removed assignment to member variable randomGenerator → KILLED |
this.randomGenerator = _randomGenerator; |
120 | } | |
121 | ||
122 | /** | |
123 | * Determines whether this handler can process the given mutation policy. | |
124 | * | |
125 | * <p>This handler specifically processes NeatConnectionWeight mutation policies, which | |
126 | * configure the parameters for mutating connection weights in NEAT neural networks. | |
127 | * | |
128 | * @param mutationPolicyHandlerResolver resolver for nested mutation policies | |
129 | * @param mutationPolicy the mutation policy to check | |
130 | * @return true if the policy is a NeatConnectionWeight instance, false otherwise | |
131 | * @throws IllegalArgumentException if any parameter is null | |
132 | */ | |
133 | @Override | |
134 | public boolean canHandle(final MutationPolicyHandlerResolver<T> mutationPolicyHandlerResolver, | |
135 | final MutationPolicy mutationPolicy) { | |
136 | Validate.notNull(mutationPolicyHandlerResolver); | |
137 | Validate.notNull(mutationPolicy); | |
138 | ||
139 |
2
1. canHandle : replaced boolean return with false for net/bmahe/genetics4j/neat/mutation/NeatConnectionWeightPolicyHandler::canHandle → KILLED 2. canHandle : replaced boolean return with true for net/bmahe/genetics4j/neat/mutation/NeatConnectionWeightPolicyHandler::canHandle → KILLED |
return mutationPolicy instanceof NeatConnectionWeight; |
140 | } | |
141 | ||
142 | /** | |
143 | * Creates a concrete mutator for connection weight mutations. | |
144 | * | |
145 | * <p>This method resolves the appropriate chromosome mutation handlers for NEAT chromosomes | |
146 | * and creates a generic mutator that applies weight mutations according to the | |
147 | * specified policy parameters. | |
148 | * | |
149 | * <p>Mutator creation process: | |
150 | * <ol> | |
151 | * <li>Extract population mutation probability from the policy</li> | |
152 | * <li>Resolve chromosome-specific mutation handlers</li> | |
153 | * <li>Create generic mutator with resolved components</li> | |
154 | * <li>Return configured mutator ready for population application</li> | |
155 | * </ol> | |
156 | * | |
157 | * @param eaExecutionContext execution context containing NEAT-specific components | |
158 | * @param eaConfiguration evolutionary algorithm configuration | |
159 | * @param mutationPolicyHandlerResolver resolver for chromosome mutation handlers | |
160 | * @param mutationPolicy the connection weight mutation policy | |
161 | * @return a configured mutator for applying weight mutations | |
162 | * @throws IllegalArgumentException if any parameter is null | |
163 | */ | |
164 | @Override | |
165 | public Mutator createMutator(final AbstractEAExecutionContext<T> eaExecutionContext, | |
166 | final AbstractEAConfiguration<T> eaConfiguration, | |
167 | final MutationPolicyHandlerResolver<T> mutationPolicyHandlerResolver, MutationPolicy mutationPolicy) { | |
168 | Validate.notNull(eaExecutionContext); | |
169 | Validate.notNull(eaConfiguration); | |
170 | Validate.notNull(mutationPolicy); | |
171 | Validate.notNull(mutationPolicyHandlerResolver); | |
172 | ||
173 | final NeatConnectionWeight neatConnectionWeightMutationPolicy = (NeatConnectionWeight) mutationPolicy; | |
174 |
1
1. createMutator : removed call to net/bmahe/genetics4j/neat/spec/mutation/NeatConnectionWeight::populationMutationProbability → SURVIVED |
final double populationMutationProbability = neatConnectionWeightMutationPolicy.populationMutationProbability(); |
175 | ||
176 | final ChromosomeMutationHandler<? extends Chromosome>[] chromosomeMutationHandlers = ChromosomeResolverUtils | |
177 |
1
1. createMutator : removed call to net/bmahe/genetics4j/core/util/ChromosomeResolverUtils::resolveChromosomeMutationHandlers → KILLED |
.resolveChromosomeMutationHandlers(eaExecutionContext, eaConfiguration, mutationPolicy); |
178 | ||
179 |
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/NeatConnectionWeightPolicyHandler::createMutator → KILLED |
return new GenericMutatorImpl(randomGenerator, |
180 | chromosomeMutationHandlers, | |
181 | mutationPolicy, | |
182 | populationMutationProbability); | |
183 | } | |
184 | } | |
Mutations | ||
119 |
1.1 |
|
139 |
1.1 2.2 |
|
174 |
1.1 |
|
177 |
1.1 |
|
179 |
1.1 2.2 |