NeatChromosomeSpec.java

1
package net.bmahe.genetics4j.neat.spec;
2
3
import org.apache.commons.lang3.Validate;
4
import org.immutables.value.Value;
5
6
import net.bmahe.genetics4j.core.spec.chromosome.ChromosomeSpec;
7
8
/**
9
 * Specification for NEAT (NeuroEvolution of Augmenting Topologies) neural network chromosomes.
10
 * 
11
 * <p>NeatChromosomeSpec defines the structural parameters and constraints for creating NEAT neural network
12
 * chromosomes. This specification is used by chromosome factories to generate initial network topologies
13
 * and by genetic operators to understand network boundaries and weight constraints.
14
 * 
15
 * <p>Key parameters:
16
 * <ul>
17
 * <li><strong>Network topology</strong>: Defines the number of input and output nodes</li>
18
 * <li><strong>Weight constraints</strong>: Specifies minimum and maximum connection weight values</li>
19
 * <li><strong>Network structure</strong>: Establishes the foundation for topology evolution</li>
20
 * <li><strong>Genetic boundaries</strong>: Provides constraints for mutation and crossover operations</li>
21
 * </ul>
22
 * 
23
 * <p>NEAT network architecture:
24
 * <ul>
25
 * <li><strong>Input layer</strong>: Fixed number of input nodes (indices 0 to numInputs-1)</li>
26
 * <li><strong>Output layer</strong>: Fixed number of output nodes (indices numInputs to numInputs+numOutputs-1)</li>
27
 * <li><strong>Hidden layers</strong>: Variable number of hidden nodes added through evolution</li>
28
 * <li><strong>Connections</strong>: Weighted links between nodes with enable/disable states</li>
29
 * </ul>
30
 * 
31
 * <p>Common usage patterns:
32
 * <pre>{@code
33
 * // Simple XOR problem specification
34
 * NeatChromosomeSpec xorSpec = NeatChromosomeSpec.of(
35
 *     2,      // 2 inputs (A, B)
36
 *     1,      // 1 output (A XOR B)
37
 *     -1.0f,  // minimum weight
38
 *     1.0f    // maximum weight
39
 * );
40
 * 
41
 * // Complex classification problem
42
 * NeatChromosomeSpec classificationSpec = NeatChromosomeSpec.of(
43
 *     784,    // 28x28 pixel inputs
44
 *     10,     // 10 class outputs
45
 *     -2.0f,  // wider weight range
46
 *     2.0f
47
 * );
48
 * 
49
 * // Builder pattern for complex construction
50
 * NeatChromosomeSpec spec = new NeatChromosomeSpec.Builder()
51
 *     .numInputs(5)
52
 *     .numOutputs(3)
53
 *     .minWeightValue(-1.5f)
54
 *     .maxWeightValue(1.5f)
55
 *     .build();
56
 * }</pre>
57
 * 
58
 * <p>Integration with NEAT ecosystem:
59
 * <ul>
60
 * <li><strong>Chromosome factories</strong>: Used by NeatConnectedChromosomeFactory for initial network generation</li>
61
 * <li><strong>Genetic operators</strong>: Provides constraints for weight mutations and structural changes</li>
62
 * <li><strong>Network evaluation</strong>: Defines input/output interfaces for fitness computation</li>
63
 * <li><strong>Evolution configuration</strong>: Establishes network parameters for entire evolutionary run</li>
64
 * </ul>
65
 * 
66
 * <p>Weight constraint management:
67
 * <ul>
68
 * <li><strong>Mutation boundaries</strong>: Weight mutations respect min/max bounds</li>
69
 * <li><strong>Initial generation</strong>: New connections use weights within specified range</li>
70
 * <li><strong>Crossover inheritance</strong>: Parent weights may be clipped to child bounds</li>
71
 * <li><strong>Network stability</strong>: Bounded weights help prevent gradient explosion/vanishing</li>
72
 * </ul>
73
 * 
74
 * <p>Validation and constraints:
75
 * <ul>
76
 * <li><strong>Positive node counts</strong>: Both input and output counts must be greater than zero</li>
77
 * <li><strong>Weight ordering</strong>: Minimum weight value should be less than maximum (not enforced)</li>
78
 * <li><strong>Reasonable bounds</strong>: Weight ranges should be appropriate for the problem domain</li>
79
 * <li><strong>Network capacity</strong>: Input/output counts should match problem requirements</li>
80
 * </ul>
81
 * 
82
 * <p>Problem domain considerations:
83
 * <ul>
84
 * <li><strong>Classification</strong>: Output count should match number of classes</li>
85
 * <li><strong>Regression</strong>: Single or multiple outputs for continuous value prediction</li>
86
 * <li><strong>Control problems</strong>: Outputs correspond to control signals or actions</li>
87
 * <li><strong>Feature extraction</strong>: Input count should match feature dimensionality</li>
88
 * </ul>
89
 * 
90
 * @see net.bmahe.genetics4j.neat.chromosomes.NeatChromosome
91
 * @see net.bmahe.genetics4j.neat.chromosomes.factory.NeatConnectedChromosomeFactory
92
 * @see net.bmahe.genetics4j.core.spec.EAConfiguration
93
 * @see ChromosomeSpec
94
 */
95
@Value.Immutable
96
public abstract class NeatChromosomeSpec implements ChromosomeSpec {
97
98
	/**
99
	 * Returns the number of input nodes for the neural network.
100
	 * 
101
	 * <p>Input nodes receive external data and form the first layer of the network.
102
	 * They are assigned indices 0 through numInputs-1 and do not apply activation
103
	 * functions to their values.
104
	 * 
105
	 * @return the number of input nodes (must be positive)
106
	 */
107
	@Value.Parameter
108
	public abstract int numInputs();
109
110
	/**
111
	 * Returns the number of output nodes for the neural network.
112
	 * 
113
	 * <p>Output nodes produce the final results of network computation and form the
114
	 * last layer of the network. They are assigned indices numInputs through
115
	 * numInputs+numOutputs-1 and apply activation functions to their weighted sums.
116
	 * 
117
	 * @return the number of output nodes (must be positive)
118
	 */
119
	@Value.Parameter
120
	public abstract int numOutputs();
121
122
	/**
123
	 * Returns the minimum allowed connection weight value.
124
	 * 
125
	 * <p>This constraint is used by genetic operators to bound weight mutations
126
	 * and ensure network stability. New connections and weight perturbations
127
	 * should respect this lower bound.
128
	 * 
129
	 * @return the minimum connection weight value
130
	 */
131
	@Value.Parameter
132
	public abstract float minWeightValue();
133
134
	/**
135
	 * Returns the maximum allowed connection weight value.
136
	 * 
137
	 * <p>This constraint is used by genetic operators to bound weight mutations
138
	 * and ensure network stability. New connections and weight perturbations
139
	 * should respect this upper bound.
140
	 * 
141
	 * @return the maximum connection weight value
142
	 */
143
	@Value.Parameter
144
	public abstract float maxWeightValue();
145
146
	@Value.Check
147
	protected void check() {
148
		Validate.isTrue(numInputs() > 0);
149
		Validate.isTrue(numOutputs() > 0);
150
	}
151
152
	public static class Builder extends ImmutableNeatChromosomeSpec.Builder {
153
	}
154
155
	/**
156
	 * Creates a new NEAT chromosome specification with the given parameters.
157
	 * 
158
	 * <p>This is a convenience factory method for creating chromosome specifications
159
	 * with all required parameters. The specification will be validated to ensure
160
	 * positive input and output counts.
161
	 * 
162
	 * @param numInputs number of input nodes (must be positive)
163
	 * @param numOutputs number of output nodes (must be positive)
164
	 * @param minWeightValue minimum allowed connection weight
165
	 * @param maxWeightValue maximum allowed connection weight
166
	 * @return a new chromosome specification with the specified parameters
167
	 * @throws IllegalArgumentException if numInputs &lt;= 0 or numOutputs &lt;= 0
168
	 */
169
	public static NeatChromosomeSpec of(final int numInputs, final int numOutputs, final float minWeightValue,
170
			final float maxWeightValue) {
171 4 1. of : replaced return value with null for net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec::of → KILLED
2. of : replaced call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::numInputs with receiver → KILLED
3. of : removed call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::<init> → KILLED
4. of : removed call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::numInputs → KILLED
		return new Builder().numInputs(numInputs)
172 2 1. of : removed call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::numOutputs → KILLED
2. of : replaced call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::numOutputs with receiver → KILLED
				.numOutputs(numOutputs)
173 2 1. of : removed call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::minWeightValue → KILLED
2. of : replaced call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::minWeightValue with receiver → KILLED
				.minWeightValue(minWeightValue)
174 2 1. of : replaced call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::maxWeightValue with receiver → KILLED
2. of : removed call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::maxWeightValue → KILLED
				.maxWeightValue(maxWeightValue)
175 1 1. of : removed call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::build → KILLED
				.build();
176
	}
177
}

Mutations

171

1.1
Location : of
Killed by : net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest]/[method:canHandle()]
replaced return value with null for net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec::of → KILLED

2.2
Location : of
Killed by : net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest]/[method:canHandle()]
replaced call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::numInputs with receiver → KILLED

3.3
Location : of
Killed by : net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest]/[method:canHandle()]
removed call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::<init> → KILLED

4.4
Location : of
Killed by : net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest]/[method:canHandle()]
removed call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::numInputs → KILLED

172

1.1
Location : of
Killed by : net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest]/[method:canHandle()]
removed call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::numOutputs → KILLED

2.2
Location : of
Killed by : net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest]/[method:canHandle()]
replaced call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::numOutputs with receiver → KILLED

173

1.1
Location : of
Killed by : net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest]/[method:canHandle()]
removed call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::minWeightValue → KILLED

2.2
Location : of
Killed by : net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest]/[method:canHandle()]
replaced call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::minWeightValue with receiver → KILLED

174

1.1
Location : of
Killed by : net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest]/[method:canHandle()]
replaced call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::maxWeightValue with receiver → KILLED

2.2
Location : of
Killed by : net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest]/[method:canHandle()]
removed call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::maxWeightValue → KILLED

175

1.1
Location : of
Killed by : net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.chromosomes.factory.NeatEmptyChromosomeFactoryTest]/[method:canHandle()]
removed call to net/bmahe/genetics4j/neat/spec/NeatChromosomeSpec$Builder::build → KILLED

Active mutators

Tests examined


Report generated by PIT 1.19.6