001 /*
002 * Java Genetic Algorithm Library (jenetics-5.2.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.Arrays;
023 import java.util.Comparator;
024 import java.util.List;
025
026 import io.jenetics.Optimize;
027
028 /**
029 * This interface allows to create vector object from a given array type
030 * {@code T}. It is useful if you need some additional parametrization of the
031 * created vectors.
032 * <p>
033 * As the following example shows, only one {@code VecFactory} instance should
034 * be used for creating the vectors for a given multi-objective <em>problem</em>.
035 * <pre>{@code
036 * private static final VecFactory<double[]> FACTORY = VecFactory.ofDoubleVec(
037 * Optimize.MAXIMUM,
038 * Optimize.MINIMUM,
039 * Optimize.MINIMUM,
040 * Optimize.MAXIMUM
041 * );
042 *
043 * // The fitness function.
044 * static Vec<double[]> fitness(final double[] x) {
045 * final double[] result = new double[4];
046 * // ...
047 * return FACTORY.newVec(result);
048 * }
049 * }</pre>
050 * In the example above, the first dimension of the created vector is maximized,
051 * the following two are minimized and the last vector component is again
052 * maximized.
053 *
054 * @see Vec
055 *
056 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
057 * @version 5.2
058 * @since 5.2
059 */
060 @FunctionalInterface
061 public interface VecFactory<T> {
062
063 /**
064 * Create a new {@link Vec} object from the given {@code array}.
065 *
066 * @param array the array used in the created vector
067 * @return a new {@link Vec} object from the given {@code array}
068 * @throws NullPointerException if the given {@code array} is {@code null}
069 * @throws IllegalArgumentException if the {@code array} length is zero or
070 * doesn't match the required length of the actual factory
071 */
072 Vec<T> newVec(final T array);
073
074 /**
075 * Create a new factory for {@code int[]} vectors. Additionally you can
076 * specify the optimization direction (maximization or minimization) for
077 * each dimension. The dimensionality of the created vectors must be exactly
078 * the same as the given length of the given {@code optimizes}. If the
079 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
080 *
081 * @see #ofIntVec(Optimize...)
082 *
083 * @apiNote
084 * Only one factory instance should be used for a given multi-objective
085 * <em>problem</em>.
086 *
087 * @param optimizes the optimization <em>direction</em> for each dimension
088 * @return a new factory for {@code int[]} vectors
089 * @throws NullPointerException if the given {@code optimizes} is
090 * {@code null}
091 * @throws IllegalArgumentException if the {@code optimizes} length is zero
092 */
093 static VecFactory<int[]> ofIntVec(final List<Optimize> optimizes) {
094 return new GeneralIntVecFactory(optimizes);
095 }
096
097 /**
098 * Create a new factory for {@code int[]} vectors. Additionally you can
099 * specify the optimization direction (maximization or minimization) for
100 * each dimension. The dimensionality of the created vectors must be exactly
101 * the same as the given length of the given {@code optimizes}. If the
102 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
103 *
104 * @see #ofIntVec(List)
105 *
106 * @apiNote
107 * Only one factory instance should be used for a given multi-objective
108 * <em>problem</em>.
109 *
110 * @param optimizes the optimization <em>direction</em> for each dimension
111 * @return a new factory for {@code int[]} vectors
112 * @throws NullPointerException if the given {@code optimizes} is
113 * {@code null}
114 * @throws IllegalArgumentException if the {@code optimizes} length is zero
115 */
116 static VecFactory<int[]> ofIntVec(final Optimize... optimizes) {
117 return ofIntVec(Arrays.asList(optimizes));
118 }
119
120 /**
121 * Create a new factory for {@code int[]} vectors, where all dimensions are
122 * maximized.
123 *
124 * @see Vec#of(int...)
125 *
126 * @return a new factory for {@code int[]} vectors, where all dimensions are
127 * maximized
128 */
129 static VecFactory<int[]> ofIntVec() {
130 return Vec::of;
131 }
132
133 /**
134 * Create a new factory for {@code long[]} vectors. Additionally you can
135 * specify the optimization direction (maximization or minimization) for
136 * each dimension. The dimensionality of the created vectors must be exactly
137 * the same as the given length of the given {@code optimizes}. If the
138 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
139 *
140 * @see #ofLongVec(Optimize...)
141 *
142 * @apiNote
143 * Only one factory instance should be used for a given multi-objective
144 * <em>problem</em>.
145 *
146 * @param optimizes the optimization <em>direction</em> for each dimension
147 * @return a new factory for {@code long[]} vectors
148 * @throws NullPointerException if the given {@code optimizes} is
149 * {@code null}
150 * @throws IllegalArgumentException if the {@code optimizes} length is zero
151 */
152 static VecFactory<long[]> ofLongVec(final List<Optimize> optimizes) {
153 return new GeneralLongVecFactory(optimizes);
154 }
155
156 /**
157 * Create a new factory for {@code long[]} vectors. Additionally you can
158 * specify the optimization direction (maximization or minimization) for
159 * each dimension. The dimensionality of the created vectors must be exactly
160 * the same as the given length of the given {@code optimizes}. If the
161 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
162 *
163 * @see #ofLongVec(List)
164 *
165 * @apiNote
166 * Only one factory instance should be used for a given multi-objective
167 * <em>problem</em>.
168 *
169 * @param optimizes the optimization <em>direction</em> for each dimension
170 * @return a new factory for {@code long[]} vectors
171 * @throws NullPointerException if the given {@code optimizes} is
172 * {@code null}
173 * @throws IllegalArgumentException if the {@code optimizes} length is zero
174 */
175 static VecFactory<long[]> ofLongVec(final Optimize... optimizes) {
176 return ofLongVec(Arrays.asList(optimizes));
177 }
178
179 /**
180 * Create a new factory for {@code long[]} vectors, where all dimensions are
181 * maximized.
182 *
183 * @see Vec#of(long...)
184 *
185 * @return a new factory for {@code long[]} vectors, where all dimensions are
186 * maximized
187 */
188 static VecFactory<long[]> ofLongVec() {
189 return Vec::of;
190 }
191
192 /**
193 * Create a new factory for {@code double[]} vectors. Additionally you can
194 * specify the optimization direction (maximization or minimization) for
195 * each dimension. The dimensionality of the created vectors must be exactly
196 * the same as the given length of the given {@code optimizes}. If the
197 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
198 *
199 * @see #ofDoubleVec(Optimize...)
200 *
201 * @apiNote
202 * Only one factory instance should be used for a given multi-objective
203 * <em>problem</em>.
204 *
205 * @param optimizes the optimization <em>direction</em> for each dimension
206 * @return a new factory for {@code double[]} vectors
207 * @throws NullPointerException if the given {@code optimizes} is
208 * {@code null}
209 * @throws IllegalArgumentException if the {@code optimizes} length is zero
210 */
211 static VecFactory<double[]> ofDoubleVec(final List<Optimize> optimizes) {
212 return new GeneralDoubleVecFactory(optimizes);
213 }
214
215 /**
216 * Create a new factory for {@code double[]} vectors. Additionally you can
217 * specify the optimization direction (maximization or minimization) for
218 * each dimension. The dimensionality of the created vectors must be exactly
219 * the same as the given length of the given {@code optimizes}. If the
220 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
221 *
222 * @see #ofDoubleVec(List)
223 *
224 * @apiNote
225 * Only one factory instance should be used for a given multi-objective
226 * <em>problem</em>.
227 *
228 * @param optimizes the optimization <em>direction</em> for each dimension
229 * @return a new factory for {@code double[]} vectors
230 * @throws NullPointerException if the given {@code optimizes} is
231 * {@code null}
232 * @throws IllegalArgumentException if the {@code optimizes} length is zero
233 */
234 static VecFactory<double[]> ofDoubleVec(final Optimize... optimizes) {
235 return ofDoubleVec(Arrays.asList(optimizes));
236 }
237
238 /**
239 * Create a new factory for {@code double[]} vectors, where all dimensions
240 * are maximized.
241 *
242 * @see Vec#of(double...)
243 *
244 * @return a new factory for {@code double[]} vectors, where all dimensions
245 * are maximized
246 */
247 static VecFactory<double[]> ofDoubleVec() {
248 return Vec::of;
249 }
250
251 /**
252 * Create a new factory for {@code T[]} vectors. Additionally you can
253 * specify the optimization direction (maximization or minimization) for
254 * each dimension. The dimensionality of the created vectors must be exactly
255 * the same as the given length of the given {@code optimizes}. If the
256 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
257 *
258 * @see #ofObjectVec(Comparator, ElementDistance, Optimize...)
259 *
260 * @param comparator the array element comparator
261 * @param distance the element distance function
262 * @param optimizes the optimization <em>direction</em> for each dimension
263 * @param <T> the array element type
264 * @return a new factory for {@code T[]} vectors
265 * @throws NullPointerException if one of the arguments is {@code null}
266 * @throws IllegalArgumentException if the {@code optimizes} length is zero
267 */
268 static <T> VecFactory<T[]> ofObjectVec(
269 final Comparator<? super T> comparator,
270 final ElementDistance<T[]> distance,
271 final List<Optimize> optimizes
272 ) {
273 return new GeneralObjectVecFactory<>(comparator, distance, optimizes);
274 }
275
276 /**
277 * Create a new factory for {@code T[]} vectors. Additionally you can
278 * specify the optimization direction (maximization or minimization) for
279 * each dimension. The dimensionality of the created vectors must be exactly
280 * the same as the given length of the given {@code optimizes}. If the
281 * lengths doesn't match, an {@link IllegalArgumentException} is thrown.
282 *
283 * @see #ofObjectVec(Comparator, ElementDistance, List)
284 *
285 * @param comparator the array element comparator
286 * @param distance the element distance function
287 * @param optimizes the optimization <em>direction</em> for each dimension
288 * @param <T> the array element type
289 * @return a new factory for {@code T[]} vectors
290 * @throws NullPointerException if one of the arguments is {@code null}
291 * @throws IllegalArgumentException if the {@code optimizes} length is zero
292 */
293 static <T> VecFactory<T[]> ofObjectVec(
294 final Comparator<? super T> comparator,
295 final ElementDistance<T[]> distance,
296 final Optimize... optimizes
297 ) {
298 return ofObjectVec(comparator, distance, Arrays.asList(optimizes));
299 }
300
301 }
|