NeatEAExecutionContexts.java
package net.bmahe.genetics4j.neat;
import java.util.random.RandomGenerator;
import org.apache.commons.lang3.Validate;
import net.bmahe.genetics4j.core.chromosomes.factory.ChromosomeFactoryProvider;
import net.bmahe.genetics4j.core.chromosomes.factory.ImmutableChromosomeFactoryProvider;
import net.bmahe.genetics4j.core.spec.EAExecutionContexts;
import net.bmahe.genetics4j.core.spec.ImmutableEAExecutionContext.Builder;
import net.bmahe.genetics4j.neat.chromosomes.factory.NeatConnectedChromosomeFactory;
import net.bmahe.genetics4j.neat.combination.NeatCombinationHandler;
import net.bmahe.genetics4j.neat.mutation.AddConnectionPolicyHandler;
import net.bmahe.genetics4j.neat.mutation.AddNodePolicyHandler;
import net.bmahe.genetics4j.neat.mutation.DeleteConnectionPolicyHandler;
import net.bmahe.genetics4j.neat.mutation.DeleteNodePolicyHandler;
import net.bmahe.genetics4j.neat.mutation.NeatConnectionWeightPolicyHandler;
import net.bmahe.genetics4j.neat.mutation.NeatSwitchStatePolicyHandler;
import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeAddConnection;
import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeAddNodeMutationHandler;
import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeConnectionWeightMutationHandler;
import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeCreepMutationHandler;
import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeDeleteConnection;
import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeDeleteNodeMutationHandler;
import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeRandomMutationHandler;
import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeSwitchStateHandler;
import net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandler;
/**
* Factory class for creating NEAT (NeuroEvolution of Augmenting Topologies) execution contexts.
*
* <p>NeatEAExecutionContexts provides convenient factory methods for setting up evolutionary algorithm
* execution contexts with all the necessary NEAT-specific components, including innovation management,
* species-based selection, structural mutations, and neural network-specific genetic operators.
* This class serves as the primary entry point for configuring NEAT evolutionary systems.
*
* <p>Key NEAT components integrated:
* <ul>
* <li><strong>Innovation management</strong>: Historical marking system for structural mutations</li>
* <li><strong>Species-based selection</strong>: Population organization by genetic similarity</li>
* <li><strong>Structural mutations</strong>: Add/delete nodes and connections with innovation tracking</li>
* <li><strong>Neural network crossover</strong>: Topology-aware genetic recombination</li>
* <li><strong>Chromosome factories</strong>: Initial network generation with proper connectivity</li>
* </ul>
*
* <p>NEAT algorithm configuration:
* <ul>
* <li><strong>Mutation operators</strong>: Weight perturbation, add/delete nodes, add/delete connections</li>
* <li><strong>Selection strategy</strong>: Species-based selection with fitness sharing</li>
* <li><strong>Crossover mechanism</strong>: Innovation-number-based gene alignment</li>
* <li><strong>Network initialization</strong>: Configurable initial topology generation</li>
* </ul>
*
* <p>Common usage patterns:
* <pre>{@code
* // Standard NEAT setup with default components
* EAExecutionContext<Double> context = NeatEAExecutionContexts.<Double>standard().build();
*
* // Custom NEAT setup with existing builder
* var builder = EAExecutionContexts.<Double>forScalarFitness()
* .randomGenerator(myRandomGenerator)
* .termination(myTerminationCondition);
* EAExecutionContext<Double> context = NeatEAExecutionContexts.enrichWithNeat(builder).build();
*
* // Advanced setup with custom innovation manager
* InnovationManager customInnovationManager = new InnovationManager(1000);
* SpeciesIdGenerator customSpeciesIdGenerator = new SpeciesIdGenerator();
* ChromosomeFactoryProvider customFactoryProvider = // ... create custom provider
*
* var context = NeatEAExecutionContexts.enrichWithNeat(
* builder, customInnovationManager, customSpeciesIdGenerator, customFactoryProvider
* ).build();
* }</pre>
*
* <p>Integrated NEAT genetic operators:
* <ul>
* <li><strong>Weight mutations</strong>: Gaussian perturbation, random replacement, creep mutation</li>
* <li><strong>Structural mutations</strong>: Add node, add connection, delete node, delete connection</li>
* <li><strong>State mutations</strong>: Enable/disable connections for network topology exploration</li>
* <li><strong>Crossover operations</strong>: Innovation-guided gene alignment and inheritance</li>
* </ul>
*
* <p>Species-based evolution:
* <ul>
* <li><strong>Compatibility distance</strong>: Genetic similarity measurement for speciation</li>
* <li><strong>Fitness sharing</strong>: Population diversity maintenance through species-based selection</li>
* <li><strong>Species management</strong>: Dynamic species formation and extinction</li>
* <li><strong>Representative selection</strong>: Species representative selection for next generation</li>
* </ul>
*
* <p>Performance and scalability:
* <ul>
* <li><strong>Efficient innovation tracking</strong>: O(1) innovation number lookup</li>
* <li><strong>Concurrent execution</strong>: Thread-safe components for parallel evolution</li>
* <li><strong>Memory management</strong>: Configurable cache management for large populations</li>
* <li><strong>Modular design</strong>: Customizable components for specific problem domains</li>
* </ul>
*
* @see InnovationManager
* @see SpeciesIdGenerator
* @see NeatChromosome
* @see net.bmahe.genetics4j.neat.spec.NeatChromosomeSpec
*/
public class NeatEAExecutionContexts {
private NeatEAExecutionContexts() {
}
/**
* Enriches an existing EA execution context builder with standard NEAT components.
*
* <p>This method configures the builder with default NEAT components including a new innovation
* manager, species ID generator, and connected chromosome factory. All NEAT-specific genetic
* operators, selection mechanisms, and mutation handlers are automatically registered.
*
* @param <T> the fitness value type
* @param builder the execution context builder to enrich with NEAT capabilities
* @return the builder configured with NEAT components
* @throws IllegalArgumentException if builder is null
*/
public static <T extends Number & Comparable<T>> Builder<T> enrichWithNeat(final Builder<T> builder) {
Validate.notNull(builder);
final var innovationManager = new InnovationManager();
final var speciesIdGenerator = new SpeciesIdGenerator();
final var cfp = ImmutableChromosomeFactoryProvider.builder()
.randomGenerator(RandomGenerator.getDefault())
.addChromosomeFactoriesGenerator(
cdp -> new NeatConnectedChromosomeFactory(cdp.randomGenerator(), innovationManager))
.build();
return enrichWithNeat(builder, innovationManager, speciesIdGenerator, cfp);
}
/**
* Enriches an EA execution context builder with custom NEAT components.
*
* <p>This method allows full customization of NEAT components while still configuring all
* necessary genetic operators and handlers. This is useful when you need custom innovation
* tracking, species management, or initial network topology generation.
*
* @param <T> the fitness value type
* @param builder the execution context builder to enrich
* @param innovationManager custom innovation manager for structural mutation tracking
* @param speciesIdGenerator custom species ID generator for population organization
* @param chromosomeFactoryProvider custom factory provider for initial network generation
* @return the builder configured with custom NEAT components
* @throws IllegalArgumentException if any parameter is null
*/
public static <T extends Number & Comparable<T>> Builder<T> enrichWithNeat(final Builder<T> builder,
final InnovationManager innovationManager, final SpeciesIdGenerator speciesIdGenerator,
final ChromosomeFactoryProvider chromosomeFactoryProvider) {
Validate.notNull(builder);
Validate.notNull(innovationManager);
Validate.notNull(speciesIdGenerator);
Validate.notNull(chromosomeFactoryProvider);
builder.chromosomeFactoryProvider(chromosomeFactoryProvider)
.addSelectionPolicyHandlerFactories(
ec -> new NeatSelectionPolicyHandler<>(ec.randomGenerator(), speciesIdGenerator))
.addMutationPolicyHandlerFactories(ec -> new NeatSwitchStatePolicyHandler<>(ec.randomGenerator()),
ec -> new AddNodePolicyHandler<>(ec.randomGenerator()),
ec -> new DeleteNodePolicyHandler<>(ec.randomGenerator()),
ec -> new AddConnectionPolicyHandler<>(ec.randomGenerator()),
ec -> new DeleteConnectionPolicyHandler<>(ec.randomGenerator()),
ec -> new NeatConnectionWeightPolicyHandler<>(ec.randomGenerator()))
.addChromosomeCombinatorHandlerFactories(ec -> new NeatCombinationHandler<>(ec.randomGenerator()))
.addChromosomeMutationPolicyHandlerFactories(
ec -> new NeatChromosomeSwitchStateHandler(ec.randomGenerator()),
ec -> new NeatChromosomeCreepMutationHandler(ec.randomGenerator()),
ec -> new NeatChromosomeRandomMutationHandler(ec.randomGenerator()),
ec -> new NeatChromosomeAddNodeMutationHandler(ec.randomGenerator(), innovationManager),
ec -> new NeatChromosomeDeleteNodeMutationHandler(ec.randomGenerator()),
ec -> new NeatChromosomeAddConnection(ec.randomGenerator(), innovationManager),
ec -> new NeatChromosomeDeleteConnection(ec.randomGenerator()),
ec -> new NeatChromosomeConnectionWeightMutationHandler(ec.randomGenerator()));
return builder;
}
/**
* Creates a standard NEAT execution context builder with default configuration.
*
* <p>This is the most convenient method for setting up a NEAT evolutionary algorithm with
* standard components and configurations. The returned builder is pre-configured with:
* <ul>
* <li>Scalar fitness evaluation</li>
* <li>Default innovation manager and species ID generator</li>
* <li>Connected initial network topology</li>
* <li>All standard NEAT genetic operators</li>
* <li>Species-based selection mechanism</li>
* </ul>
*
* @param <T> the fitness value type (typically Double)
* @return a builder configured with standard NEAT components
*/
public static <T extends Number & Comparable<T>> Builder<T> standard() {
final var scalarEAExecutionContext = EAExecutionContexts.<T>forScalarFitness();
return enrichWithNeat(scalarEAExecutionContext);
}
}