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 4 1. lambda$from$0 : replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::lambda$from$0 → KILLED
2. from : removed call to java/util/stream/Stream::map → KILLED
3. from : replaced call to java/util/stream/Stream::map with receiver → KILLED
4. lambda$from$0 : removed call to net/bmahe/genetics4j/core/combination/ChromosomeCombinatorResolver::resolve → KILLED
				.map(chromosome -> chromosomeCombinatorResolver.resolve(combinationPolicy, chromosome))
165 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());
166
167 1 1. from : removed call to java/util/ArrayList::<init> → KILLED
		final List<Mutator> mutators = new ArrayList<>();
168 1 1. from : removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::mutationPolicies → KILLED
		final List<MutationPolicy> mutationPolicies = eaConfiguration.mutationPolicies();
169 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++) {
170 1 1. from : removed call to java/util/List::get → KILLED
			final var mutationPolicy = mutationPolicies.get(i);
171
172 1 1. from : removed call to net/bmahe/genetics4j/core/mutation/MutationPolicyHandlerResolver::resolve → KILLED
			final var mutationPolicyHandler = mutationPolicyHandlerResolver.resolve(mutationPolicy);
173
			final var mutator = mutationPolicyHandler
174 1 1. from : removed call to net/bmahe/genetics4j/core/mutation/MutationPolicyHandler::createMutator → KILLED
					.createMutator(eaExecutionContext, eaConfiguration, mutationPolicyHandlerResolver, mutationPolicy);
175
176 1 1. from : removed call to java/util/List::add → SURVIVED
			mutators.add(mutator);
177
178
		}
179
180 1 1. from : removed call to net/bmahe/genetics4j/core/spec/AbstractEAExecutionContext::replacementStrategyHandlers → KILLED
		final var replacementStrategyHandlers = eaExecutionContext.replacementStrategyHandlers();
181 1 1. from : removed call to net/bmahe/genetics4j/core/spec/AbstractEAConfiguration::replacementStrategy → KILLED
		final var replacementStrategy = eaConfiguration.replacementStrategy();
182
183 1 1. from : removed call to java/util/List::stream → KILLED
		final Optional<ReplacementStrategyHandler<T>> replacementStrategyHandlerOpt = replacementStrategyHandlers.stream()
184 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))
185 1 1. from : removed call to java/util/stream/Stream::findFirst → KILLED
				.findFirst();
186
187 1 1. from : removed call to java/util/Optional::orElseThrow → KILLED
		final ReplacementStrategyHandler<T> replacementStrategyHandler = replacementStrategyHandlerOpt.orElseThrow(
188 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(
189
						"Could not find an implementation to handle the replacement strategy " + replacementStrategy));
190
		final var replacementStrategyImplementor = replacementStrategyHandler
191 1 1. from : removed call to net/bmahe/genetics4j/core/replacement/ReplacementStrategyHandler::resolve → KILLED
				.resolve(eaExecutionContext, eaConfiguration, selectionPolicyHandlerResolver, replacementStrategy);
192
193 1 1. from : removed call to net/bmahe/genetics4j/core/spec/AbstractEAExecutionContext::populationSize → KILLED
		final long populationSize = eaExecutionContext.populationSize();
194
195 1 1. from : replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::from → KILLED
		return new EASystem<>(eaConfiguration,
196
				populationSize,
197
				chromosomeCombinators,
198 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(),
199
				parentSelector,
200
				mutators,
201
				replacementStrategyImplementor,
202
				eaExecutionContext,
203
				fitnessEvaluator);
204
	}
205
206
	/**
207
	 * Creates an {@link EASystem} with synchronous fitness evaluation and explicit thread pool.
208
	 * 
209
	 * <p>This method is ideal for scenarios where fitness computation is relatively fast and can benefit from parallel
210
	 * evaluation across multiple threads. The fitness function defined in the configuration will be called synchronously
211
	 * for each individual or in parallel depending on the evaluator implementation.
212
	 * 
213
	 * <p>Use this method when:
214
	 * <ul>
215
	 * <li>Fitness computation is CPU-bound and relatively fast (&lt; 100ms per evaluation)</li>
216
	 * <li>You want control over the thread pool used for parallel evaluation</li>
217
	 * <li>You need deterministic thread pool behavior for testing or resource management</li>
218
	 * </ul>
219
	 * 
220
	 * @param <T>                 the type of fitness values, must be comparable for selection operations
221
	 * @param eaConfigurationSync the synchronous EA configuration with a simple fitness function
222
	 * @param eaExecutionContext  the execution context containing population and termination parameters
223
	 * @param executorService     the thread pool for parallel fitness evaluation (caller responsible for shutdown)
224
	 * @return a configured {@link EASystem} using synchronous fitness evaluation
225
	 * @throws IllegalArgumentException if any parameter is null
226
	 */
227
	public static <T extends Comparable<T>> EASystem<T> from(final EAConfiguration<T> eaConfigurationSync,
228
			final EAExecutionContext<T> eaExecutionContext, final ExecutorService executorService) {
229
230 1 1. from : removed call to net/bmahe/genetics4j/core/evaluation/FitnessEvaluatorSync::<init> → KILLED
		final var fitnessEvaluator = new FitnessEvaluatorSync<>(eaExecutionContext, eaConfigurationSync, executorService);
231 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);
232
	}
233
234
	/**
235
	 * Creates an {@link EASystem} with synchronous fitness evaluation using the common thread pool.
236
	 * 
237
	 * <p>This is the most convenient method for creating evolutionary algorithms with simple fitness functions. It uses
238
	 * {@link ForkJoinPool#commonPool()} for automatic parallelization without requiring explicit thread pool management.
239
	 * 
240
	 * <p>This method is ideal for:
241
	 * <ul>
242
	 * <li>Quick prototyping and experimentation</li>
243
	 * <li>Applications where thread pool management is not critical</li>
244
	 * <li>Fast fitness functions that can benefit from automatic parallelization</li>
245
	 * <li>Educational purposes and simple examples</li>
246
	 * </ul>
247
	 * 
248
	 * @param <T>                 the type of fitness values, must be comparable for selection operations
249
	 * @param eaConfigurationSync the synchronous EA configuration with a simple fitness function
250
	 * @param eaExecutionContext  the execution context containing population and termination parameters
251
	 * @return a configured {@link EASystem} using synchronous fitness evaluation with common thread pool
252
	 * @throws IllegalArgumentException if any parameter is null
253
	 */
254
	public static <T extends Comparable<T>> EASystem<T> from(final EAConfiguration<T> eaConfigurationSync,
255
			final EAExecutionContext<T> eaExecutionContext) {
256 1 1. from : removed call to java/util/concurrent/ForkJoinPool::commonPool → KILLED
		final ExecutorService executorService = ForkJoinPool.commonPool();
257 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);
258
	}
259
260
	/**
261
	 * Creates an {@link EASystem} with bulk asynchronous fitness evaluation and explicit thread pool.
262
	 * 
263
	 * <p>This method is designed for expensive fitness functions that can benefit from batch processing or asynchronous
264
	 * evaluation. The bulk async evaluator can process entire populations at once, enabling optimization strategies like
265
	 * GPU acceleration, external service calls, or database batch operations.
266
	 * 
267
	 * <p>Use this method when:
268
	 * <ul>
269
	 * <li>Fitness computation involves external resources (databases, web services, files)</li>
270
	 * <li>Evaluation can be accelerated through batch processing (GPU, vectorized operations)</li>
271
	 * <li>Fitness computation is expensive (&gt; 100ms per evaluation)</li>
272
	 * <li>You need to optimize I/O operations through batching</li>
273
	 * </ul>
274
	 * 
275
	 * @param <T>                      the type of fitness values, must be comparable for selection operations
276
	 * @param eaConfigurationBulkAsync the bulk async EA configuration with batch fitness evaluation
277
	 * @param eaExecutionContext       the execution context containing population and termination parameters
278
	 * @param executorService          the thread pool for managing asynchronous operations (caller responsible for
279
	 *                                 shutdown)
280
	 * @return a configured {@link EASystem} using bulk asynchronous fitness evaluation
281
	 * @throws IllegalArgumentException if any parameter is null
282
	 */
283
	public static <T extends Comparable<T>> EASystem<T> from(final EAConfigurationBulkAsync<T> eaConfigurationBulkAsync,
284
			final EAExecutionContext<T> eaExecutionContext, final ExecutorService executorService) {
285
286 1 1. from : removed call to net/bmahe/genetics4j/core/evaluation/FitnessEvaluatorBulkAsync::<init> → NO_COVERAGE
		final var fitnessEvaluator = new FitnessEvaluatorBulkAsync<>(eaConfigurationBulkAsync, executorService);
287 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);
288
	}
289
290
	/**
291
	 * Creates an {@link EASystem} with bulk asynchronous fitness evaluation using the common thread pool.
292
	 * 
293
	 * <p>This convenience method provides the benefits of bulk asynchronous evaluation without requiring explicit thread
294
	 * pool management. It automatically uses {@link ForkJoinPool#commonPool()} for managing asynchronous operations.
295
	 * 
296
	 * <p>This method combines the convenience of automatic thread pool management with the power of bulk asynchronous
297
	 * evaluation, making it ideal for:
298
	 * <ul>
299
	 * <li>Expensive fitness functions in research and experimentation</li>
300
	 * <li>Applications requiring external resource access without complex thread management</li>
301
	 * <li>GPU-accelerated fitness evaluation with simple setup</li>
302
	 * <li>Prototype development with advanced evaluation strategies</li>
303
	 * </ul>
304
	 * 
305
	 * @param <T>                      the type of fitness values, must be comparable for selection operations
306
	 * @param eaConfigurationBulkAsync the bulk async EA configuration with batch fitness evaluation
307
	 * @param eaExecutionContext       the execution context containing population and termination parameters
308
	 * @return a configured {@link EASystem} using bulk asynchronous fitness evaluation with common thread pool
309
	 * @throws IllegalArgumentException if any parameter is null
310
	 */
311
	public static <T extends Comparable<T>> EASystem<T> from(final EAConfigurationBulkAsync<T> eaConfigurationBulkAsync,
312
			final EAExecutionContext<T> eaExecutionContext) {
313 1 1. from : removed call to java/util/concurrent/ForkJoinPool::commonPool → NO_COVERAGE
		final ExecutorService executorService = ForkJoinPool.commonPool();
314 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);
315
	}
316
317
	/**
318
	 * Creates an {@link EASystem} with virtual thread-based fitness evaluation.
319
	 *
320
	 * <p>This method leverages virtual threads to provide massive parallelism for fitness evaluation without the
321
	 * overhead of traditional platform threads. Each genotype gets its own virtual thread, making this approach ideal
322
	 * for I/O-bound fitness functions and large populations.
323
	 *
324
	 * <p>Virtual threads excel in scenarios involving:
325
	 * <ul>
326
	 * <li><strong>I/O-bound fitness functions</strong>: Database queries, web service calls, file operations</li>
327
	 * <li><strong>Large populations</strong>: Thousands of individuals without thread pool limitations</li>
328
	 * <li><strong>Complex simulations</strong>: Long-running evaluations that benefit from massive parallelism</li>
329
	 * <li><strong>External service integration</strong>: Fitness evaluations requiring network calls</li>
330
	 * </ul>
331
	 *
332
	 * <p>Performance characteristics:
333
	 * <ul>
334
	 * <li><strong>Memory overhead</strong>: ~200 bytes per virtual thread vs ~2MB per platform thread</li>
335
	 * <li><strong>Creation cost</strong>: Nearly zero compared to platform threads</li>
336
	 * <li><strong>Blocking behavior</strong>: Virtual threads don't block carrier threads during I/O</li>
337
	 * <li><strong>Scalability</strong>: Can handle millions of concurrent virtual threads</li>
338
	 * </ul>
339
	 *
340
	 * <p><strong>Requirements:</strong> Java 25 or later
341
	 *
342
	 * @param <T>                 the type of fitness values, must be comparable for selection operations
343
	 * @param eaConfigurationSync the synchronous EA configuration with a simple fitness function
344
	 * @param eaExecutionContext  the execution context containing population and termination parameters
345
	 * @return a configured {@link EASystem} using virtual thread-based fitness evaluation
346
	 * @throws IllegalArgumentException      if any parameter is null
347
	 * @throws UnsupportedOperationException if virtual threads are not available in current JVM
348
	 */
349
	public static <T extends Comparable<T>> EASystem<T> fromWithVirtualThreads(
350
			final EAConfiguration<T> eaConfigurationSync, final EAExecutionContext<T> eaExecutionContext) {
351
352 1 1. fromWithVirtualThreads : removed call to net/bmahe/genetics4j/core/evaluation/FitnessEvaluatorVirtualThread::<init> → KILLED
		final var fitnessEvaluator = new FitnessEvaluatorVirtualThread<>(eaExecutionContext, eaConfigurationSync);
353 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);
354
	}
355
}

Mutations

146

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

149

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

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

151

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

155

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

157

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

159

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

161

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

162

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

163

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

164

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

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

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

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

165

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

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

167

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

168

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

169

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.evaluation.FitnessEvaluatorVirtualThreadTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorVirtualThreadTest]/[method:virtualThreadFactory()]
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.evaluation.FitnessEvaluatorVirtualThreadTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorVirtualThreadTest]/[method:virtualThreadFactory()]
changed conditional boundary → KILLED

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

170

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

172

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

174

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

176

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

180

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

181

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

183

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

184

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.evaluation.FitnessEvaluatorVirtualThreadTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorVirtualThreadTest]/[method:virtualThreadFactory()]
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.evaluation.FitnessEvaluatorVirtualThreadTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorVirtualThreadTest]/[method:virtualThreadFactory()]
removed call to net/bmahe/genetics4j/core/replacement/ReplacementStrategyHandler::canHandle → KILLED

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

185

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

187

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

188

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

191

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

193

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

195

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

198

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

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

230

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

231

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:evaluateOnceWithDifferentGenerations()]
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:evaluateOnceWithDifferentGenerations()]
removed call to net/bmahe/genetics4j/core/EASystemFactory::from → KILLED

256

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

257

1.1
Location : from
Killed by : net.bmahe.genetics4j.core.EASystemTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.EASystemTest]/[method:evaluateOnceWithDifferentGenerations()]
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:evaluateOnceWithDifferentGenerations()]
removed call to net/bmahe/genetics4j/core/EASystemFactory::from → KILLED

286

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

287

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

313

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

314

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

352

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

353

1.1
Location : fromWithVirtualThreads
Killed by : net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorVirtualThreadTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorVirtualThreadTest]/[method:virtualThreadFactory()]
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:virtualThreadFactory()]
replaced return value with null for net/bmahe/genetics4j/core/EASystemFactory::fromWithVirtualThreads → KILLED

Active mutators

Tests examined


Report generated by PIT 1.25.7 support