| 1 | package net.bmahe.genetics4j.neat.selection; | |
| 2 | ||
| 3 | import java.util.random.RandomGenerator; | |
| 4 | ||
| 5 | import org.apache.commons.lang3.Validate; | |
| 6 | import org.apache.logging.log4j.LogManager; | |
| 7 | import org.apache.logging.log4j.Logger; | |
| 8 | ||
| 9 | import net.bmahe.genetics4j.core.selection.SelectionPolicyHandler; | |
| 10 | import net.bmahe.genetics4j.core.selection.SelectionPolicyHandlerResolver; | |
| 11 | import net.bmahe.genetics4j.core.selection.Selector; | |
| 12 | import net.bmahe.genetics4j.core.spec.AbstractEAConfiguration; | |
| 13 | import net.bmahe.genetics4j.core.spec.AbstractEAExecutionContext; | |
| 14 | import net.bmahe.genetics4j.core.spec.selection.SelectionPolicy; | |
| 15 | import net.bmahe.genetics4j.neat.SpeciesIdGenerator; | |
| 16 | import net.bmahe.genetics4j.neat.spec.selection.NeatSelection; | |
| 17 | ||
| 18 | /** | |
| 19 | * Selection policy handler for NEAT (NeuroEvolution of Augmenting Topologies) species-based selection. | |
| 20 | * | |
| 21 | * <p>NeatSelectionPolicyHandler implements the species-based selection mechanism that is fundamental to the NEAT | |
| 22 | * algorithm. It organizes the population into species based on genetic compatibility, applies fitness sharing within | |
| 23 | * species, and manages reproduction allocation across species to maintain population diversity and protect innovative | |
| 24 | * topologies. | |
| 25 | * | |
| 26 | * <p>Key responsibilities: | |
| 27 | * <ul> | |
| 28 | * <li><strong>Species formation</strong>: Groups genetically similar individuals into species</li> | |
| 29 | * <li><strong>Fitness sharing</strong>: Adjusts individual fitness based on species membership</li> | |
| 30 | * <li><strong>Reproduction allocation</strong>: Distributes offspring across species based on average fitness</li> | |
| 31 | * <li><strong>Diversity preservation</strong>: Protects innovative topologies from elimination by established | |
| 32 | * forms</li> | |
| 33 | * </ul> | |
| 34 | * | |
| 35 | * <p>NEAT species-based selection process: | |
| 36 | * <ol> | |
| 37 | * <li><strong>Compatibility calculation</strong>: Measure genetic distance between individuals</li> | |
| 38 | * <li><strong>Species assignment</strong>: Assign individuals to species based on compatibility thresholds</li> | |
| 39 | * <li><strong>Fitness adjustment</strong>: Apply fitness sharing within each species</li> | |
| 40 | * <li><strong>Species evaluation</strong>: Calculate average fitness for each species</li> | |
| 41 | * <li><strong>Reproduction allocation</strong>: Determine offspring count for each species</li> | |
| 42 | * <li><strong>Within-species selection</strong>: Select parents within each species for reproduction</li> | |
| 43 | * </ol> | |
| 44 | * | |
| 45 | * <p>Species management features: | |
| 46 | * <ul> | |
| 47 | * <li><strong>Dynamic speciation</strong>: Species boundaries adjust as population evolves</li> | |
| 48 | * <li><strong>Species extinction</strong>: Poor-performing species are eliminated</li> | |
| 49 | * <li><strong>Representative tracking</strong>: Maintains species representatives for compatibility testing</li> | |
| 50 | * <li><strong>Population diversity</strong>: Prevents single topology from dominating</li> | |
| 51 | * </ul> | |
| 52 | * | |
| 53 | * <p>Common usage patterns: | |
| 54 | * | |
| 55 | * <pre>{@code | |
| 56 | * // Create NEAT selection policy handler | |
| 57 | * RandomGenerator randomGen = RandomGenerator.getDefault(); | |
| 58 | * SpeciesIdGenerator speciesIdGen = new SpeciesIdGenerator(); | |
| 59 | * | |
| 60 | * NeatSelectionPolicyHandler<Double> handler = new NeatSelectionPolicyHandler<>(randomGen, speciesIdGen); | |
| 61 | * | |
| 62 | * // Configure NEAT selection policy | |
| 63 | * NeatSelection<Double> neatSelection = NeatSelection.<Double>builder() | |
| 64 | * .compatibilityThreshold(3.0) | |
| 65 | * .speciesSelection(new TournamentSelection(3)) // Within-species selection | |
| 66 | * .build(); | |
| 67 | * | |
| 68 | * // Resolve selector for EA execution | |
| 69 | * Selector<Double> selector = handler.resolve(executionContext, configuration, resolverRegistry, neatSelection); | |
| 70 | * }</pre> | |
| 71 | * | |
| 72 | * <p>Integration with genetic operators: | |
| 73 | * <ul> | |
| 74 | * <li><strong>Crossover compatibility</strong>: Species ensure genetic compatibility for meaningful recombination</li> | |
| 75 | * <li><strong>Mutation guidance</strong>: Species composition influences structural mutation rates</li> | |
| 76 | * <li><strong>Innovation protection</strong>: New topologies get time to optimize within their species</li> | |
| 77 | * <li><strong>Diversity maintenance</strong>: Multiple species explore different regions of topology space</li> | |
| 78 | * </ul> | |
| 79 | * | |
| 80 | * <p>Performance considerations: | |
| 81 | * <ul> | |
| 82 | * <li><strong>Compatibility caching</strong>: Genetic distances cached for efficiency</li> | |
| 83 | * <li><strong>Species reuse</strong>: Species structures maintained across generations</li> | |
| 84 | * <li><strong>Parallel processing</strong>: Species-based selection enables concurrent evaluation</li> | |
| 85 | * <li><strong>Memory management</strong>: Efficient species membership tracking</li> | |
| 86 | * </ul> | |
| 87 | * | |
| 88 | * <p>Selection policy delegation: | |
| 89 | * <ul> | |
| 90 | * <li><strong>Within-species selection</strong>: Delegates to standard selection policies (tournament, roulette, | |
| 91 | * etc.)</li> | |
| 92 | * <li><strong>Composable policies</strong>: Can combine with any standard selection mechanism</li> | |
| 93 | * <li><strong>Flexible configuration</strong>: Different species can use different selection strategies</li> | |
| 94 | * <li><strong>Performance optimization</strong>: Leverages existing high-performance selectors</li> | |
| 95 | * </ul> | |
| 96 | * | |
| 97 | * @param <T> the fitness value type (typically Double) | |
| 98 | * @see NeatSelection | |
| 99 | * @see NeatSelectorImpl | |
| 100 | * @see Species | |
| 101 | * @see SpeciesIdGenerator | |
| 102 | * @see SelectionPolicyHandler | |
| 103 | */ | |
| 104 | public class NeatSelectionPolicyHandler<T extends Number & Comparable<T>> implements SelectionPolicyHandler<T> { | |
| 105 | public static final Logger logger = LogManager.getLogger(NeatSelectionPolicyHandler.class); | |
| 106 | ||
| 107 | private final RandomGenerator randomGenerator; | |
| 108 | private final SpeciesIdGenerator speciesIdGenerator; | |
| 109 | ||
| 110 | /** | |
| 111 | * Constructs a new NEAT selection policy handler with the specified components. | |
| 112 | * | |
| 113 | * <p>The random generator is used for stochastic operations during species formation and selection. The species ID | |
| 114 | * generator provides unique identifiers for newly created species throughout the evolutionary process. | |
| 115 | * | |
| 116 | * @param _randomGenerator random number generator for stochastic operations | |
| 117 | * @param _speciesIdGenerator generator for unique species identifiers | |
| 118 | * @throws IllegalArgumentException if randomGenerator or speciesIdGenerator is null | |
| 119 | */ | |
| 120 | public NeatSelectionPolicyHandler(final RandomGenerator _randomGenerator, | |
| 121 | final SpeciesIdGenerator _speciesIdGenerator) { | |
| 122 | Validate.notNull(_randomGenerator); | |
| 123 | Validate.notNull(_speciesIdGenerator); | |
| 124 | ||
| 125 |
1
1. <init> : Removed assignment to member variable randomGenerator → KILLED |
this.randomGenerator = _randomGenerator; |
| 126 |
1
1. <init> : Removed assignment to member variable speciesIdGenerator → KILLED |
this.speciesIdGenerator = _speciesIdGenerator; |
| 127 | } | |
| 128 | ||
| 129 | /** | |
| 130 | * Determines whether this handler can process the given selection policy. | |
| 131 | * | |
| 132 | * <p>This handler specifically processes NeatSelection policies, which configure species-based selection with | |
| 133 | * compatibility thresholds and within-species selection strategies. | |
| 134 | * | |
| 135 | * @param selectionPolicy the selection policy to check | |
| 136 | * @return true if the policy is a NeatSelection instance, false otherwise | |
| 137 | * @throws IllegalArgumentException if selectionPolicy is null | |
| 138 | */ | |
| 139 | @Override | |
| 140 | public boolean canHandle(final SelectionPolicy selectionPolicy) { | |
| 141 | Validate.notNull(selectionPolicy); | |
| 142 | ||
| 143 |
2
1. canHandle : replaced boolean return with true for net/bmahe/genetics4j/neat/selection/NeatSelectionPolicyHandler::canHandle → KILLED 2. canHandle : replaced boolean return with false for net/bmahe/genetics4j/neat/selection/NeatSelectionPolicyHandler::canHandle → KILLED |
return selectionPolicy instanceof NeatSelection; |
| 144 | } | |
| 145 | ||
| 146 | /** | |
| 147 | * Resolves a NEAT selection policy into a concrete selector implementation. | |
| 148 | * | |
| 149 | * <p>This method creates a NeatSelectorImpl that implements the species-based selection mechanism. It resolves the | |
| 150 | * within-species selection policy using the provided resolver and configures the selector with the necessary NEAT | |
| 151 | * components. | |
| 152 | * | |
| 153 | * <p>Resolution process: | |
| 154 | * <ol> | |
| 155 | * <li>Extract the within-species selection policy from the NEAT selection configuration</li> | |
| 156 | * <li>Resolve the within-species selection policy to a concrete selector</li> | |
| 157 | * <li>Create a NeatSelectorImpl with all necessary components</li> | |
| 158 | * <li>Return the configured selector ready for use in evolution</li> | |
| 159 | * </ol> | |
| 160 | * | |
| 161 | * @param eaExecutionContext the execution context for the evolutionary algorithm | |
| 162 | * @param eaConfiguration the configuration for the evolutionary algorithm | |
| 163 | * @param selectionPolicyHandlerResolver resolver for nested selection policies | |
| 164 | * @param selectionPolicy the NEAT selection policy to resolve | |
| 165 | * @return a configured selector implementing NEAT species-based selection | |
| 166 | * @throws IllegalArgumentException if selectionPolicy is null or not a NeatSelection | |
| 167 | */ | |
| 168 | @Override | |
| 169 | public Selector<T> resolve(final AbstractEAExecutionContext<T> eaExecutionContext, | |
| 170 | final AbstractEAConfiguration<T> eaConfiguration, | |
| 171 | final SelectionPolicyHandlerResolver<T> selectionPolicyHandlerResolver, | |
| 172 | final SelectionPolicy selectionPolicy) { | |
| 173 | Validate.notNull(selectionPolicy); | |
| 174 | Validate.isInstanceOf(NeatSelection.class, selectionPolicy); | |
| 175 | ||
| 176 | final NeatSelection<T> neatSelection = (NeatSelection<T>) selectionPolicy; | |
| 177 | ||
| 178 |
1
1. resolve : removed call to net/bmahe/genetics4j/neat/spec/selection/NeatSelection::speciesSelection → SURVIVED |
final SelectionPolicy speciesSelection = neatSelection.speciesSelection(); |
| 179 | final SelectionPolicyHandler<T> speciesSelectionPolicyHandler = selectionPolicyHandlerResolver | |
| 180 |
1
1. resolve : removed call to net/bmahe/genetics4j/core/selection/SelectionPolicyHandlerResolver::resolve → KILLED |
.resolve(speciesSelection); |
| 181 | final Selector<T> speciesSelector = speciesSelectionPolicyHandler | |
| 182 |
1
1. resolve : removed call to net/bmahe/genetics4j/core/selection/SelectionPolicyHandler::resolve → KILLED |
.resolve(eaExecutionContext, eaConfiguration, selectionPolicyHandlerResolver, speciesSelection); |
| 183 | ||
| 184 |
2
1. resolve : replaced return value with null for net/bmahe/genetics4j/neat/selection/NeatSelectionPolicyHandler::resolve → KILLED 2. resolve : removed call to net/bmahe/genetics4j/neat/selection/NeatSelectorImpl::<init> → KILLED |
return new NeatSelectorImpl<>(randomGenerator, neatSelection, speciesIdGenerator, speciesSelector); |
| 185 | } | |
| 186 | } | |
Mutations | ||
| 125 |
1.1 |
|
| 126 |
1.1 |
|
| 143 |
1.1 2.2 |
|
| 178 |
1.1 |
|
| 180 |
1.1 |
|
| 182 |
1.1 |
|
| 184 |
1.1 2.2 |