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}