NeatCombination.java

1
package net.bmahe.genetics4j.neat.spec.combination;
2
3
import org.apache.commons.lang3.Validate;
4
import org.immutables.value.Value;
5
6
import net.bmahe.genetics4j.core.spec.combination.CombinationPolicy;
7
import net.bmahe.genetics4j.neat.spec.combination.parentcompare.ParentComparisonPolicy;
8
import net.bmahe.genetics4j.neat.spec.combination.parentcompare.FitnessComparison;
9
10
/**
11
 * Configuration policy for NEAT (NeuroEvolution of Augmenting Topologies) genetic crossover operations.
12
 * 
13
 * <p>NeatCombination defines how neural network chromosomes should be recombined during genetic crossover, including
14
 * inheritance biases, gene re-enabling policies, and parent comparison strategies. This policy controls the fundamental
15
 * genetic operators that shape network topology evolution in NEAT.
16
 * 
17
 * <p>Key crossover parameters:
18
 * <ul>
19
 * <li><strong>Inheritance threshold</strong>: Bias toward fitter parent for gene inheritance</li>
20
 * <li><strong>Gene re-enabling</strong>: Probability of re-enabling disabled genes during crossover</li>
21
 * <li><strong>Parent comparison</strong>: Strategy for determining relative parent fitness</li>
22
 * <li><strong>Genetic alignment</strong>: Innovation-number-based gene matching</li>
23
 * </ul>
24
 * 
25
 * <p>NEAT genetic crossover process:
26
 * <ol>
27
 * <li><strong>Gene alignment</strong>: Match genes by innovation number between parents</li>
28
 * <li><strong>Matching genes</strong>: Randomly inherit from either parent (biased by inheritance threshold)</li>
29
 * <li><strong>Disjoint genes</strong>: Inherit from fitter parent based on parent comparison</li>
30
 * <li><strong>Excess genes</strong>: Inherit from fitter parent beyond less fit parent's range</li>
31
 * <li><strong>Gene state</strong>: Apply re-enabling policy to disabled genes</li>
32
 * </ol>
33
 * 
34
 * <p>Gene inheritance strategies:
35
 * <ul>
36
 * <li><strong>Matching genes</strong>: Present in both parents with same innovation number</li>
37
 * <li><strong>Disjoint genes</strong>: Present in one parent within other parent's innovation range</li>
38
 * <li><strong>Excess genes</strong>: Present in one parent beyond other parent's highest innovation</li>
39
 * <li><strong>Disabled genes</strong>: May be re-enabled based on re-enabling threshold</li>
40
 * </ul>
41
 * 
42
 * <p>Common usage patterns:
43
 * 
44
 * <pre>{@code
45
 * // Default NEAT crossover configuration
46
 * NeatCombination defaultPolicy = NeatCombination.build();
47
 * 
48
 * // Custom crossover with fitness bias
49
 * NeatCombination biasedPolicy = NeatCombination.builder()
50
 * 		.inheritanceThresold(0.7) // 70% bias toward fitter parent
51
 * 		.reenableGeneInheritanceThresold(0.3) // 30% chance to re-enable genes
52
 * 		.parentComparisonPolicy(FitnessComparison.build())
53
 * 		.build();
54
 * 
55
 * // Unbiased crossover for diversity
56
 * NeatCombination unbiasedPolicy = NeatCombination.builder()
57
 * 		.inheritanceThresold(0.5) // No bias toward either parent
58
 * 		.reenableGeneInheritanceThresold(0.1) // Low re-enabling rate
59
 * 		.build();
60
 * 
61
 * // Use in EA configuration
62
 * var combinationSpec = ChromosomeCombinatorSpec.builder()
63
 * 		.combinationPolicy(biasedPolicy)
64
 * 		.build();
65
 * }</pre>
66
 * 
67
 * <p>Inheritance threshold effects:
68
 * <ul>
69
 * <li><strong>0.5 (default)</strong>: Unbiased inheritance, equal probability from both parents</li>
70
 * <li><strong>&gt; 0.5</strong>: Bias toward fitter parent, promotes convergence</li>
71
 * <li><strong>&lt; 0.5</strong>: Bias toward less fit parent, increases diversity</li>
72
 * <li><strong>1.0</strong>: Always inherit from fitter parent (if determinable)</li>
73
 * </ul>
74
 * 
75
 * <p>Gene re-enabling mechanism:
76
 * <ul>
77
 * <li><strong>Historical information</strong>: Disabled genes preserve connection topology</li>
78
 * <li><strong>Re-activation chance</strong>: Allows previously disabled connections to contribute again</li>
79
 * <li><strong>Topology exploration</strong>: Enables rediscovery of useful connection patterns</li>
80
 * <li><strong>Genetic diversity</strong>: Prevents permanent loss of structural information</li>
81
 * </ul>
82
 * 
83
 * <p>Parent comparison integration:
84
 * <ul>
85
 * <li><strong>Fitness comparison</strong>: Standard fitness-based parent ranking</li>
86
 * <li><strong>Custom strategies</strong>: Pluggable comparison policies for different problem domains</li>
87
 * <li><strong>Multi-objective support</strong>: Compatible with complex fitness landscapes</li>
88
 * <li><strong>Equal fitness handling</strong>: Special rules when parents have identical fitness</li>
89
 * </ul>
90
 * 
91
 * <p>Performance considerations:
92
 * <ul>
93
 * <li><strong>Innovation sorting</strong>: Leverages pre-sorted connection lists for O(n) crossover</li>
94
 * <li><strong>Memory efficiency</strong>: Minimal allocation during gene inheritance</li>
95
 * <li><strong>Cache-friendly</strong>: Sequential access patterns for better cache performance</li>
96
 * <li><strong>Parallelizable</strong>: Crossover operations can be executed concurrently</li>
97
 * </ul>
98
 * 
99
 * @see ParentComparisonPolicy
100
 * @see FitnessComparison
101
 * @see net.bmahe.genetics4j.neat.combination.NeatChromosomeCombinator
102
 * @see CombinationPolicy
103
 */
104
@Value.Immutable
105
public interface NeatCombination extends CombinationPolicy {
106
107
	public static final double DEFAULT_INHERITANCE_THRESHOLD = 0.5d;
108
109
	public static final double DEFAULT_REENABLE_GENE_INHERITANCE_THRESHOLD = 0.25d;
110
111
	/**
112
	 * Returns the inheritance threshold for biasing gene selection toward fitter parents.
113
	 * 
114
	 * <p>This threshold controls the probability of inheriting genes from the fitter parent during crossover. Higher
115
	 * values bias inheritance toward the better performing parent, while lower values provide more equal inheritance or
116
	 * even bias toward the less fit parent.
117
	 * 
118
	 * <p>Inheritance behavior:
119
	 * <ul>
120
	 * <li><strong>0.5 (default)</strong>: Unbiased inheritance, equal probability from both parents</li>
121
	 * <li><strong>&gt; 0.5</strong>: Bias toward fitter parent, promotes convergence to good solutions</li>
122
	 * <li><strong>&lt; 0.5</strong>: Bias toward less fit parent, increases population diversity</li>
123
	 * <li><strong>1.0</strong>: Always inherit from fitter parent when fitness differs</li>
124
	 * <li><strong>0.0</strong>: Always inherit from less fit parent when fitness differs</li>
125
	 * </ul>
126
	 * 
127
	 * @return inheritance threshold value between 0.0 and 1.0 (inclusive)
128
	 */
129
	@Value.Default
130
	default public double inheritanceThresold() {
131 2 1. inheritanceThresold : replaced double return with 0.0d for net/bmahe/genetics4j/neat/spec/combination/NeatCombination::inheritanceThresold → SURVIVED
2. inheritanceThresold : Substituted 0.5 with 1.0 → SURVIVED
		return DEFAULT_INHERITANCE_THRESHOLD;
132
	}
133
134
	/**
135
	 * Returns the threshold for re-enabling disabled genes during crossover.
136
	 * 
137
	 * <p>When a gene (connection) is disabled in one parent but enabled in the other, this threshold determines the
138
	 * probability that the gene will be enabled in the offspring. This mechanism prevents permanent loss of potentially
139
	 * useful connections and allows rediscovery of structural innovations.
140
	 * 
141
	 * <p>Re-enabling behavior:
142
	 * <ul>
143
	 * <li><strong>0.25 (default)</strong>: 25% chance to re-enable disabled connections</li>
144
	 * <li><strong>0.0</strong>: Never re-enable disabled connections</li>
145
	 * <li><strong>1.0</strong>: Always re-enable connections that are enabled in either parent</li>
146
	 * <li><strong>Higher values</strong>: More aggressive topology exploration</li>
147
	 * <li><strong>Lower values</strong>: More conservative structural preservation</li>
148
	 * </ul>
149
	 * 
150
	 * @return re-enabling threshold value between 0.0 and 1.0 (inclusive)
151
	 */
152
	@Value.Default
153
	default public double reenableGeneInheritanceThresold() {
154 2 1. reenableGeneInheritanceThresold : replaced double return with 0.0d for net/bmahe/genetics4j/neat/spec/combination/NeatCombination::reenableGeneInheritanceThresold → SURVIVED
2. reenableGeneInheritanceThresold : Substituted 0.25 with 1.0 → SURVIVED
		return DEFAULT_REENABLE_GENE_INHERITANCE_THRESHOLD;
155
	}
156
157
	/**
158
	 * Returns the policy used to compare parent fitness for inheritance decisions.
159
	 * 
160
	 * <p>The parent comparison policy determines which parent is considered "fitter" for the purposes of biased gene
161
	 * inheritance. This affects how disjoint and excess genes are inherited and how the inheritance threshold is
162
	 * applied.
163
	 * 
164
	 * <p>Available comparison strategies:
165
	 * <ul>
166
	 * <li><strong>FitnessComparison (default)</strong>: Compare parents based on their fitness values</li>
167
	 * <li><strong>Custom policies</strong>: Pluggable strategies for domain-specific comparisons</li>
168
	 * <li><strong>Multi-objective</strong>: Specialized comparisons for multi-objective optimization</li>
169
	 * <li><strong>Equal fitness handling</strong>: Specific behavior when parents have identical fitness</li>
170
	 * </ul>
171
	 * 
172
	 * @return the parent comparison policy (defaults to fitness-based comparison)
173
	 */
174
	@Value.Default
175
	default public ParentComparisonPolicy parentComparisonPolicy() {
176 2 1. parentComparisonPolicy : replaced return value with null for net/bmahe/genetics4j/neat/spec/combination/NeatCombination::parentComparisonPolicy → KILLED
2. parentComparisonPolicy : removed call to net/bmahe/genetics4j/neat/spec/combination/parentcompare/FitnessComparison::build → KILLED
		return FitnessComparison.build();
177
	}
178
179
	@Value.Check
180
	default void check() {
181
		Validate.inclusiveBetween(0, 1, inheritanceThresold());
182
		Validate.inclusiveBetween(0, 1, reenableGeneInheritanceThresold());
183
	}
184
185
	class Builder extends ImmutableNeatCombination.Builder {
186
	}
187
188
	static Builder builder() {
189 2 1. builder : removed call to net/bmahe/genetics4j/neat/spec/combination/NeatCombination$Builder::<init> → KILLED
2. builder : replaced return value with null for net/bmahe/genetics4j/neat/spec/combination/NeatCombination::builder → KILLED
		return new Builder();
190
	}
191
192
	/**
193
	 * Creates a NEAT combination policy with default settings.
194
	 * 
195
	 * <p>Default configuration:
196
	 * <ul>
197
	 * <li>Inheritance threshold: 0.5 (unbiased)</li>
198
	 * <li>Gene re-enabling threshold: 0.25 (25% chance)</li>
199
	 * <li>Parent comparison: Fitness-based comparison</li>
200
	 * </ul>
201
	 * 
202
	 * @return a new NEAT combination policy with default settings
203
	 */
204
	static NeatCombination build() {
205 3 1. build : replaced return value with null for net/bmahe/genetics4j/neat/spec/combination/NeatCombination::build → KILLED
2. build : removed call to net/bmahe/genetics4j/neat/spec/combination/NeatCombination$Builder::build → KILLED
3. build : removed call to net/bmahe/genetics4j/neat/spec/combination/NeatCombination::builder → KILLED
		return builder().build();
206
	}
207
208
}

Mutations

131

1.1
Location : inheritanceThresold
Killed by : none
replaced double return with 0.0d for net/bmahe/genetics4j/neat/spec/combination/NeatCombination::inheritanceThresold → SURVIVED
Covering tests

2.2
Location : inheritanceThresold
Killed by : none
Substituted 0.5 with 1.0 → SURVIVED Covering tests

154

1.1
Location : reenableGeneInheritanceThresold
Killed by : none
replaced double return with 0.0d for net/bmahe/genetics4j/neat/spec/combination/NeatCombination::reenableGeneInheritanceThresold → SURVIVED
Covering tests

2.2
Location : reenableGeneInheritanceThresold
Killed by : none
Substituted 0.25 with 1.0 → SURVIVED Covering tests

176

1.1
Location : parentComparisonPolicy
Killed by : net.bmahe.genetics4j.neat.combination.NeatChromosomeCombinatorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatChromosomeCombinatorTest]/[method:shouldNeverReEnable()]
replaced return value with null for net/bmahe/genetics4j/neat/spec/combination/NeatCombination::parentComparisonPolicy → KILLED

2.2
Location : parentComparisonPolicy
Killed by : net.bmahe.genetics4j.neat.combination.NeatChromosomeCombinatorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatChromosomeCombinatorTest]/[method:shouldNeverReEnable()]
removed call to net/bmahe/genetics4j/neat/spec/combination/parentcompare/FitnessComparison::build → KILLED

189

1.1
Location : builder
Killed by : net.bmahe.genetics4j.neat.combination.NeatChromosomeCombinatorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatChromosomeCombinatorTest]/[method:shouldNeverReEnable()]
removed call to net/bmahe/genetics4j/neat/spec/combination/NeatCombination$Builder::<init> → KILLED

2.2
Location : builder
Killed by : net.bmahe.genetics4j.neat.combination.NeatChromosomeCombinatorTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.combination.NeatChromosomeCombinatorTest]/[method:shouldNeverReEnable()]
replaced return value with null for net/bmahe/genetics4j/neat/spec/combination/NeatCombination::builder → KILLED

205

1.1
Location : build
Killed by : net.bmahe.genetics4j.neat.selection.NeatSelectorImplTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.selection.NeatSelectorImplTest]/[method:simple()]
replaced return value with null for net/bmahe/genetics4j/neat/spec/combination/NeatCombination::build → KILLED

2.2
Location : build
Killed by : net.bmahe.genetics4j.neat.selection.NeatSelectorImplTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.selection.NeatSelectorImplTest]/[method:simple()]
removed call to net/bmahe/genetics4j/neat/spec/combination/NeatCombination$Builder::build → KILLED

3.3
Location : build
Killed by : net.bmahe.genetics4j.neat.selection.NeatSelectorImplTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.neat.selection.NeatSelectorImplTest]/[method:simple()]
removed call to net/bmahe/genetics4j/neat/spec/combination/NeatCombination::builder → KILLED

Active mutators

Tests examined


Report generated by PIT 1.20.3