View Javadoc
1   package net.bmahe.genetics4j.core;
2   
3   import java.util.List;
4   import java.util.concurrent.CompletableFuture;
5   import java.util.concurrent.ExecutorService;
6   
7   /**
8    * Functional interface for asynchronous batch fitness evaluation in evolutionary algorithms.
9    * 
10   * <p>FitnessBulkAsync enables efficient evaluation of entire populations through asynchronous, batch-oriented fitness
11   * computation. This approach is particularly beneficial for expensive fitness functions that can be optimized through
12   * parallel processing, external service calls, or specialized hardware acceleration like GPUs.
13   * 
14   * <p>Key advantages of bulk asynchronous evaluation:
15   * <ul>
16   * <li><strong>Batch optimization</strong>: Process multiple individuals simultaneously for better resource
17   * utilization</li>
18   * <li><strong>External integration</strong>: Efficient interfacing with databases, web services, or simulation
19   * engines</li>
20   * <li><strong>Hardware acceleration</strong>: Leverage GPUs, TPUs, or distributed computing resources</li>
21   * <li><strong>I/O efficiency</strong>: Minimize network round-trips and database connections through batching</li>
22   * <li><strong>Non-blocking execution</strong>: Allow other operations to proceed while fitness computation occurs</li>
23   * </ul>
24   * 
25   * <p>Common use cases include:
26   * <ul>
27   * <li><strong>Neural network evaluation</strong>: Batch processing through deep learning frameworks</li>
28   * <li><strong>Simulation-based fitness</strong>: Running multiple simulations in parallel or on clusters</li>
29   * <li><strong>Database queries</strong>: Efficient batch retrieval of fitness data from external sources</li>
30   * <li><strong>Web service calls</strong>: Minimize API calls through bulk evaluation requests</li>
31   * <li><strong>Scientific computing</strong>: Utilize high-performance computing resources</li>
32   * </ul>
33   * 
34   * <p>Implementation considerations:
35   * <ul>
36   * <li><strong>Return order</strong>: Fitness values must correspond to input genotypes in the same order</li>
37   * <li><strong>Error handling</strong>: Handle individual evaluation failures gracefully within the batch</li>
38   * <li><strong>Resource management</strong>: Properly utilize the provided executor service for concurrent
39   * operations</li>
40   * <li><strong>Cancellation support</strong>: Consider supporting cancellation through CompletableFuture mechanisms</li>
41   * </ul>
42   * 
43   * <p>Example implementations:
44   * 
45   * <pre>{@code
46   * // GPU-accelerated batch evaluation
47   * FitnessBulkAsync<Double> gpuEvaluator = (executorService, genotypes) -> {
48   * 	return CompletableFuture.supplyAsync(() -> {
49   * 		// Convert genotypes to GPU-friendly format
50   * 		float[][] inputData = convertToGPUFormat(genotypes);
51   * 
52   * 		// Execute batch computation on GPU
53   * 		float[] results = gpuKernel.evaluate(inputData);
54   * 
55   * 		// Convert back to fitness values
56   * 		return Arrays.stream(results).boxed().map(Double::valueOf).collect(toList());
57   * 	}, executorService);
58   * };
59   * 
60   * // External service batch evaluation
61   * FitnessBulkAsync<Double> serviceEvaluator = (executorService, genotypes) -> {
62   * 	return CompletableFuture.supplyAsync(() -> {
63   * 		// Prepare batch request
64   * 		BatchEvaluationRequest request = new BatchEvaluationRequest(genotypes);
65   * 
66   * 		// Make single API call for entire batch
67   * 		BatchEvaluationResponse response = fitnessService.evaluateBatch(request);
68   * 
69   * 		return response.getFitnessValues();
70   * 	}, executorService);
71   * };
72   * 
73   * // Parallel simulation evaluation
74   * FitnessBulkAsync<Double> simulationEvaluator = (executorService, genotypes) -> {
75   * 	List<CompletableFuture<Double>> futures = genotypes.stream()
76   * 			.map(genotype -> CompletableFuture.supplyAsync(() -> runSimulation(genotype), executorService))
77   * 			.collect(toList());
78   * 
79   * 	return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
80   * 			.thenApply(ignored -> futures.stream().map(CompletableFuture::join).collect(toList()));
81   * };
82   * }</pre>
83   * 
84   * <p>Integration with EA system:
85   * <ul>
86   * <li><strong>Configuration</strong>: Used with {@link net.bmahe.genetics4j.core.spec.EAConfigurationBulkAsync}</li>
87   * <li><strong>Evaluation flow</strong>: Called by
88   * {@link net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorBulkAsync}</li>
89   * <li><strong>Thread management</strong>: Receives configured executor service for optimal resource usage</li>
90   * <li><strong>Performance monitoring</strong>: Can be wrapped with metrics collection and caching strategies</li>
91   * </ul>
92   * 
93   * @param <T> the type of fitness values produced, must be comparable for selection operations
94   * @see net.bmahe.genetics4j.core.spec.EAConfigurationBulkAsync
95   * @see net.bmahe.genetics4j.core.evaluation.FitnessEvaluatorBulkAsync
96   * @see net.bmahe.genetics4j.core.Fitness
97   * @see CompletableFuture
98   */
99  @FunctionalInterface
100 public interface FitnessBulkAsync<T extends Comparable<T>> {
101 
102 	/**
103 	 * Asynchronously computes fitness values for an entire population of genotypes.
104 	 * 
105 	 * <p>This method implements the core fitness evaluation logic for bulk asynchronous processing. Implementations
106 	 * should leverage the provided executor service for optimal concurrency and return a CompletableFuture that will
107 	 * complete with fitness values corresponding to each input genotype in the same order.
108 	 * 
109 	 * <p>Implementation requirements:
110 	 * <ul>
111 	 * <li><strong>Order preservation</strong>: Return fitness values in the same order as input genotypes</li>
112 	 * <li><strong>Size consistency</strong>: Return exactly one fitness value per input genotype</li>
113 	 * <li><strong>Executor usage</strong>: Utilize the provided executor service for concurrent operations</li>
114 	 * <li><strong>Error handling</strong>: Handle evaluation failures gracefully or propagate through
115 	 * CompletableFuture</li>
116 	 * </ul>
117 	 * 
118 	 * <p>Performance considerations:
119 	 * <ul>
120 	 * <li>Batch operations where possible to minimize overhead</li>
121 	 * <li>Use the executor service for CPU-bound parallel operations</li>
122 	 * <li>Consider async I/O for external service calls</li>
123 	 * <li>Implement appropriate timeouts for long-running operations</li>
124 	 * </ul>
125 	 * 
126 	 * @param executorService the executor service configured in the EA system for parallel operations
127 	 * @param genotypes       the population of genotypes to evaluate
128 	 * @return a CompletableFuture that will complete with fitness values corresponding to each genotype
129 	 * @throws IllegalArgumentException if genotypes is null or empty (implementation-dependent)
130 	 * @throws RuntimeException         if evaluation setup fails (propagated through CompletableFuture)
131 	 */
132 	CompletableFuture<List<T>> compute(final ExecutorService executorService, final List<Genotype> genotypes);
133 }