EASystemFactory.java

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

Mutations

146

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/selection/SelectionPolicyHandlerResolver::<init> → KILLED

149

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::parentSelectionPolicy → KILLED

2.2
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/selection/SelectionPolicyHandlerResolver::resolve → KILLED

151

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/selection/SelectionPolicyHandler::resolve → KILLED

155

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::parentSelectionPolicy → KILLED

157

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/mutation/MutationPolicyHandlerResolver::<init> → KILLED

159

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/combination/ChromosomeCombinatorResolver::<init> → KILLED

161

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::combinationPolicy → KILLED

162

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::chromosomeSpecs → KILLED

163

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to java/util/List::stream → KILLED

164

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to java/util/stream/Stream::map → KILLED

2.2
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testEvolveWithIntChromosome()]
replaced call to java/util/stream/Stream::map with receiver → KILLED

165

1.1
Location : lambda$from$0
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testEvolveWithIntChromosome()]
replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::lambda$from$0 → KILLED

2.2
Location : lambda$from$0
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testEvolveWithIntChromosome()]
removed call to net/bmahe/genetics4j/core/combination/ChromosomeCombinatorResolver::resolve → KILLED

167

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to java/util/stream/Stream::collect → KILLED

2.2
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to java/util/stream/Collectors::toList → KILLED

169

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to java/util/ArrayList::<init> → KILLED

170

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::mutationPolicies → KILLED

171

1.1
Location : from
Killed by : none
removed call to java/util/List::size → SURVIVED
Covering tests

2.2
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed conditional - replaced comparison check with true → KILLED

3.3
Location : from
Killed by : none
negated conditional → SURVIVED Covering tests

4.4
Location : from
Killed by : none
Substituted 0 with 1 → SURVIVED Covering tests

5.5
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
changed conditional boundary → KILLED

6.6
Location : from
Killed by : none
removed conditional - replaced comparison check with false → SURVIVED Covering tests

172

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to java/util/List::get → KILLED

174

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/mutation/MutationPolicyHandlerResolver::resolve → KILLED

176

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testEvolveWithIntChromosome()]
removed call to net/bmahe/genetics4j/core/mutation/MutationPolicyHandler::createMutator → KILLED

178

1.1
Location : from
Killed by : none
removed call to java/util/List::add → SURVIVED
Covering tests

182

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/spec/AbstractEAExecutionContext::replacementStrategyHandlers → KILLED

183

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::replacementStrategy → KILLED

185

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to java/util/List::stream → KILLED

186

1.1
Location : lambda$from$1
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/core/EASystemFactory::lambda$from$1 → SURVIVED
Covering tests

2.2
Location : lambda$from$1
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
replaced boolean return with false for net/bmahe/genetics4j/core/EASystemFactory::lambda$from$1 → KILLED

3.3
Location : from
Killed by : none
replaced call to java/util/stream/Stream::filter with receiver → SURVIVED Covering tests

4.4
Location : lambda$from$1
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/replacement/ReplacementStrategyHandler::canHandle → KILLED

5.5
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to java/util/stream/Stream::filter → KILLED

187

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to java/util/stream/Stream::findFirst → KILLED

189

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to java/util/Optional::orElseThrow → KILLED

190

1.1
Location : lambda$from$2
Killed by : none
removed call to java/lang/String::valueOf → NO_COVERAGE

2.2
Location : lambda$from$2
Killed by : none
replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::lambda$from$2 → NO_COVERAGE

3.3
Location : lambda$from$2
Killed by : none
removed call to java/lang/IllegalStateException::<init> → NO_COVERAGE

193

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/replacement/ReplacementStrategyHandler::resolve → KILLED

195

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/spec/AbstractEAExecutionContext::populationSize → KILLED

197

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::from → KILLED

200

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testEvolveWithIntChromosome()]
removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::offspringGeneratedRatio → KILLED

2.2
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/EASystem::<init> → KILLED

232

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/evaluation/FitnessEvaluatorSync::<init> → KILLED

233

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::from → KILLED

2.2
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/EASystemFactory::from → KILLED

258

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to java/util/concurrent/ForkJoinPool::commonPool → KILLED

259

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::from → KILLED

2.2
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:testSystemConstruction()]
removed call to net/bmahe/genetics4j/core/EASystemFactory::from → KILLED

288

1.1
Location : from
Killed by : none
removed call to net/bmahe/genetics4j/core/evaluation/FitnessEvaluatorBulkAsync::<init> → NO_COVERAGE

289

1.1
Location : from
Killed by : none
removed call to net/bmahe/genetics4j/core/EASystemFactory::from → NO_COVERAGE

2.2
Location : from
Killed by : none
replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::from → NO_COVERAGE

315

1.1
Location : from
Killed by : none
removed call to java/util/concurrent/ForkJoinPool::commonPool → NO_COVERAGE

316

1.1
Location : from
Killed by : none
removed call to net/bmahe/genetics4j/core/EASystemFactory::from → NO_COVERAGE

2.2
Location : from
Killed by : none
replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::from → NO_COVERAGE

354

1.1
Location : fromWithVirtualThreads
Killed by : net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorVirtualThreadTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorVirtualThreadTest]/[method:testVirtualThreadFactory()]
removed call to net/bmahe/genetics4j/core/evaluation/FitnessEvaluatorVirtualThread::<init> → KILLED

355

1.1
Location : fromWithVirtualThreads
Killed by : net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorVirtualThreadTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorVirtualThreadTest]/[method:testVirtualThreadFactory()]
removed call to net/bmahe/genetics4j/core/EASystemFactory::from → KILLED

2.2
Location : fromWithVirtualThreads
Killed by : net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorVirtualThreadTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorVirtualThreadTest]/[method:testVirtualThreadFactory()]
replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::fromWithVirtualThreads → KILLED

Active mutators

Tests examined


Report generated by PIT 1.20.3