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 }