View Javadoc
1   package net.bmahe.genetics4j.neat;
2   
3   import java.util.Objects;
4   import java.util.random.RandomGenerator;
5   
6   import net.bmahe.genetics4j.core.chromosomes.factory.ChromosomeFactoryProvider;
7   import net.bmahe.genetics4j.core.chromosomes.factory.ImmutableChromosomeFactoryProvider;
8   import net.bmahe.genetics4j.core.spec.EAExecutionContexts;
9   import net.bmahe.genetics4j.core.spec.ImmutableEAExecutionContext.Builder;
10  import net.bmahe.genetics4j.neat.chromosomes.factory.NeatConnectedChromosomeFactory;
11  import net.bmahe.genetics4j.neat.combination.NeatCombinationHandler;
12  import net.bmahe.genetics4j.neat.mutation.AddConnectionPolicyHandler;
13  import net.bmahe.genetics4j.neat.mutation.AddNodePolicyHandler;
14  import net.bmahe.genetics4j.neat.mutation.DeleteConnectionPolicyHandler;
15  import net.bmahe.genetics4j.neat.mutation.DeleteNodePolicyHandler;
16  import net.bmahe.genetics4j.neat.mutation.NeatConnectionWeightPolicyHandler;
17  import net.bmahe.genetics4j.neat.mutation.NeatSwitchStatePolicyHandler;
18  import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeAddConnection;
19  import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeAddNodeMutationHandler;
20  import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeConnectionWeightMutationHandler;
21  import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeCreepMutationHandler;
22  import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeDeleteConnection;
23  import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeDeleteNodeMutationHandler;
24  import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeRandomMutationHandler;
25  import net.bmahe.genetics4j.neat.mutation.chromosome.NeatChromosomeSwitchStateHandler;
26  import net.bmahe.genetics4j.neat.selection.NeatSelectionPolicyHandler;
27  
28  /**
29   * Factory class for creating NEAT (NeuroEvolution of Augmenting Topologies) execution contexts.
30   * 
31   * <p>NeatEAExecutionContexts provides convenient factory methods for setting up evolutionary algorithm execution
32   * contexts with all the necessary NEAT-specific components, including innovation management, species-based selection,
33   * structural mutations, and neural network-specific genetic operators. This class serves as the primary entry point for
34   * configuring NEAT evolutionary systems.
35   * 
36   * <p>Key NEAT components integrated:
37   * <ul>
38   * <li><strong>Innovation management</strong>: Historical marking system for structural mutations</li>
39   * <li><strong>Species-based selection</strong>: Population organization by genetic similarity</li>
40   * <li><strong>Structural mutations</strong>: Add/delete nodes and connections with innovation tracking</li>
41   * <li><strong>Neural network crossover</strong>: Topology-aware genetic recombination</li>
42   * <li><strong>Chromosome factories</strong>: Initial network generation with proper connectivity</li>
43   * </ul>
44   * 
45   * <p>NEAT algorithm configuration:
46   * <ul>
47   * <li><strong>Mutation operators</strong>: Weight perturbation, add/delete nodes, add/delete connections</li>
48   * <li><strong>Selection strategy</strong>: Species-based selection with fitness sharing</li>
49   * <li><strong>Crossover mechanism</strong>: Innovation-number-based gene alignment</li>
50   * <li><strong>Network initialization</strong>: Configurable initial topology generation</li>
51   * </ul>
52   * 
53   * <p>Common usage patterns:
54   * 
55   * <pre>{@code
56   * // Standard NEAT setup with default components
57   * EAExecutionContext<Double> context = NeatEAExecutionContexts.<Double>standard().build();
58   * 
59   * // Custom NEAT setup with existing builder
60   * var builder = EAExecutionContexts.<Double>forScalarFitness()
61   *     .randomGenerator(myRandomGenerator)
62   *     .termination(myTerminationCondition);
63   * EAExecutionContext<Double> context = NeatEAExecutionContexts.enrichWithNeat(builder).build();
64   * 
65   * // Advanced setup with custom innovation manager
66   * InnovationManager customInnovationManager = new InnovationManager(1000);
67   * SpeciesIdGenerator customSpeciesIdGenerator = new SpeciesIdGenerator();
68   * ChromosomeFactoryProvider customFactoryProvider = // ... create custom provider
69   * 
70   * var context = NeatEAExecutionContexts.enrichWithNeat(
71   *     builder, customInnovationManager, customSpeciesIdGenerator, customFactoryProvider
72   * ).build();
73   * }</pre>
74   * 
75   * <p>Integrated NEAT genetic operators:
76   * <ul>
77   * <li><strong>Weight mutations</strong>: Gaussian perturbation, random replacement, creep mutation</li>
78   * <li><strong>Structural mutations</strong>: Add node, add connection, delete node, delete connection</li>
79   * <li><strong>State mutations</strong>: Enable/disable connections for network topology exploration</li>
80   * <li><strong>Crossover operations</strong>: Innovation-guided gene alignment and inheritance</li>
81   * </ul>
82   * 
83   * <p>Species-based evolution:
84   * <ul>
85   * <li><strong>Compatibility distance</strong>: Genetic similarity measurement for speciation</li>
86   * <li><strong>Fitness sharing</strong>: Population diversity maintenance through species-based selection</li>
87   * <li><strong>Species management</strong>: Dynamic species formation and extinction</li>
88   * <li><strong>Representative selection</strong>: Species representative selection for next generation</li>
89   * </ul>
90   * 
91   * <p>Performance and scalability:
92   * <ul>
93   * <li><strong>Efficient innovation tracking</strong>: O(1) innovation number lookup</li>
94   * <li><strong>Concurrent execution</strong>: Thread-safe components for parallel evolution</li>
95   * <li><strong>Memory management</strong>: Configurable cache management for large populations</li>
96   * <li><strong>Modular design</strong>: Customizable components for specific problem domains</li>
97   * </ul>
98   * 
99   * @see InnovationManager
100  * @see SpeciesIdGenerator
101  * @see NeatChromosome
102  * @see net.bmahe.genetics4j.neat.spec.NeatChromosomeSpec
103  */
104 public class NeatEAExecutionContexts {
105 
106 	private NeatEAExecutionContexts() {
107 	}
108 
109 	/**
110 	 * Enriches an existing EA execution context builder with standard NEAT components.
111 	 * 
112 	 * <p>This method configures the builder with default NEAT components including a new innovation manager, species ID
113 	 * generator, and connected chromosome factory. All NEAT-specific genetic operators, selection mechanisms, and
114 	 * mutation handlers are automatically registered.
115 	 * 
116 	 * @param <T>     the fitness value type
117 	 * @param builder the execution context builder to enrich with NEAT capabilities
118 	 * @return the builder configured with NEAT components
119 	 * @throws IllegalArgumentException if builder is null
120 	 */
121 	public static <T extends Number & Comparable<T>> Builder<T> enrichWithNeat(final Builder<T> builder) {
122 		Objects.requireNonNull(builder);
123 
124 		final var innovationManager = new InnovationManager();
125 		final var speciesIdGenerator = new SpeciesIdGenerator();
126 		final var nodeIdManagerRegistry = new NodeIdManagerRegistry();
127 
128 		final var cfp = ImmutableChromosomeFactoryProvider.builder()
129 				.randomGenerator(RandomGenerator.getDefault())
130 				.addChromosomeFactoriesGenerator(
131 						cdp -> new NeatConnectedChromosomeFactory(cdp.randomGenerator(), innovationManager))
132 				.build();
133 
134 		return enrichWithNeat(builder, innovationManager, speciesIdGenerator, nodeIdManagerRegistry, cfp);
135 	}
136 
137 	/**
138 	 * Enriches an EA execution context builder with custom NEAT components.
139 	 * 
140 	 * <p>This method allows full customization of NEAT components while still configuring all necessary genetic
141 	 * operators and handlers. This is useful when you need custom innovation tracking, species management, or initial
142 	 * network topology generation.
143 	 * 
144 	 * @param <T>                       the fitness value type
145 	 * @param builder                   the execution context builder to enrich
146 	 * @param innovationManager         custom innovation manager for structural mutation tracking
147 	 * @param speciesIdGenerator        custom species ID generator for population organization
148 	 * @param chromosomeFactoryProvider custom factory provider for initial network generation
149 	 * @return the builder configured with custom NEAT components
150 	 * @throws IllegalArgumentException if any parameter is null
151 	 */
152 	public static <T extends Number & Comparable<T>> Builder<T> enrichWithNeat(final Builder<T> builder,
153 			final InnovationManager innovationManager, final SpeciesIdGenerator speciesIdGenerator,
154 			final ChromosomeFactoryProvider chromosomeFactoryProvider) {
155 		return enrichWithNeat(
156 				builder,
157 				innovationManager,
158 				speciesIdGenerator,
159 				new NodeIdManagerRegistry(),
160 				chromosomeFactoryProvider);
161 	}
162 
163 	public static <T extends Number & Comparable<T>> Builder<T> enrichWithNeat(final Builder<T> builder,
164 			final InnovationManager innovationManager, final SpeciesIdGenerator speciesIdGenerator,
165 			final NodeIdManagerRegistry nodeIdManagerRegistry, final ChromosomeFactoryProvider chromosomeFactoryProvider) {
166 		Objects.requireNonNull(builder);
167 		Objects.requireNonNull(innovationManager);
168 		Objects.requireNonNull(speciesIdGenerator);
169 		Objects.requireNonNull(nodeIdManagerRegistry);
170 		Objects.requireNonNull(chromosomeFactoryProvider);
171 
172 		builder.chromosomeFactoryProvider(chromosomeFactoryProvider)
173 				.addSelectionPolicyHandlerFactories(
174 						ec -> new NeatSelectionPolicyHandler<>(ec.randomGenerator(), speciesIdGenerator))
175 				.addMutationPolicyHandlerFactories(
176 						ec -> new NeatSwitchStatePolicyHandler<>(ec.randomGenerator()),
177 						ec -> new AddNodePolicyHandler<>(ec.randomGenerator()),
178 						ec -> new DeleteNodePolicyHandler<>(ec.randomGenerator()),
179 						ec -> new AddConnectionPolicyHandler<>(ec.randomGenerator()),
180 						ec -> new DeleteConnectionPolicyHandler<>(ec.randomGenerator()),
181 						ec -> new NeatConnectionWeightPolicyHandler<>(ec.randomGenerator()))
182 				.addChromosomeCombinatorHandlerFactories(ec -> new NeatCombinationHandler<>(ec.randomGenerator()))
183 				.addChromosomeMutationPolicyHandlerFactories(
184 						ec -> new NeatChromosomeSwitchStateHandler(ec.randomGenerator()),
185 						ec -> new NeatChromosomeCreepMutationHandler(ec.randomGenerator()),
186 						ec -> new NeatChromosomeRandomMutationHandler(ec.randomGenerator()),
187 						ec -> new NeatChromosomeAddNodeMutationHandler(ec.randomGenerator(),
188 								innovationManager,
189 								nodeIdManagerRegistry),
190 						ec -> new NeatChromosomeDeleteNodeMutationHandler(ec.randomGenerator()),
191 						ec -> new NeatChromosomeAddConnection(ec.randomGenerator(), innovationManager),
192 						ec -> new NeatChromosomeDeleteConnection(ec.randomGenerator()),
193 						ec -> new NeatChromosomeConnectionWeightMutationHandler(ec.randomGenerator()));
194 
195 		return builder;
196 	}
197 
198 	/**
199 	 * Creates a standard NEAT execution context builder with default configuration.
200 	 * 
201 	 * <p>This is the most convenient method for setting up a NEAT evolutionary algorithm with standard components and
202 	 * configurations. The returned builder is pre-configured with:
203 	 * <ul>
204 	 * <li>Scalar fitness evaluation</li>
205 	 * <li>Default innovation manager and species ID generator</li>
206 	 * <li>Connected initial network topology</li>
207 	 * <li>All standard NEAT genetic operators</li>
208 	 * <li>Species-based selection mechanism</li>
209 	 * </ul>
210 	 * 
211 	 * @param <T> the fitness value type (typically Double)
212 	 * @return a builder configured with standard NEAT components
213 	 */
214 	public static <T extends Number & Comparable<T>> Builder<T> standard() {
215 
216 		final var scalarEAExecutionContext = EAExecutionContexts.<T>forScalarFitness();
217 		return enrichWithNeat(scalarEAExecutionContext);
218 	}
219 }