001 /*
002 * Java Genetic Algorithm Library (jenetics-6.0.0).
003 * Copyright (c) 2007-2020 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 */
020 package io.jenetics.ext.moea;
021
022 import java.util.Comparator;
023 import java.util.List;
024
025 import io.jenetics.Optimize;
026
027 /**
028 * This interface allows to create vector object from a given array type
029 * {@code T}. It is useful if you need some additional parametrization of the
030 * created vectors.
031 * <p>
032 * As the following example shows, only one {@code VecFactory} instance should
033 * be used for creating the vectors for a given multi-objective <em>problem</em>.
034 * <pre>{@code
035 * private static final VecFactory<double[]> FACTORY = VecFactory.ofDoubleVec(
036 * Optimize.MAXIMUM,
037 * Optimize.MINIMUM,
038 * Optimize.MINIMUM,
039 * Optimize.MAXIMUM
040 * );
041 *
042 * // The fitness function.
043 * static Vec<double[]> fitness(final double[] x) {
044 * final double[] result = new double[4];
045 * // ...
046 * return FACTORY.newVec(result);
047 * }
048 * }</pre>
049 * In the example above, the first dimension of the created vector is maximized,
050 * the following two are minimized and the last vector component is again
051 * maximized.
052 *
053 * @see Vec
054 *
055 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
056 * @version 6.0
057 * @since 5.2
058 */
059 @FunctionalInterface
060 public interface VecFactory<T> {
061
062 /**
063 * Create a new {@link Vec} object from the given {@code array}.
064 *
065 * @param array the array used in the created vector
066 * @return a new {@link Vec} object from the given {@code array}
067 * @throws NullPointerException if the given {@code array} is {@code null}
068 * @throws IllegalArgumentException if the {@code array} length is zero or
069 * doesn't match the required length of the actual factory
070 */
071 Vec<T> newVec(final T array);
072
073 /**
074 * Create a new factory for {@code int[]} vectors. Additionally you can
075 * specify the optimization direction (maximization or minimization) for
076 * each dimension. The dimensionality of the created vectors must be exactly
077 * the same as the given length of the given {@code optimizes}. If the
078 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
079 *
080 * @see #ofIntVec(Optimize...)
081 *
082 * @apiNote
083 * Only one factory instance should be used for a given multi-objective
084 * <em>problem</em>.
085 *
086 * @param optimizes the optimization <em>direction</em> for each dimension
087 * @return a new factory for {@code int[]} vectors
088 * @throws NullPointerException if the given {@code optimizes} is
089 * {@code null}
090 * @throws IllegalArgumentException if the {@code optimizes} length is zero
091 */
092 static VecFactory<int[]> ofIntVec(final List<Optimize> optimizes) {
093 return new GeneralIntVecFactory(optimizes);
094 }
095
096 /**
097 * Create a new factory for {@code int[]} vectors. Additionally you can
098 * specify the optimization direction (maximization or minimization) for
099 * each dimension. The dimensionality of the created vectors must be exactly
100 * the same as the given length of the given {@code optimizes}. If the
101 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
102 *
103 * @see #ofIntVec(List)
104 *
105 * @apiNote
106 * Only one factory instance should be used for a given multi-objective
107 * <em>problem</em>.
108 *
109 * @param optimizes the optimization <em>direction</em> for each dimension
110 * @return a new factory for {@code int[]} vectors
111 * @throws NullPointerException if the given {@code optimizes} is
112 * {@code null}
113 * @throws IllegalArgumentException if the {@code optimizes} length is zero
114 */
115 static VecFactory<int[]> ofIntVec(final Optimize... optimizes) {
116 return ofIntVec(List.of(optimizes));
117 }
118
119 /**
120 * Create a new factory for {@code int[]} vectors, where all dimensions are
121 * maximized.
122 *
123 * @see Vec#of(int...)
124 *
125 * @return a new factory for {@code int[]} vectors, where all dimensions are
126 * maximized
127 */
128 static VecFactory<int[]> ofIntVec() {
129 return Vec::of;
130 }
131
132 /**
133 * Create a new factory for {@code long[]} vectors. Additionally you can
134 * specify the optimization direction (maximization or minimization) for
135 * each dimension. The dimensionality of the created vectors must be exactly
136 * the same as the given length of the given {@code optimizes}. If the
137 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
138 *
139 * @see #ofLongVec(Optimize...)
140 *
141 * @apiNote
142 * Only one factory instance should be used for a given multi-objective
143 * <em>problem</em>.
144 *
145 * @param optimizes the optimization <em>direction</em> for each dimension
146 * @return a new factory for {@code long[]} vectors
147 * @throws NullPointerException if the given {@code optimizes} is
148 * {@code null}
149 * @throws IllegalArgumentException if the {@code optimizes} length is zero
150 */
151 static VecFactory<long[]> ofLongVec(final List<Optimize> optimizes) {
152 return new GeneralLongVecFactory(optimizes);
153 }
154
155 /**
156 * Create a new factory for {@code long[]} vectors. Additionally you can
157 * specify the optimization direction (maximization or minimization) for
158 * each dimension. The dimensionality of the created vectors must be exactly
159 * the same as the given length of the given {@code optimizes}. If the
160 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
161 *
162 * @see #ofLongVec(List)
163 *
164 * @apiNote
165 * Only one factory instance should be used for a given multi-objective
166 * <em>problem</em>.
167 *
168 * @param optimizes the optimization <em>direction</em> for each dimension
169 * @return a new factory for {@code long[]} vectors
170 * @throws NullPointerException if the given {@code optimizes} is
171 * {@code null}
172 * @throws IllegalArgumentException if the {@code optimizes} length is zero
173 */
174 static VecFactory<long[]> ofLongVec(final Optimize... optimizes) {
175 return ofLongVec(List.of(optimizes));
176 }
177
178 /**
179 * Create a new factory for {@code long[]} vectors, where all dimensions are
180 * maximized.
181 *
182 * @see Vec#of(long...)
183 *
184 * @return a new factory for {@code long[]} vectors, where all dimensions are
185 * maximized
186 */
187 static VecFactory<long[]> ofLongVec() {
188 return Vec::of;
189 }
190
191 /**
192 * Create a new factory for {@code double[]} vectors. Additionally you can
193 * specify the optimization direction (maximization or minimization) for
194 * each dimension. The dimensionality of the created vectors must be exactly
195 * the same as the given length of the given {@code optimizes}. If the
196 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
197 *
198 * @see #ofDoubleVec(Optimize...)
199 *
200 * @apiNote
201 * Only one factory instance should be used for a given multi-objective
202 * <em>problem</em>.
203 *
204 * @param optimizes the optimization <em>direction</em> for each dimension
205 * @return a new factory for {@code double[]} vectors
206 * @throws NullPointerException if the given {@code optimizes} is
207 * {@code null}
208 * @throws IllegalArgumentException if the {@code optimizes} length is zero
209 */
210 static VecFactory<double[]> ofDoubleVec(final List<Optimize> optimizes) {
211 return new GeneralDoubleVecFactory(optimizes);
212 }
213
214 /**
215 * Create a new factory for {@code double[]} vectors. Additionally you can
216 * specify the optimization direction (maximization or minimization) for
217 * each dimension. The dimensionality of the created vectors must be exactly
218 * the same as the given length of the given {@code optimizes}. If the
219 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
220 *
221 * @see #ofDoubleVec(List)
222 *
223 * @apiNote
224 * Only one factory instance should be used for a given multi-objective
225 * <em>problem</em>.
226 *
227 * @param optimizes the optimization <em>direction</em> for each dimension
228 * @return a new factory for {@code double[]} vectors
229 * @throws NullPointerException if the given {@code optimizes} is
230 * {@code null}
231 * @throws IllegalArgumentException if the {@code optimizes} length is zero
232 */
233 static VecFactory<double[]> ofDoubleVec(final Optimize... optimizes) {
234 return ofDoubleVec(List.of(optimizes));
235 }
236
237 /**
238 * Create a new factory for {@code double[]} vectors, where all dimensions
239 * are maximized.
240 *
241 * @see Vec#of(double...)
242 *
243 * @return a new factory for {@code double[]} vectors, where all dimensions
244 * are maximized
245 */
246 static VecFactory<double[]> ofDoubleVec() {
247 return Vec::of;
248 }
249
250 /**
251 * Create a new factory for {@code T[]} vectors. Additionally you can
252 * specify the optimization direction (maximization or minimization) for
253 * each dimension. The dimensionality of the created vectors must be exactly
254 * the same as the given length of the given {@code optimizes}. If the
255 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
256 *
257 * @see #ofObjectVec(Comparator, ElementDistance, Optimize...)
258 *
259 * @param comparator the array element comparator
260 * @param distance the element distance function
261 * @param optimizes the optimization <em>direction</em> for each dimension
262 * @param <T> the array element type
263 * @return a new factory for {@code T[]} vectors
264 * @throws NullPointerException if one of the arguments is {@code null}
265 * @throws IllegalArgumentException if the {@code optimizes} length is zero
266 */
267 static <T> VecFactory<T[]> ofObjectVec(
268 final Comparator<? super T> comparator,
269 final ElementDistance<T[]> distance,
270 final List<Optimize> optimizes
271 ) {
272 return new GeneralObjectVecFactory<>(comparator, distance, optimizes);
273 }
274
275 /**
276 * Create a new factory for {@code T[]} vectors. Additionally you can
277 * specify the optimization direction (maximization or minimization) for
278 * each dimension. The dimensionality of the created vectors must be exactly
279 * the same as the given length of the given {@code optimizes}. If the
280 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
281 *
282 * @see #ofObjectVec(Comparator, ElementDistance, List)
283 *
284 * @param comparator the array element comparator
285 * @param distance the element distance function
286 * @param optimizes the optimization <em>direction</em> for each dimension
287 * @param <T> the array element type
288 * @return a new factory for {@code T[]} vectors
289 * @throws NullPointerException if one of the arguments is {@code null}
290 * @throws IllegalArgumentException if the {@code optimizes} length is zero
291 */
292 static <T> VecFactory<T[]> ofObjectVec(
293 final Comparator<? super T> comparator,
294 final ElementDistance<T[]> distance,
295 final Optimize... optimizes
296 ) {
297 return ofObjectVec(comparator, distance, List.of(optimizes));
298 }
299
300 /**
301 * Create a new factory for {@code T[]} vectors with comparable element
302 * types. Additionally you can specify the optimization direction
303 * (maximization or minimization) for each dimension. The dimensionality of
304 * the created vectors must be exactly the same as the given length of the
305 * given {@code optimizes}. If the lengths doesn't match, an
306 * {@link IllegalArgumentException} is thrown.
307 *
308 * @since 6.0
309 *
310 * @see #ofObjectVec(Comparator, ElementDistance, List)
311 *
312 * @param distance the element distance function
313 * @param optimizes the optimization <em>direction</em> for each dimension
314 * @param <T> the array element type
315 * @return a new factory for {@code T[]} vectors
316 * @throws NullPointerException if one of the arguments is {@code null}
317 * @throws IllegalArgumentException if the {@code optimizes} length is zero
318 */
319 static <T extends Comparable<? super T>> VecFactory<T[]> ofObjectVec(
320 final ElementDistance<T[]> distance,
321 final List<Optimize> optimizes
322 ) {
323 return ofObjectVec(
324 Comparator.naturalOrder(),
325 distance,
326 optimizes
327 );
328 }
329
330 /**
331 * Create a new factory for {@code T[]} vectors with comparable element
332 * types. Additionally you can specify the optimization direction
333 * (maximization or minimization) for each dimension. The dimensionality of
334 * the created vectors must be exactly the same as the given length of the
335 * given {@code optimizes}. If the lengths doesn't match, an
336 * {@link IllegalArgumentException} is thrown.
337 *
338 * @since 6.0
339 *
340 * @see #ofObjectVec(Comparator, ElementDistance, List)
341 *
342 * @param distance the element distance function
343 * @param optimizes the optimization <em>direction</em> for each dimension
344 * @param <T> the array element type
345 * @return a new factory for {@code T[]} vectors
346 * @throws NullPointerException if one of the arguments is {@code null}
347 * @throws IllegalArgumentException if the {@code optimizes} length is zero
348 */
349 static <T extends Comparable<? super T>> VecFactory<T[]> ofObjectVec(
350 final ElementDistance<T[]> distance,
351 final Optimize... optimizes
352 ) {
353 return ofObjectVec(
354 Comparator.naturalOrder(),
355 distance,
356 optimizes
357 );
358 }
359
360 /**
361 * Create a new factory for {@code T[]} vectors with comparable element
362 * types. Additionally you can specify the optimization direction
363 * (maximization or minimization) for each dimension. The dimensionality of
364 * the created vectors must be exactly the same as the given length of the
365 * given {@code optimizes}. If the lengths doesn't match, an
366 * {@link IllegalArgumentException} is thrown.
367 *
368 * @since 6.0
369 *
370 * @see #ofObjectVec(Comparator, ElementDistance, List)
371 *
372 * @param optimizes the optimization <em>direction</em> for each dimension
373 * @param <T> the array element type
374 * @return a new factory for {@code T[]} vectors
375 * @throws NullPointerException if one of the arguments is {@code null}
376 * @throws IllegalArgumentException if the {@code optimizes} length is zero
377 */
378 static <T extends Comparable<? super T>> VecFactory<T[]>
379 ofObjectVec(final List<Optimize> optimizes) {
380 return ofObjectVec(VecFactory::dist, optimizes);
381 }
382
383 private static <T extends Comparable<? super T>>
384 double dist(final T[] u, final T[] v, final int i) {
385 return Integer.compare(u[i].compareTo(v[i]), 0);
386 }
387
388 /**
389 * Create a new factory for {@code T[]} vectors with comparable element
390 * types. Additionally you can specify the optimization direction
391 * (maximization or minimization) for each dimension. The dimensionality of
392 * the created vectors must be exactly the same as the given length of the
393 * given {@code optimizes}. If the lengths doesn't match, an
394 * {@link IllegalArgumentException} is thrown.
395 *
396 * @since 6.0
397 *
398 * @see #ofObjectVec(Comparator, ElementDistance, List)
399 *
400 * @param optimizes the optimization <em>direction</em> for each dimension
401 * @param <T> the array element type
402 * @return a new factory for {@code T[]} vectors
403 * @throws NullPointerException if one of the arguments is {@code null}
404 * @throws IllegalArgumentException if the {@code optimizes} length is zero
405 */
406 static <T extends Comparable<? super T>> VecFactory<T[]>
407 ofObjectVec(final Optimize... optimizes) {
408 return ofObjectVec(VecFactory::dist, optimizes);
409 }
410
411 /**
412 * Create a new factory for {@code T[]} vectors with comparable element
413 * types. Additionally you can specify the optimization direction
414 * (maximization or minimization) for each dimension. The dimensionality of
415 * the created vectors must be exactly the same as the given length of the
416 * given {@code optimizes}. If the lengths doesn't match, an
417 * {@link IllegalArgumentException} is thrown.
418 *
419 * @since 6.0
420 *
421 * @see Vec#of(Comparable[])
422 *
423 * @param <T> the array element type
424 * @return a new factory for {@code T[]} vectors
425 * @throws NullPointerException if one of the arguments is {@code null}
426 * @throws IllegalArgumentException if the {@code optimizes} length is zero
427 */
428 static <T extends Comparable<? super T>> VecFactory<T[]> ofObjectVec() {
429 return Vec::of;
430 }
431
432 }
|