| 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>> 0.5</strong>: Bias toward fitter parent, promotes convergence</li> | |
| 71 | * <li><strong>< 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>> 0.5</strong>: Bias toward fitter parent, promotes convergence to good solutions</li> | |
| 122 | * <li><strong>< 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 2.2 |
|
| 154 |
1.1 2.2 |
|
| 176 |
1.1 2.2 |
|
| 189 |
1.1 2.2 |
|
| 205 |
1.1 2.2 3.3 |