001/*
002 * Java Genetic Algorithm Library (jenetics-7.2.0).
003 * Copyright (c) 2007-2023 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019 */
020package io.jenetics.engine;
021
022import java.util.concurrent.CompletableFuture;
023import java.util.concurrent.Executor;
024import java.util.concurrent.Future;
025import java.util.function.Function;
026
027import io.jenetics.Gene;
028import io.jenetics.Genotype;
029
030/**
031 * This class contains factory methods for creating commonly usable
032 * {@link Evaluator} implementations. By default, the evolution {@link Engine}
033 * uses the {@code concurrent} evaluators ({@link #concurrent(Function, Executor)}).
034 *
035 * @see Evaluator
036 *
037 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
038 * @version 5.0
039 * @since 5.0
040 */
041public final class Evaluators {
042        private Evaluators() {}
043
044        /**
045         * Return a new fitness evaluator, which evaluates the fitness function of
046         * the population serially in the main thread. Might be useful for testing
047         * purpose.
048         *
049         * @param fitness the fitness function
050         * @param <G> the gene type
051         * @param <C> the fitness value type
052         * @return a new serial fitness evaluator
053         * @throws NullPointerException if the fitness {@code function} is {@code null}
054         */
055        public static <G extends Gene<?, G>, C extends Comparable<? super C>>
056        Evaluator<G, C>
057        serial(final Function<? super Genotype<G>, ? extends C> fitness) {
058                return concurrent(fitness, Runnable::run);
059        }
060
061        /**
062         * Return a new fitness evaluator, which evaluates the fitness function of
063         * the population serially in the main thread. Might be useful for testing
064         * purpose.
065         *
066         * @param fitness the fitness function
067         * @param decoder the decoder function for the fitness domain
068         * @param <T> the <em>native</em> fitness domain type
069         * @param <G> the gene type
070         * @param <C> the fitness value type
071         * @return a new (concurrent) fitness evaluator
072         * @throws NullPointerException if one of the arguments is {@code null}
073         */
074        public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
075        Evaluator<G, C> serial(
076                final Function<? super T, ? extends C> fitness,
077                final Function<? super Genotype<G>, ? extends T> decoder
078        ) {
079                return serial(fitness.compose(decoder));
080        }
081
082        /**
083         * Return a new fitness evaluator, which evaluates the fitness function of
084         * the population serially in the main thread. Might be useful for testing
085         * purpose.
086         *
087         * @param fitness the fitness function
088         * @param codec the codec used for transforming the fitness domain
089         * @param <T> the <em>native</em> fitness domain type
090         * @param <G> the gene type
091         * @param <C> the fitness value type
092         * @return a new (concurrent) fitness evaluator
093         * @throws NullPointerException if one of the arguments is {@code null}
094         */
095        public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
096        Evaluator<G, C> serial(
097                final Function<? super T, ? extends C> fitness,
098                final Codec<T, G> codec
099        ) {
100                return serial(fitness.compose(codec.decoder()));
101        }
102
103        /**
104         * Return a new fitness evaluator, which evaluates the fitness function of
105         * the population (concurrently) with the given {@code executor}. This is
106         * the default evaluator used by the evolution engine.
107         *
108         * @param fitness the fitness function
109         * @param executor the {@code Executor} used for evaluating the fitness
110         *        function
111         * @param <G> the gene type
112         * @param <C> the fitness value type
113         * @return a new (concurrent) fitness evaluator
114         * @throws NullPointerException if one of the arguments is {@code null}
115         */
116        public static <G extends Gene<?, G>, C extends Comparable<? super C>>
117        Evaluator<G, C> concurrent(
118                final Function<? super Genotype<G>, ? extends C> fitness,
119                final Executor executor
120        ) {
121                return new ConcurrentEvaluator<>(fitness, executor);
122        }
123
124        /**
125         * Return a new fitness evaluator, which evaluates the fitness function of
126         * the population (concurrently) with the given {@code executor}. This is
127         * the default evaluator used by the evolution engine.
128         *
129         * @param fitness the fitness function, working on the <em>native</em>
130         *        fitness domain
131         * @param decoder the decoder function for the fitness domain
132         * @param executor the {@code Executor} used for evaluating the fitness
133         *        function
134         * @param <T> the <em>native</em> fitness domain type
135         * @param <G> the gene type
136         * @param <C> the fitness value type
137         * @return a new (concurrent) fitness evaluator
138         * @throws NullPointerException if one of the arguments is {@code null}
139         */
140        public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
141        Evaluator<G, C> concurrent(
142                final Function<? super T, ? extends C> fitness,
143                final Function<? super Genotype<G>, ? extends T> decoder,
144                final Executor executor
145        ) {
146                return concurrent(fitness.compose(decoder), executor);
147        }
148
149        /**
150         * Return a new fitness evaluator, which evaluates the fitness function of
151         * the population (concurrently) with the given {@code executor}. This is
152         * the default evaluator used by the evolution engine.
153         *
154         * @param fitness the fitness function, working on the <em>native</em>
155         *        fitness domain
156         * @param codec the codec used for transforming the fitness domain
157         * @param executor the {@code Executor} used for evaluating the fitness
158         *        function
159         * @param <T> the <em>native</em> fitness domain type
160         * @param <G> the gene type
161         * @param <C> the fitness value type
162         * @return a new (concurrent) fitness evaluator
163         * @throws NullPointerException if one of the arguments is {@code null}
164         */
165        public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
166        Evaluator<G, C> concurrent(
167                final Function<? super T, ? extends C> fitness,
168                final Codec<T, G> codec,
169                final Executor executor
170        ) {
171                return concurrent(fitness, codec.decoder(), executor);
172        }
173
174        /**
175         * Return a new fitness evaluator, which evaluates <em>asynchronous</em>
176         * fitness functions.
177         *
178         * @see #completable(Function)
179         *
180         * @param fitness the asynchronous fitness function
181         * @param <G> the gene type
182         * @param <C> the fitness value type
183         * @return a new (asynchronous) fitness evaluator
184         * @throws NullPointerException if one of the arguments is {@code null}
185         */
186        public static <G extends Gene<?, G>, C extends Comparable<? super C>>
187        Evaluator<G, C>
188        async(final Function<? super Genotype<G>, ? extends Future<C>> fitness) {
189                return new FutureEvaluator<>(fitness);
190        }
191
192        /**
193         * Return a new fitness evaluator, which evaluates <em>asynchronous</em>
194         * fitness functions.
195         *
196         * @param fitness the asynchronous fitness function, working on the
197         *        <em>native</em> fitness domain
198         * @param decoder the decoder function for the fitness domain
199         * @param <T> the <em>native</em> fitness domain type
200         * @param <G> the gene type
201         * @param <C> the fitness value type
202         * @return a new (async) fitness evaluator
203         * @throws NullPointerException if one of the arguments is {@code null}
204         */
205        public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
206        Evaluator<G, C> async(
207                final Function<? super T, ? extends Future<C>> fitness,
208                final Function<? super Genotype<G>, ? extends T> decoder
209        ) {
210                return async(fitness.compose(decoder));
211        }
212
213        /**
214         * Return a new fitness evaluator, which evaluates <em>asynchronous</em>
215         * fitness functions.
216         *
217         * @param fitness the asynchronous fitness function, working on the
218         *        <em>native</em> fitness domain
219         * @param codec the codec used for transforming the fitness domain
220         * @param <T> the <em>native</em> fitness domain type
221         * @param <G> the gene type
222         * @param <C> the fitness value type
223         * @return a new (async) fitness evaluator
224         * @throws NullPointerException if one of the arguments is {@code null}
225         */
226        public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
227        Evaluator<G, C> async(
228                final Function<? super T, ? extends Future<C>> fitness,
229                final Codec<T, G> codec
230        ) {
231                return async(fitness, codec.decoder());
232        }
233
234        /**
235         * Return a new fitness evaluator, which evaluates <em>asynchronous</em>
236         * fitness functions.
237         *
238         * @see #async(Function)
239         *
240         * @param fitness the asynchronous fitness function
241         * @param <G> the gene type
242         * @param <C> the fitness value type
243         * @return a new (asynchronous) fitness evaluator
244         * @throws NullPointerException if one of the arguments is {@code null}
245         */
246        public static <G extends Gene<?, G>, C extends Comparable<? super C>>
247        Evaluator<G, C>
248        completable(
249                final Function<
250                        ? super Genotype<G>,
251                        ? extends CompletableFuture<C>> fitness
252        ) {
253                return new CompletableFutureEvaluator<>(fitness);
254        }
255
256        /**
257         * Return a new fitness evaluator, which evaluates <em>asynchronous</em>
258         * fitness functions.
259         *
260         * @param fitness the asynchronous fitness function, working on the
261         *        <em>native</em> fitness domain
262         * @param decoder the decoder function for the fitness domain
263         * @param <T> the <em>native</em> fitness domain type
264         * @param <G> the gene type
265         * @param <C> the fitness value type
266         * @return a new (async) fitness evaluator
267         * @throws NullPointerException if one of the arguments is {@code null}
268         */
269        public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
270        Evaluator<G, C> completable(
271                final Function<? super T, ? extends CompletableFuture<C>> fitness,
272                final Function<? super Genotype<G>, ? extends T> decoder
273        ) {
274                return completable(fitness.compose(decoder));
275        }
276
277        /**
278         * Return a new fitness evaluator, which evaluates <em>asynchronous</em>
279         * fitness functions.
280         *
281         * @param fitness the asynchronous fitness function, working on the
282         *        <em>native</em> fitness domain
283         * @param codec the codec used for transforming the fitness domain
284         * @param <T> the <em>native</em> fitness domain type
285         * @param <G> the gene type
286         * @param <C> the fitness value type
287         * @return a new (async) fitness evaluator
288         * @throws NullPointerException if one of the arguments is {@code null}
289         */
290        public static <T, G extends Gene<?, G>, C extends Comparable<? super C>>
291        Evaluator<G, C> completable(
292                final Function<? super T, ? extends CompletableFuture<C>> fitness,
293                final Codec<T, G> codec
294        ) {
295                return completable(fitness, codec.decoder());
296        }
297
298}