Optimize.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-6.2.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;
021 
022 import java.util.Comparator;
023 import java.util.function.BinaryOperator;
024 
025 /**
026  * This {@code enum} determines whether the GA should maximize or minimize the
027  * fitness function.
028  *
029  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
030  @since 1.0
031  @version 6.2
032  */
033 public enum Optimize {
034 
035     /**
036      * GA minimization
037      */
038     MINIMUM {
039         @Override
040         public <T extends Comparable<? super T>>
041         int compare(final T a, final T b) {
042             return b.compareTo(a);
043         }
044     },
045 
046     /**
047      * GA maximization
048      */
049     MAXIMUM {
050         @Override
051         public <T extends Comparable<? super T>>
052         int compare(final T a, final T b) {
053             return a.compareTo(b);
054         }
055     };
056 
057     /**
058      * Compares two comparable objects. Returns a negative integer, zero, or a
059      * positive integer as the first argument is better than, equal to, or worse
060      * than the second. This compare method is {@code null}-hostile. If you need
061      * to make it {@code null}-friendly, you can wrap it with the
062      {@link Comparator#nullsFirst(Comparator)} method.
063      *
064      <pre>{@code
065      * final Comparator<Integer> comparator = nullsFirst(Optimize.MAXIMUM::compare);
066      * assertEquals(comparator.compare(null, null), 0);
067      * assertEquals(comparator.compare(null, 4), -1);
068      * assertEquals(comparator.compare(4, null), 1);
069      * }</pre>
070      * or
071      <pre>{@code
072      * final Comparator<Integer> comparator = nullsFirst(Optimize.MINIMUM::compare);
073      * assertEquals(comparator.compare(null, null), 0);
074      * assertEquals(comparator.compare(null, 4), -1);
075      * assertEquals(comparator.compare(4, null), 1);
076      * }</pre>
077      *
078      @param <T> the comparable type
079      @param a the first object to be compared.
080      @param b the second object to be compared.
081      @return a negative integer, zero, or a positive integer as the first
082      *          argument is better than, equal to, or worse than the second.
083      @throws NullPointerException if one of the arguments is {@code null}.
084      */
085     public abstract <T extends Comparable<? super T>>
086     int compare(final T a, final T b);
087 
088     /**
089      * Create an appropriate comparator of the given optimization strategy. A
090      * collection of comparable objects with the returned comparator will be
091      * sorted in <b>descending</b> order, according to the given definition
092      * of <i>better</i> and <i>worse</i>.
093      *
094      <pre>{@code
095      * final Population<DoubleGene, Double> population = ...
096      * population.sort(Optimize.MINIMUM.<Double>descending());
097      * }</pre>
098      *
099      * The code example above will populationSort the population according it's fitness
100      * values in ascending order, since lower values are <i>better</i> in this
101      * case.
102      *
103      @param <T> the type of the objects to compare.
104      @return a new {@link Comparator} for the type {@code T}.
105      */
106     public <T extends Comparable<? super T>> Comparator<T> descending() {
107         return (a, b-> compare(b, a);
108     }
109 
110     /**
111      * Create an appropriate comparator of the given optimization strategy. A
112      * collection of comparable objects with the returned comparator will be
113      * sorted in <b>ascending</b> order, according to the given definition
114      * of <i>better</i> and <i>worse</i>.
115      *
116      <pre>{@code
117      * final Population<DoubleGene, Double> population = ...
118      * population.sort(Optimize.MINIMUM.<Double>ascending());
119      * }</pre>
120      *
121      * The code example above will populationSort the population according it's fitness
122      * values in descending order, since lower values are <i>better</i> in this
123      * case.
124      *
125      @param <T> the type of the objects to compare.
126      @return a new {@link Comparator} for the type {@code T}.
127      */
128     public <T extends Comparable<? super T>> Comparator<T> ascending() {
129         return this::compare;
130     }
131 
132     /**
133      * Return the best value, according to this optimization direction.
134      *
135      @see #best()
136      *
137      @param <C> the fitness value type.
138      @param a the first value.
139      @param b the second value.
140      @return the best value. If both values are equal the first one is returned.
141      @throws NullPointerException if one of the given arguments is {@code null}
142      */
143     public <C extends Comparable<? super C>> C best(final C a, final C b) {
144         return compare(b, a? b : a;
145     }
146 
147     /**
148      * Return a {@code null}-friendly function which returns the best element of
149      * two values. E.g.
150      *
151      <pre>{@code
152      * assertNull(Optimize.MAXIMUM.<Integer>best().apply(null, null));
153      * assertEquals(Optimize.MAXIMUM.<Integer>best().apply(null, 4), (Integer)4);
154      * assertEquals(Optimize.MAXIMUM.<Integer>best().apply(6, null), (Integer)6);
155      * }</pre>
156      *
157      @see #best(Comparable, Comparable)
158      *
159      @since 6.2
160      *
161      @param <C> the comparable argument type
162      @return a {@code null}-friendly method which returns the best element of
163      *            two values
164      */
165     public <C extends Comparable<? super C>> BinaryOperator<C> best() {
166         return (a, b-> {
167             switch (cmp(a, b)) {
168                 case 2return best(a, b);
169                 case -1return b;
170                 defaultreturn a;
171             }
172         };
173     }
174 
175     /**
176      * Return the worst value, according to this optimization direction.
177      *
178      @see #worst()
179      *
180      @param <C> the fitness value type.
181      @param a the first value.
182      @param b the second value.
183      @return the worst value. If both values are equal the first one is returned.
184      @throws NullPointerException if one of the given arguments is {@code null}
185      */
186     public <C extends Comparable<? super C>> C worst(final C a, final C b) {
187         return compare(b, a? b : a;
188     }
189 
190     /**
191      * Return a {@code null}-friendly function which returns the worst element
192      * of two values. E.g.
193      *
194      <pre>{@code
195      * assertNull(Optimize.MAXIMUM.<Integer>worst().apply(null, null));
196      * assertEquals(Optimize.MAXIMUM.<Integer>worst().apply(null, 4), (Integer)4);
197      * assertEquals(Optimize.MAXIMUM.<Integer>worst().apply(6, null), (Integer)6);
198      * }</pre>
199      *
200      @see #worst(Comparable, Comparable)
201      *
202      @since 6.2
203      *
204      @param <C> the comparable argument type
205      @return a {@code null}-friendly method which returns the worst element of
206      *            two values
207      */
208     public <C extends Comparable<? super C>> BinaryOperator<C> worst() {
209         return (a, b-> {
210             switch (cmp(a, b)) {
211                 case 2return worst(a, b);
212                 case -1return b;
213                 defaultreturn a;
214             }
215         };
216     }
217 
218     private static <T extends Comparable<? super T>>
219     int cmp(final T a, final T b) {
220         if (a != null) {
221             if (b != null) {
222                 return 2;
223             else {
224                 return 1;
225             }
226         else {
227             if (b != null) {
228                 return -1;
229             else {
230                 return 0;
231             }
232         }
233     }
234 
235 }