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, | |
14 | * including inheritance biases, gene re-enabling policies, and parent comparison strategies. This policy | |
15 | * controls the fundamental 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 | * <pre>{@code | |
44 | * // Default NEAT crossover configuration | |
45 | * NeatCombination defaultPolicy = NeatCombination.build(); | |
46 | * | |
47 | * // Custom crossover with fitness bias | |
48 | * NeatCombination biasedPolicy = NeatCombination.builder() | |
49 | * .inheritanceThresold(0.7) // 70% bias toward fitter parent | |
50 | * .reenableGeneInheritanceThresold(0.3) // 30% chance to re-enable genes | |
51 | * .parentComparisonPolicy(FitnessComparison.build()) | |
52 | * .build(); | |
53 | * | |
54 | * // Unbiased crossover for diversity | |
55 | * NeatCombination unbiasedPolicy = NeatCombination.builder() | |
56 | * .inheritanceThresold(0.5) // No bias toward either parent | |
57 | * .reenableGeneInheritanceThresold(0.1) // Low re-enabling rate | |
58 | * .build(); | |
59 | * | |
60 | * // Use in EA configuration | |
61 | * var combinationSpec = ChromosomeCombinatorSpec.builder() | |
62 | * .combinationPolicy(biasedPolicy) | |
63 | * .build(); | |
64 | * }</pre> | |
65 | * | |
66 | * <p>Inheritance threshold effects: | |
67 | * <ul> | |
68 | * <li><strong>0.5 (default)</strong>: Unbiased inheritance, equal probability from both parents</li> | |
69 | * <li><strong>> 0.5</strong>: Bias toward fitter parent, promotes convergence</li> | |
70 | * <li><strong>< 0.5</strong>: Bias toward less fit parent, increases diversity</li> | |
71 | * <li><strong>1.0</strong>: Always inherit from fitter parent (if determinable)</li> | |
72 | * </ul> | |
73 | * | |
74 | * <p>Gene re-enabling mechanism: | |
75 | * <ul> | |
76 | * <li><strong>Historical information</strong>: Disabled genes preserve connection topology</li> | |
77 | * <li><strong>Re-activation chance</strong>: Allows previously disabled connections to contribute again</li> | |
78 | * <li><strong>Topology exploration</strong>: Enables rediscovery of useful connection patterns</li> | |
79 | * <li><strong>Genetic diversity</strong>: Prevents permanent loss of structural information</li> | |
80 | * </ul> | |
81 | * | |
82 | * <p>Parent comparison integration: | |
83 | * <ul> | |
84 | * <li><strong>Fitness comparison</strong>: Standard fitness-based parent ranking</li> | |
85 | * <li><strong>Custom strategies</strong>: Pluggable comparison policies for different problem domains</li> | |
86 | * <li><strong>Multi-objective support</strong>: Compatible with complex fitness landscapes</li> | |
87 | * <li><strong>Equal fitness handling</strong>: Special rules when parents have identical fitness</li> | |
88 | * </ul> | |
89 | * | |
90 | * <p>Performance considerations: | |
91 | * <ul> | |
92 | * <li><strong>Innovation sorting</strong>: Leverages pre-sorted connection lists for O(n) crossover</li> | |
93 | * <li><strong>Memory efficiency</strong>: Minimal allocation during gene inheritance</li> | |
94 | * <li><strong>Cache-friendly</strong>: Sequential access patterns for better cache performance</li> | |
95 | * <li><strong>Parallelizable</strong>: Crossover operations can be executed concurrently</li> | |
96 | * </ul> | |
97 | * | |
98 | * @see ParentComparisonPolicy | |
99 | * @see FitnessComparison | |
100 | * @see net.bmahe.genetics4j.neat.combination.NeatChromosomeCombinator | |
101 | * @see CombinationPolicy | |
102 | */ | |
103 | @Value.Immutable | |
104 | public interface NeatCombination extends CombinationPolicy { | |
105 | ||
106 | public static final double DEFAULT_INHERITANCE_THRESHOLD = 0.5d; | |
107 | ||
108 | public static final double DEFAULT_REENABLE_GENE_INHERITANCE_THRESHOLD = 0.25d; | |
109 | ||
110 | /** | |
111 | * Returns the inheritance threshold for biasing gene selection toward fitter parents. | |
112 | * | |
113 | * <p>This threshold controls the probability of inheriting genes from the fitter parent | |
114 | * during crossover. Higher values bias inheritance toward the better performing parent, | |
115 | * while lower values provide more equal inheritance or even bias toward the less fit parent. | |
116 | * | |
117 | * <p>Inheritance behavior: | |
118 | * <ul> | |
119 | * <li><strong>0.5 (default)</strong>: Unbiased inheritance, equal probability from both parents</li> | |
120 | * <li><strong>> 0.5</strong>: Bias toward fitter parent, promotes convergence to good solutions</li> | |
121 | * <li><strong>< 0.5</strong>: Bias toward less fit parent, increases population diversity</li> | |
122 | * <li><strong>1.0</strong>: Always inherit from fitter parent when fitness differs</li> | |
123 | * <li><strong>0.0</strong>: Always inherit from less fit parent when fitness differs</li> | |
124 | * </ul> | |
125 | * | |
126 | * @return inheritance threshold value between 0.0 and 1.0 (inclusive) | |
127 | */ | |
128 | @Value.Default | |
129 | default public double inheritanceThresold() { | |
130 |
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; |
131 | } | |
132 | ||
133 | /** | |
134 | * Returns the threshold for re-enabling disabled genes during crossover. | |
135 | * | |
136 | * <p>When a gene (connection) is disabled in one parent but enabled in the other, | |
137 | * this threshold determines the probability that the gene will be enabled in the | |
138 | * offspring. This mechanism prevents permanent loss of potentially useful connections | |
139 | * 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" | |
161 | * for the purposes of biased gene inheritance. This affects how disjoint and excess | |
162 | * genes are inherited and how the inheritance threshold is 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 | ||
130 |
1.1 2.2 |
|
154 |
1.1 2.2 |
|
176 |
1.1 2.2 |
|
189 |
1.1 2.2 |
|
205 |
1.1 2.2 3.3 |