1 | package net.bmahe.genetics4j.core; | |
2 | ||
3 | import java.util.ArrayList; | |
4 | import java.util.List; | |
5 | import java.util.Objects; | |
6 | import java.util.Optional; | |
7 | import java.util.concurrent.ExecutorService; | |
8 | import java.util.concurrent.ForkJoinPool; | |
9 | import java.util.stream.Collectors; | |
10 | ||
11 | import net.bmahe.genetics4j.core.combination.ChromosomeCombinator; | |
12 | import net.bmahe.genetics4j.core.combination.ChromosomeCombinatorResolver; | |
13 | import net.bmahe.genetics4j.core.evaluation.FitnessEvaluator; | |
14 | import net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorBulkAsync; | |
15 | import net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorSync; | |
16 | import net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorVirtualThread; | |
17 | import net.bmahe.genetics4j.core.mutation.MutationPolicyHandlerResolver; | |
18 | import net.bmahe.genetics4j.core.mutation.Mutator; | |
19 | import net.bmahe.genetics4j.core.replacement.ReplacementStrategyHandler; | |
20 | import net.bmahe.genetics4j.core.selection.SelectionPolicyHandlerResolver; | |
21 | import net.bmahe.genetics4j.core.spec.AbstractEAConfiguration; | |
22 | import net.bmahe.genetics4j.core.spec.AbstractEAExecutionContext; | |
23 | import net.bmahe.genetics4j.core.spec.EAConfiguration; | |
24 | import net.bmahe.genetics4j.core.spec.EAConfigurationBulkAsync; | |
25 | import net.bmahe.genetics4j.core.spec.EAExecutionContext; | |
26 | import net.bmahe.genetics4j.core.spec.combination.CombinationPolicy; | |
27 | import net.bmahe.genetics4j.core.spec.mutation.MutationPolicy; | |
28 | ||
29 | /** | |
30 | * Factory class providing convenient methods for creating properly configured {@link EASystem} instances. | |
31 | * | |
32 | * <p>EASystemFactory simplifies the complex process of assembling all the components required for evolutionary | |
33 | * algorithms by providing pre-configured factory methods that handle the initialization and wiring of selection | |
34 | * strategies, mutation operators, combination policies, and fitness evaluators. | |
35 | * | |
36 | * <p>The factory abstracts away the complexity of manually creating and configuring: | |
37 | * <ul> | |
38 | * <li><strong>Selection policy resolvers</strong>: Components that match selection strategies to implementations</li> | |
39 | * <li><strong>Mutation policy resolvers</strong>: Components that handle different mutation strategies</li> | |
40 | * <li><strong>Chromosome combinators</strong>: Components responsible for crossover operations</li> | |
41 | * <li><strong>Replacement strategy handlers</strong>: Components managing population replacement</li> | |
42 | * <li><strong>Fitness evaluators</strong>: Components handling fitness computation strategies</li> | |
43 | * </ul> | |
44 | * | |
45 | * <p>Factory methods are organized by evaluation strategy: | |
46 | * <ul> | |
47 | * <li><strong>Synchronous evaluation</strong>: Traditional single-threaded or parallel evaluation using | |
48 | * {@link EAConfiguration}</li> | |
49 | * <li><strong>Bulk asynchronous evaluation</strong>: Batch processing for external services or GPU acceleration using | |
50 | * {@link EAConfigurationBulkAsync}</li> | |
51 | * <li><strong>Custom evaluation</strong>: User-provided {@link FitnessEvaluator} implementations</li> | |
52 | * </ul> | |
53 | * | |
54 | * <p>Common usage patterns: | |
55 | * | |
56 | * <pre>{@code | |
57 | * // Simple synchronous evaluation with default thread pool | |
58 | * EAConfiguration<Double> config = EAConfigurationBuilder.<Double>builder() | |
59 | * .chromosomeSpecs(chromosomeSpec) | |
60 | * .parentSelectionPolicy(Tournament.of(3)) | |
61 | * .combinationPolicy(SinglePointCrossover.build()) | |
62 | * .mutationPolicies(List.of(RandomMutation.of(0.1))) | |
63 | * .replacementStrategy(Elitism.builder() | |
64 | * .offspringRatio(0.8) | |
65 | * .build()) | |
66 | * .build(); | |
67 | * | |
68 | * EAExecutionContext<Double> context = EAExecutionContextBuilder.<Double>builder() | |
69 | * .populationSize(100) | |
70 | * .fitness(genotype -> computeFitness(genotype)) | |
71 | * .termination(Generations.of(100)) | |
72 | * .build(); | |
73 | * | |
74 | * EASystem<Double> eaSystem = EASystemFactory.from(config, context); | |
75 | * | |
76 | * // Asynchronous evaluation for expensive fitness functions | |
77 | * EAConfigurationBulkAsync<Double> asyncConfig = EAConfigurationBulkAsyncBuilder.<Double>builder() | |
78 | * .chromosomeSpecs(chromosomeSpec) | |
79 | * .parentSelectionPolicy(Tournament.of(3)) | |
80 | * .combinationPolicy(SinglePointCrossover.build()) | |
81 | * .mutationPolicies(List.of(RandomMutation.of(0.1))) | |
82 | * .replacementStrategy(Elitism.builder() | |
83 | * .offspringRatio(0.8) | |
84 | * .build()) | |
85 | * .fitnessBulkAsync(genotypes -> evaluateBatch(genotypes)) | |
86 | * .build(); | |
87 | * | |
88 | * EASystem<Double> asyncSystem = EASystemFactory.from(asyncConfig, context); | |
89 | * | |
90 | * // Custom evaluation strategy | |
91 | * FitnessEvaluator<Double> customEvaluator = new CachedFitnessEvaluator<>(baseFitness, cacheSize); | |
92 | * EASystem<Double> customSystem = EASystemFactory.from(config, context, executorService, customEvaluator); | |
93 | * }</pre> | |
94 | * | |
95 | * <p>Factory method selection guide: | |
96 | * <ul> | |
97 | * <li><strong>Fast fitness functions</strong>: Use synchronous methods with {@link EAConfiguration}</li> | |
98 | * <li><strong>Expensive fitness functions</strong>: Use asynchronous methods with {@link EAConfigurationBulkAsync}</li> | |
99 | * <li><strong>External fitness computation</strong>: Use custom evaluator methods</li> | |
100 | * <li><strong>GPU acceleration</strong>: Use bulk async methods for batch processing</li> | |
101 | * </ul> | |
102 | * | |
103 | * <p>Thread pool considerations: | |
104 | * <ul> | |
105 | * <li><strong>Default behavior</strong>: Uses {@link ForkJoinPool#commonPool()} for automatic parallelization</li> | |
106 | * <li><strong>Custom thread pools</strong>: Provide specific {@link ExecutorService} for resource control</li> | |
107 | * <li><strong>Single-threaded</strong>: Use {@link java.util.concurrent.Executors#newSingleThreadExecutor()}</li> | |
108 | * <li><strong>Resource management</strong>: Caller responsible for shutdown of custom thread pools</li> | |
109 | * </ul> | |
110 | * | |
111 | * @see EASystem | |
112 | * @see EAConfiguration | |
113 | * @see EAConfigurationBulkAsync | |
114 | * @see EAExecutionContext | |
115 | * @see FitnessEvaluator | |
116 | */ | |
117 | public class EASystemFactory { | |
118 | ||
119 | /** | |
120 | * Prevents instantiation since it's a bunch of static methods | |
121 | */ | |
122 | private EASystemFactory() { | |
123 | } | |
124 | ||
125 | /** | |
126 | * Creates an {@link EASystem} with a custom fitness evaluator and explicit thread pool. | |
127 | * | |
128 | * <p>This is the most flexible factory method that allows complete control over all components of the evolutionary | |
129 | * algorithm system. It assembles and wires all necessary components including selection strategies, mutation | |
130 | * operators, chromosome combinators, and replacement strategies. | |
131 | * | |
132 | * <p>This method is primarily used internally by other factory methods, but can be used directly when you need to | |
133 | * provide a custom {@link FitnessEvaluator} implementation such as cached, distributed, or specialized evaluation | |
134 | * strategies. | |
135 | * | |
136 | * @param <T> the type of fitness values, must be comparable for selection operations | |
137 | * @param eaConfiguration the evolutionary algorithm configuration specifying genetic operators and strategies | |
138 | * @param eaExecutionContext the execution context containing population parameters and fitness functions | |
139 | * @param fitnessEvaluator the fitness evaluator implementation to use for population evaluation | |
140 | * @return a fully configured {@link EASystem} ready for evolution execution | |
141 | * @throws IllegalArgumentException if any parameter is null | |
142 | * @throws IllegalStateException if no suitable replacement strategy handler can be found | |
143 | */ | |
144 | public static <T extends Comparable<T>> EASystem<T> from(final AbstractEAConfiguration<T> eaConfiguration, | |
145 | final AbstractEAExecutionContext<T> eaExecutionContext, final FitnessEvaluator<T> fitnessEvaluator) { | |
146 | Objects.requireNonNull(eaConfiguration); | |
147 | Objects.requireNonNull(eaExecutionContext); | |
148 | Objects.requireNonNull(fitnessEvaluator); | |
149 | ||
150 |
1
1. from : removed call to net/bmahe/genetics4j/core/selection/SelectionPolicyHandlerResolver::<init> → KILLED |
final var selectionPolicyHandlerResolver = new SelectionPolicyHandlerResolver<T>(eaExecutionContext); |
151 | ||
152 | final var parentSelectionPolicyHandler = selectionPolicyHandlerResolver | |
153 |
2
1. from : removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::parentSelectionPolicy → KILLED 2. from : removed call to net/bmahe/genetics4j/core/selection/SelectionPolicyHandlerResolver::resolve → KILLED |
.resolve(eaConfiguration.parentSelectionPolicy()); |
154 | ||
155 |
1
1. from : removed call to net/bmahe/genetics4j/core/selection/SelectionPolicyHandler::resolve → KILLED |
final var parentSelector = parentSelectionPolicyHandler.resolve(eaExecutionContext, |
156 | eaConfiguration, | |
157 | selectionPolicyHandlerResolver, | |
158 |
1
1. from : removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::parentSelectionPolicy → KILLED |
eaConfiguration.parentSelectionPolicy()); |
159 | ||
160 |
1
1. from : removed call to net/bmahe/genetics4j/core/mutation/MutationPolicyHandlerResolver::<init> → KILLED |
final var mutationPolicyHandlerResolver = new MutationPolicyHandlerResolver<T>(eaExecutionContext); |
161 | ||
162 |
1
1. from : removed call to net/bmahe/genetics4j/core/combination/ChromosomeCombinatorResolver::<init> → KILLED |
final var chromosomeCombinatorResolver = new ChromosomeCombinatorResolver<T>(eaExecutionContext); |
163 | ||
164 |
1
1. from : removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::combinationPolicy → KILLED |
final CombinationPolicy combinationPolicy = eaConfiguration.combinationPolicy(); |
165 |
1
1. from : removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::chromosomeSpecs → KILLED |
final List<ChromosomeCombinator<T>> chromosomeCombinators = eaConfiguration.chromosomeSpecs() |
166 |
1
1. from : removed call to java/util/List::stream → KILLED |
.stream() |
167 |
2
1. from : removed call to java/util/stream/Stream::map → KILLED 2. from : replaced call to java/util/stream/Stream::map with receiver → KILLED |
.map((chromosome) -> { |
168 |
2
1. lambda$from$0 : replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::lambda$from$0 → KILLED 2. lambda$from$0 : removed call to net/bmahe/genetics4j/core/combination/ChromosomeCombinatorResolver::resolve → KILLED |
return chromosomeCombinatorResolver.resolve(combinationPolicy, chromosome); |
169 | }) | |
170 |
2
1. from : removed call to java/util/stream/Stream::collect → KILLED 2. from : removed call to java/util/stream/Collectors::toList → KILLED |
.collect(Collectors.toList()); |
171 | ||
172 |
1
1. from : removed call to java/util/ArrayList::<init> → KILLED |
final List<Mutator> mutators = new ArrayList<>(); |
173 |
1
1. from : removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::mutationPolicies → KILLED |
final List<MutationPolicy> mutationPolicies = eaConfiguration.mutationPolicies(); |
174 |
6
1. from : removed call to java/util/List::size → SURVIVED 2. from : negated conditional → SURVIVED 3. from : Substituted 0 with 1 → SURVIVED 4. from : removed conditional - replaced comparison check with false → SURVIVED 5. from : removed conditional - replaced comparison check with true → KILLED 6. from : changed conditional boundary → KILLED |
for (int i = 0; i < mutationPolicies.size(); i++) { |
175 |
1
1. from : removed call to java/util/List::get → KILLED |
final var mutationPolicy = mutationPolicies.get(i); |
176 | ||
177 |
1
1. from : removed call to net/bmahe/genetics4j/core/mutation/MutationPolicyHandlerResolver::resolve → KILLED |
final var mutationPolicyHandler = mutationPolicyHandlerResolver.resolve(mutationPolicy); |
178 | final var mutator = mutationPolicyHandler | |
179 |
1
1. from : removed call to net/bmahe/genetics4j/core/mutation/MutationPolicyHandler::createMutator → KILLED |
.createMutator(eaExecutionContext, eaConfiguration, mutationPolicyHandlerResolver, mutationPolicy); |
180 | ||
181 |
1
1. from : removed call to java/util/List::add → SURVIVED |
mutators.add(mutator); |
182 | ||
183 | } | |
184 | ||
185 |
1
1. from : removed call to net/bmahe/genetics4j/core/spec/AbstractEAExecutionContext::replacementStrategyHandlers → KILLED |
final var replacementStrategyHandlers = eaExecutionContext.replacementStrategyHandlers(); |
186 |
1
1. from : removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::replacementStrategy → KILLED |
final var replacementStrategy = eaConfiguration.replacementStrategy(); |
187 | ||
188 |
1
1. from : removed call to java/util/List::stream → KILLED |
final Optional<ReplacementStrategyHandler<T>> replacementStrategyHandlerOpt = replacementStrategyHandlers.stream() |
189 |
5
1. lambda$from$1 : replaced boolean return with true for net/bmahe/genetics4j/core/EASystemFactory::lambda$from$1 → SURVIVED 2. from : replaced call to java/util/stream/Stream::filter with receiver → SURVIVED 3. lambda$from$1 : replaced boolean return with false for net/bmahe/genetics4j/core/EASystemFactory::lambda$from$1 → KILLED 4. lambda$from$1 : removed call to net/bmahe/genetics4j/core/replacement/ReplacementStrategyHandler::canHandle → KILLED 5. from : removed call to java/util/stream/Stream::filter → KILLED |
.filter(replacementStrategyHandler -> replacementStrategyHandler.canHandle(replacementStrategy)) |
190 |
1
1. from : removed call to java/util/stream/Stream::findFirst → KILLED |
.findFirst(); |
191 | ||
192 | final ReplacementStrategyHandler<T> replacementStrategyHandler = replacementStrategyHandlerOpt | |
193 |
4
1. lambda$from$2 : removed call to java/lang/String::valueOf → NO_COVERAGE 2. lambda$from$2 : replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::lambda$from$2 → NO_COVERAGE 3. lambda$from$2 : removed call to java/lang/IllegalStateException::<init> → NO_COVERAGE 4. from : removed call to java/util/Optional::orElseThrow → KILLED |
.orElseThrow(() -> new IllegalStateException( |
194 | "Could not find an implementation to handle the replacement strategy " + replacementStrategy)); | |
195 | final var replacementStrategyImplementor = replacementStrategyHandler | |
196 |
1
1. from : removed call to net/bmahe/genetics4j/core/replacement/ReplacementStrategyHandler::resolve → KILLED |
.resolve(eaExecutionContext, eaConfiguration, selectionPolicyHandlerResolver, replacementStrategy); |
197 | ||
198 |
1
1. from : removed call to net/bmahe/genetics4j/core/spec/AbstractEAExecutionContext::populationSize → KILLED |
final long populationSize = eaExecutionContext.populationSize(); |
199 | ||
200 |
1
1. from : replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::from → KILLED |
return new EASystem<>(eaConfiguration, |
201 | populationSize, | |
202 | chromosomeCombinators, | |
203 |
2
1. from : removed call to net/bmahe/genetics4j/core/EASystem::<init> → KILLED 2. from : removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::offspringGeneratedRatio → KILLED |
eaConfiguration.offspringGeneratedRatio(), |
204 | parentSelector, | |
205 | mutators, | |
206 | replacementStrategyImplementor, | |
207 | eaExecutionContext, | |
208 | fitnessEvaluator); | |
209 | } | |
210 | ||
211 | /** | |
212 | * Creates an {@link EASystem} with synchronous fitness evaluation and explicit thread pool. | |
213 | * | |
214 | * <p>This method is ideal for scenarios where fitness computation is relatively fast and can benefit from parallel | |
215 | * evaluation across multiple threads. The fitness function defined in the configuration will be called synchronously | |
216 | * for each individual or in parallel depending on the evaluator implementation. | |
217 | * | |
218 | * <p>Use this method when: | |
219 | * <ul> | |
220 | * <li>Fitness computation is CPU-bound and relatively fast (< 100ms per evaluation)</li> | |
221 | * <li>You want control over the thread pool used for parallel evaluation</li> | |
222 | * <li>You need deterministic thread pool behavior for testing or resource management</li> | |
223 | * </ul> | |
224 | * | |
225 | * @param <T> the type of fitness values, must be comparable for selection operations | |
226 | * @param eaConfigurationSync the synchronous EA configuration with a simple fitness function | |
227 | * @param eaExecutionContext the execution context containing population and termination parameters | |
228 | * @param executorService the thread pool for parallel fitness evaluation (caller responsible for shutdown) | |
229 | * @return a configured {@link EASystem} using synchronous fitness evaluation | |
230 | * @throws IllegalArgumentException if any parameter is null | |
231 | */ | |
232 | public static <T extends Comparable<T>> EASystem<T> from(final EAConfiguration<T> eaConfigurationSync, | |
233 | final EAExecutionContext<T> eaExecutionContext, final ExecutorService executorService) { | |
234 | ||
235 |
1
1. from : removed call to net/bmahe/genetics4j/core/evaluation/FitnessEvaluatorSync::<init> → KILLED |
final var fitnessEvaluator = new FitnessEvaluatorSync<>(eaExecutionContext, eaConfigurationSync, executorService); |
236 |
2
1. from : replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::from → KILLED 2. from : removed call to net/bmahe/genetics4j/core/EASystemFactory::from → KILLED |
return from(eaConfigurationSync, eaExecutionContext, fitnessEvaluator); |
237 | } | |
238 | ||
239 | /** | |
240 | * Creates an {@link EASystem} with synchronous fitness evaluation using the common thread pool. | |
241 | * | |
242 | * <p>This is the most convenient method for creating evolutionary algorithms with simple fitness functions. It uses | |
243 | * {@link ForkJoinPool#commonPool()} for automatic parallelization without requiring explicit thread pool management. | |
244 | * | |
245 | * <p>This method is ideal for: | |
246 | * <ul> | |
247 | * <li>Quick prototyping and experimentation</li> | |
248 | * <li>Applications where thread pool management is not critical</li> | |
249 | * <li>Fast fitness functions that can benefit from automatic parallelization</li> | |
250 | * <li>Educational purposes and simple examples</li> | |
251 | * </ul> | |
252 | * | |
253 | * @param <T> the type of fitness values, must be comparable for selection operations | |
254 | * @param eaConfigurationSync the synchronous EA configuration with a simple fitness function | |
255 | * @param eaExecutionContext the execution context containing population and termination parameters | |
256 | * @return a configured {@link EASystem} using synchronous fitness evaluation with common thread pool | |
257 | * @throws IllegalArgumentException if any parameter is null | |
258 | */ | |
259 | public static <T extends Comparable<T>> EASystem<T> from(final EAConfiguration<T> eaConfigurationSync, | |
260 | final EAExecutionContext<T> eaExecutionContext) { | |
261 |
1
1. from : removed call to java/util/concurrent/ForkJoinPool::commonPool → KILLED |
final ExecutorService executorService = ForkJoinPool.commonPool(); |
262 |
2
1. from : replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::from → KILLED 2. from : removed call to net/bmahe/genetics4j/core/EASystemFactory::from → KILLED |
return from(eaConfigurationSync, eaExecutionContext, executorService); |
263 | } | |
264 | ||
265 | /** | |
266 | * Creates an {@link EASystem} with bulk asynchronous fitness evaluation and explicit thread pool. | |
267 | * | |
268 | * <p>This method is designed for expensive fitness functions that can benefit from batch processing or asynchronous | |
269 | * evaluation. The bulk async evaluator can process entire populations at once, enabling optimization strategies like | |
270 | * GPU acceleration, external service calls, or database batch operations. | |
271 | * | |
272 | * <p>Use this method when: | |
273 | * <ul> | |
274 | * <li>Fitness computation involves external resources (databases, web services, files)</li> | |
275 | * <li>Evaluation can be accelerated through batch processing (GPU, vectorized operations)</li> | |
276 | * <li>Fitness computation is expensive (> 100ms per evaluation)</li> | |
277 | * <li>You need to optimize I/O operations through batching</li> | |
278 | * </ul> | |
279 | * | |
280 | * @param <T> the type of fitness values, must be comparable for selection operations | |
281 | * @param eaConfigurationBulkAsync the bulk async EA configuration with batch fitness evaluation | |
282 | * @param eaExecutionContext the execution context containing population and termination parameters | |
283 | * @param executorService the thread pool for managing asynchronous operations (caller responsible for | |
284 | * shutdown) | |
285 | * @return a configured {@link EASystem} using bulk asynchronous fitness evaluation | |
286 | * @throws IllegalArgumentException if any parameter is null | |
287 | */ | |
288 | public static <T extends Comparable<T>> EASystem<T> from(final EAConfigurationBulkAsync<T> eaConfigurationBulkAsync, | |
289 | final EAExecutionContext<T> eaExecutionContext, final ExecutorService executorService) { | |
290 | ||
291 |
1
1. from : removed call to net/bmahe/genetics4j/core/evaluation/FitnessEvaluatorBulkAsync::<init> → NO_COVERAGE |
final var fitnessEvaluator = new FitnessEvaluatorBulkAsync<>(eaConfigurationBulkAsync, executorService); |
292 |
2
1. from : removed call to net/bmahe/genetics4j/core/EASystemFactory::from → NO_COVERAGE 2. from : replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::from → NO_COVERAGE |
return from(eaConfigurationBulkAsync, eaExecutionContext, fitnessEvaluator); |
293 | } | |
294 | ||
295 | /** | |
296 | * Creates an {@link EASystem} with bulk asynchronous fitness evaluation using the common thread pool. | |
297 | * | |
298 | * <p>This convenience method provides the benefits of bulk asynchronous evaluation without requiring explicit thread | |
299 | * pool management. It automatically uses {@link ForkJoinPool#commonPool()} for managing asynchronous operations. | |
300 | * | |
301 | * <p>This method combines the convenience of automatic thread pool management with the power of bulk asynchronous | |
302 | * evaluation, making it ideal for: | |
303 | * <ul> | |
304 | * <li>Expensive fitness functions in research and experimentation</li> | |
305 | * <li>Applications requiring external resource access without complex thread management</li> | |
306 | * <li>GPU-accelerated fitness evaluation with simple setup</li> | |
307 | * <li>Prototype development with advanced evaluation strategies</li> | |
308 | * </ul> | |
309 | * | |
310 | * @param <T> the type of fitness values, must be comparable for selection operations | |
311 | * @param eaConfigurationBulkAsync the bulk async EA configuration with batch fitness evaluation | |
312 | * @param eaExecutionContext the execution context containing population and termination parameters | |
313 | * @return a configured {@link EASystem} using bulk asynchronous fitness evaluation with common thread pool | |
314 | * @throws IllegalArgumentException if any parameter is null | |
315 | */ | |
316 | public static <T extends Comparable<T>> EASystem<T> from(final EAConfigurationBulkAsync<T> eaConfigurationBulkAsync, | |
317 | final EAExecutionContext<T> eaExecutionContext) { | |
318 |
1
1. from : removed call to java/util/concurrent/ForkJoinPool::commonPool → NO_COVERAGE |
final ExecutorService executorService = ForkJoinPool.commonPool(); |
319 |
2
1. from : removed call to net/bmahe/genetics4j/core/EASystemFactory::from → NO_COVERAGE 2. from : replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::from → NO_COVERAGE |
return from(eaConfigurationBulkAsync, eaExecutionContext, executorService); |
320 | } | |
321 | ||
322 | /** | |
323 | * Creates an {@link EASystem} with virtual thread-based fitness evaluation. | |
324 | * | |
325 | * <p>This method leverages Java 21+ virtual threads to provide massive parallelism for fitness evaluation without | |
326 | * the overhead of traditional platform threads. Each genotype gets its own virtual thread, making this approach | |
327 | * ideal for I/O-bound fitness functions and large populations. | |
328 | * | |
329 | * <p>Virtual threads excel in scenarios involving: | |
330 | * <ul> | |
331 | * <li><strong>I/O-bound fitness functions</strong>: Database queries, web service calls, file operations</li> | |
332 | * <li><strong>Large populations</strong>: Thousands of individuals without thread pool limitations</li> | |
333 | * <li><strong>Complex simulations</strong>: Long-running evaluations that benefit from massive parallelism</li> | |
334 | * <li><strong>External service integration</strong>: Fitness evaluations requiring network calls</li> | |
335 | * </ul> | |
336 | * | |
337 | * <p>Performance characteristics: | |
338 | * <ul> | |
339 | * <li><strong>Memory overhead</strong>: ~200 bytes per virtual thread vs ~2MB per platform thread</li> | |
340 | * <li><strong>Creation cost</strong>: Nearly zero compared to platform threads</li> | |
341 | * <li><strong>Blocking behavior</strong>: Virtual threads don't block carrier threads during I/O</li> | |
342 | * <li><strong>Scalability</strong>: Can handle millions of concurrent virtual threads</li> | |
343 | * </ul> | |
344 | * | |
345 | * <p><strong>Requirements:</strong> Java 21+ with virtual threads enabled | |
346 | * | |
347 | * @param <T> the type of fitness values, must be comparable for selection operations | |
348 | * @param eaConfigurationSync the synchronous EA configuration with a simple fitness function | |
349 | * @param eaExecutionContext the execution context containing population and termination parameters | |
350 | * @return a configured {@link EASystem} using virtual thread-based fitness evaluation | |
351 | * @throws IllegalArgumentException if any parameter is null | |
352 | * @throws UnsupportedOperationException if virtual threads are not available in current JVM | |
353 | */ | |
354 | public static <T extends Comparable<T>> EASystem<T> fromWithVirtualThreads( | |
355 | final EAConfiguration<T> eaConfigurationSync, final EAExecutionContext<T> eaExecutionContext) { | |
356 | ||
357 |
1
1. fromWithVirtualThreads : removed call to net/bmahe/genetics4j/core/evaluation/FitnessEvaluatorVirtualThread::<init> → KILLED |
final var fitnessEvaluator = new FitnessEvaluatorVirtualThread<>(eaExecutionContext, eaConfigurationSync); |
358 |
2
1. fromWithVirtualThreads : removed call to net/bmahe/genetics4j/core/EASystemFactory::from → KILLED 2. fromWithVirtualThreads : replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::fromWithVirtualThreads → KILLED |
return from(eaConfigurationSync, eaExecutionContext, fitnessEvaluator); |
359 | } | |
360 | } | |
Mutations | ||
150 |
1.1 |
|
153 |
1.1 2.2 |
|
155 |
1.1 |
|
158 |
1.1 |
|
160 |
1.1 |
|
162 |
1.1 |
|
164 |
1.1 |
|
165 |
1.1 |
|
166 |
1.1 |
|
167 |
1.1 2.2 |
|
168 |
1.1 2.2 |
|
170 |
1.1 2.2 |
|
172 |
1.1 |
|
173 |
1.1 |
|
174 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
175 |
1.1 |
|
177 |
1.1 |
|
179 |
1.1 |
|
181 |
1.1 |
|
185 |
1.1 |
|
186 |
1.1 |
|
188 |
1.1 |
|
189 |
1.1 2.2 3.3 4.4 5.5 |
|
190 |
1.1 |
|
193 |
1.1 2.2 3.3 4.4 |
|
196 |
1.1 |
|
198 |
1.1 |
|
200 |
1.1 |
|
203 |
1.1 2.2 |
|
235 |
1.1 |
|
236 |
1.1 2.2 |
|
261 |
1.1 |
|
262 |
1.1 2.2 |
|
291 |
1.1 |
|
292 |
1.1 2.2 |
|
318 |
1.1 |
|
319 |
1.1 2.2 |
|
357 |
1.1 |
|
358 |
1.1 2.2 |