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