001 /*
002 * Java Genetic Algorithm Library (jenetics-6.3.0).
003 * Copyright (c) 2007-2021 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 static io.jenetics.internal.math.Basics.clamp;
023
024 import java.util.Comparator;
025
026 /**
027 * The {@code Vec} interface represents the fitness result of a multi-objective
028 * fitness function. It also defines a set of static factory methods which
029 * allows you to create {@code Vec} instance from a given {@code int[]},
030 * {@code long[]} or {@code double[]} array.
031 *
032 * <pre>{@code
033 * final Vec<double[]> point2D = Vec.of(0.1, 5.4);
034 * final Vec<int[]> point3D = Vec.of(1, 2, 3);
035 * }</pre>
036 *
037 * The underlying array is <em>just</em> wrapped and <em>not</em> copied. This
038 * means you can change the values of the {@code Vec} once it is created,
039 * <em>Not copying the underlying array is done for performance reason. Changing
040 * the {@code Vec} data is, of course, never a good idea.</em>
041 *
042 * @implNote
043 * Although the {@code Vec} interface extends the {@link Comparable} interface,
044 * it violates its <em>general</em> contract. It <em>only</em>
045 * implements the pareto <em>dominance</em> relation, which defines a partial
046 * order. So, trying to sort a list of {@code Vec} objects, might lead
047 * to an exception (thrown by the sorting method) at runtime.
048 *
049 * @param <T> the underlying array type, like {@code int[]} or {@code double[]}
050 *
051 * @see VecFactory
052 * @see <a href="https://en.wikipedia.org/wiki/Pareto_efficiency">
053 * Pareto efficiency</a>
054 *
055 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
056 * @version 4.1
057 * @since 4.1
058 */
059 public interface Vec<T> extends Comparable<Vec<T>> {
060
061 /**
062 * Return the underlying data structure.
063 *
064 * @return the underlying data structure
065 */
066 T data();
067
068 /**
069 * Return the number of vector elements.
070 *
071 * @return the number of vector elements
072 */
073 int length();
074
075 /**
076 * Return the comparator for comparing the elements of this MO vector.
077 *
078 * @return the comparator for comparing the elements of this MO vector
079 */
080 ElementComparator<T> comparator();
081
082 /**
083 * Return a function which calculates the element distance of a vector at a
084 * given element index.
085 *
086 * @return a function which calculates the element distance of a vector at a
087 * given element index
088 */
089 ElementDistance<T> distance();
090
091 /**
092 * Return the comparator which defines the (Pareto) dominance measure.
093 *
094 * @return the comparator which defines the (Pareto) dominance measure
095 */
096 Comparator<T> dominance();
097
098
099 /* *************************************************************************
100 * Default methods derived from the methods above.
101 * ************************************************************************/
102
103 /**
104 * Compares the {@code this} vector with the {@code other} at the given
105 * component {@code index}.
106 *
107 * @param other the other vector
108 * @param index the component index
109 * @return a negative integer, zero, or a positive integer as
110 * {@code this[index]} is less than, equal to, or greater than
111 * {@code other[index]}
112 * @throws NullPointerException if the {@code other} object is {@code null}
113 * @throws IllegalArgumentException if the {@code index} is out of the valid
114 * range {@code [0, length())}
115 */
116 default int compare(final Vec<T> other, final int index) {
117 return comparator().compare(data(), other.data(), index);
118 }
119
120 /**
121 * Calculates the distance between two vector elements at the given
122 * {@code index}.
123 *
124 * @param other the second vector
125 * @param index the vector element index
126 * @return the distance between two vector elements
127 * @throws NullPointerException if the {@code other} vector is {@code null}
128 * @throws IllegalArgumentException if the {@code index} is out of the valid
129 * range {@code [0, length())}
130 */
131 default double distance(final Vec<T> other, final int index) {
132 return distance().distance(data(), other.data(), index);
133 }
134
135 /**
136 * Calculates the <a href="https://en.wikipedia.org/wiki/Pareto_efficiency">
137 * <b>Pareto Dominance</b></a> of vector {@code value()} and {@code other}.
138 *
139 * @param other the other vector
140 * @return {@code 1} if <b>value()</b> ≻ <b>other</b>, {@code -1} if
141 * <b>other</b> ≻ <b>value()</b> and {@code 0} otherwise
142 * @throws NullPointerException if the {@code other} vector is {@code null}
143 */
144 default int dominance(final Vec<T> other) {
145 return dominance().compare(data(), other.data());
146 }
147
148 /**
149 * The default implementation uses the {@link #dominance(Vec)} function
150 * for defining a <b>partial</b> order of two vectors.
151 *
152 * @param other the other vector
153 * @return {@code 1} if <b>value()</b> ≻ <b>other</b>, {@code -1} if
154 * <b>other</b> ≻ <b>value()</b> and {@code 0} otherwise
155 * @throws NullPointerException if the {@code other} vector is {@code null}
156 */
157 @Override
158 default int compareTo(final Vec<T> other) {
159 return dominance(other);
160 }
161
162
163 /* *************************************************************************
164 * Common 'dominance' methods.
165 * ************************************************************************/
166
167 /**
168 * Calculates the <a href="https://en.wikipedia.org/wiki/Pareto_efficiency">
169 * <b>Pareto Dominance</b></a> of the two vectors <b>u</b> and <b>v</b>.
170 *
171 * @see Pareto#dominance(Comparable[], Comparable[])
172 *
173 * @param u the first vector
174 * @param v the second vector
175 * @param <C> the element type of vector <b>u</b> and <b>v</b>
176 * @return {@code 1} if <b>u</b> ≻ <b>v</b>, {@code -1} if <b>v</b> ≻
177 * <b>u</b> and {@code 0} otherwise
178 * @throws NullPointerException if one of the arguments is {@code null}
179 * @throws IllegalArgumentException if {@code u.length != v.length}
180 */
181 static <C extends Comparable<? super C>> int
182 dominance(final C[] u, final C[] v) {
183 return dominance(u, v, Comparator.naturalOrder());
184 }
185
186 /**
187 * Calculates the <a href="https://en.wikipedia.org/wiki/Pareto_efficiency">
188 * <b>Pareto Dominance</b></a> of the two vectors <b>u</b> and <b>v</b>.
189 *
190 * @see Pareto#dominance(Object[], Object[], Comparator)
191 *
192 * @param u the first vector
193 * @param v the second vector
194 * @param comparator the element comparator which is used for calculating
195 * the dominance
196 * @param <T> the element type of vector <b>u</b> and <b>v</b>
197 * @return {@code 1} if <b>u</b> ≻ <b>v</b>, {@code -1} if <b>v</b> ≻
198 * <b>u</b> and {@code 0} otherwise
199 * @throws NullPointerException if one of the arguments is {@code null}
200 * @throws IllegalArgumentException if {@code u.length != v.length}
201 */
202 static <T> int
203 dominance(final T[] u, final T[] v, final Comparator<? super T> comparator) {
204 return Pareto.dominance(u, v, comparator);
205 }
206
207 /**
208 * Calculates the <a href="https://en.wikipedia.org/wiki/Pareto_efficiency">
209 * <b>Pareto Dominance</b></a> of the two vectors <b>u</b> and <b>v</b>.
210 *
211 * @see Pareto#dominance(int[], int[])
212 *
213 * @param u the first vector
214 * @param v the second vector
215 * @return {@code 1} if <b>u</b> ≻ <b>v</b>, {@code -1} if <b>v</b> ≻
216 * <b>u</b> and {@code 0} otherwise
217 * @throws NullPointerException if one of the arguments is {@code null}
218 * @throws IllegalArgumentException if {@code u.length != v.length}
219 */
220 static int dominance(final int[] u, final int[] v) {
221 return Pareto.dominance(u, v);
222 }
223
224 /**
225 * Calculates the <a href="https://en.wikipedia.org/wiki/Pareto_efficiency">
226 * <b>Pareto Dominance</b></a> of the two vectors <b>u</b> and <b>v</b>.
227 *
228 * @see Pareto#dominance(long[], long[])
229 *
230 * @param u the first vector
231 * @param v the second vector
232 * @return {@code 1} if <b>u</b> ≻ <b>v</b>, {@code -1} if <b>v</b> ≻
233 * <b>u</b> and {@code 0} otherwise
234 * @throws NullPointerException if one of the arguments is {@code null}
235 * @throws IllegalArgumentException if {@code u.length != v.length}
236 */
237 static int dominance(final long[] u, final long[] v) {
238 return Pareto.dominance(u, v);
239 }
240
241 /**
242 * Calculates the <a href="https://en.wikipedia.org/wiki/Pareto_efficiency">
243 * <b>Pareto Dominance</b></a> of the two vectors <b>u</b> and <b>v</b>.
244 *
245 * @see Pareto#dominance(double[], double[])
246 *
247 * @param u the first vector
248 * @param v the second vector
249 * @return {@code 1} if <b>u</b> ≻ <b>v</b>, {@code -1} if <b>v</b> ≻
250 * <b>u</b> and {@code 0} otherwise
251 * @throws NullPointerException if one of the arguments is {@code null}
252 * @throws IllegalArgumentException if {@code u.length != v.length}
253 */
254 static int dominance(final double[] u, final double[] v) {
255 return Pareto.dominance(u, v);
256 }
257
258 /* *************************************************************************
259 * Static factory functions for wrapping ordinary arrays.
260 * ************************************************************************/
261
262 /**
263 * Wraps the given array into a {@code Vec} object.
264 *
265 * @param array the wrapped array
266 * @param <C> the array element type
267 * @return the given array wrapped into a {@code Vec} object.
268 * @throws NullPointerException if one of the arguments is {@code null}
269 * @throws IllegalArgumentException if the {@code array} length is zero
270 */
271 static <C extends Comparable<? super C>>
272 Vec<C[]> of(final C[] array) {
273 return of(
274 array,
275 (u, v, i) -> clamp(u[i].compareTo(v[i]), -1, 1)
276 );
277 }
278
279 /**
280 * Wraps the given array into a {@code Vec} object.
281 *
282 * @param array the wrapped array
283 * @param distance the array element distance measure
284 * @param <C> the array element type
285 * @return the given array wrapped into a {@code Vec} object.
286 * @throws NullPointerException if one of the arguments is {@code null}
287 * @throws IllegalArgumentException if the {@code array} length is zero
288 */
289 static <C extends Comparable<? super C>> Vec<C[]> of(
290 final C[] array,
291 final ElementDistance<C[]> distance
292 ) {
293 return of(array, Comparator.naturalOrder(), distance);
294 }
295
296 /**
297 * Wraps the given array into a {@code Vec} object.
298 *
299 * @param array the wrapped array
300 * @param comparator the (natural order) comparator of the array elements
301 * @param distance the distance function between two vector elements
302 * @param <T> the array element type
303 * @return the given array wrapped into a {@code Vec} object.
304 * @throws NullPointerException if one of the arguments is {@code null}
305 * @throws IllegalArgumentException if the {@code array} length is zero
306 */
307 static <T> Vec<T[]> of(
308 final T[] array,
309 final Comparator<? super T> comparator,
310 final ElementDistance<T[]> distance
311 ) {
312 return new SimpleObjectVec<>(array, comparator, distance);
313 }
314
315 /**
316 * Wraps the given array into a {@code Vec} object.
317 *
318 * @param array the wrapped array
319 * @return the given array wrapped into a {@code Vec} object.
320 * @throws NullPointerException if the given {@code array} is {@code null}
321 * @throws IllegalArgumentException if the {@code array} length is zero
322 */
323 static Vec<int[]> of(final int... array) {
324 return new SimpleIntVec(array);
325 }
326
327 /**
328 * Wraps the given array into a {@code Vec} object.
329 *
330 * @param array the wrapped array
331 * @return the given array wrapped into a {@code Vec} object.
332 * @throws NullPointerException if the given {@code array} is {@code null}
333 * @throws IllegalArgumentException if the {@code array} length is zero
334 */
335 static Vec<long[]> of(final long... array) {
336 return new SimpleLongVec(array);
337 }
338
339 /**
340 * Wraps the given array into a {@code Vec} object.
341 *
342 * @param array the wrapped array
343 * @return the given array wrapped into a {@code Vec} object.
344 * @throws NullPointerException if the given {@code array} is {@code null}
345 * @throws IllegalArgumentException if the {@code array} length is zero
346 */
347 static Vec<double[]> of(final double... array) {
348 return new SimpleDoubleVec(array);
349 }
350
351 }
|