io.jenetics.Optimize Maven / Gradle / Ivy
Show all versions of jenetics Show documentation
/*
* Java Genetic Algorithm Library (jenetics-8.1.0).
* Copyright (c) 2007-2024 Franz Wilhelmstötter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Author:
* Franz Wilhelmstötter ([email protected])
*/
package io.jenetics;
import java.util.Comparator;
import java.util.function.BinaryOperator;
/**
* This {@code enum} determines whether the GA should maximize or minimize the
* fitness function.
*
* @author Franz Wilhelmstötter
* @since 1.0
* @version 6.2
*/
public enum Optimize {
/**
* GA minimization
*/
MINIMUM {
@Override
public >
int compare(final T a, final T b) {
return b.compareTo(a);
}
},
/**
* GA maximization
*/
MAXIMUM {
@Override
public >
int compare(final T a, final T b) {
return a.compareTo(b);
}
};
/**
* Compares two comparable objects. Returns a negative integer, zero, or a
* positive integer as the first argument is better than, equal to, or worse
* than the second. This compare method is {@code null}-hostile. If you need
* to make it {@code null}-friendly, you can wrap it with the
* {@link Comparator#nullsFirst(Comparator)} method.
*
* {@snippet lang="java":
* final Comparator comparator = nullsFirst(Optimize.MAXIMUM::compare);
* assertEquals(comparator.compare(null, null), 0);
* assertEquals(comparator.compare(null, 4), -1);
* assertEquals(comparator.compare(4, null), 1);
* }
* or
* {@snippet lang="java":
* final Comparator comparator = nullsFirst(Optimize.MINIMUM::compare);
* assertEquals(comparator.compare(null, null), 0);
* assertEquals(comparator.compare(null, 4), -1);
* assertEquals(comparator.compare(4, null), 1);
* }
*
* @param the comparable type
* @param a the first object to be compared.
* @param b the second object to be compared.
* @return a negative integer, zero, or a positive integer as the first
* argument is better than, equal to, or worse than the second.
* @throws NullPointerException if one of the arguments is {@code null}.
*/
public abstract >
int compare(final T a, final T b);
/**
* Create an appropriate comparator of the given optimization strategy. A
* collection of comparable objects with the returned comparator will be
* sorted in descending order, according to the given definition
* of better and worse.
*
* {@snippet lang="java":
* final Population population = null; // @replace substring='null' replacement="..."
* population.sort(Optimize.MINIMUM.descending());
* }
*
* The code example above will populationSort the population according its
* fitness values in ascending order, since lower values are better
* in this case.
*
* @param the type of the objects to compare.
* @return a new {@link Comparator} for the type {@code T}.
*/
public > Comparator descending() {
return (a, b) -> compare(b, a);
}
/**
* Create an appropriate comparator of the given optimization strategy. A
* collection of comparable objects with the returned comparator will be
* sorted in ascending order, according to the given definition
* of better and worse.
*
* {@snippet lang="java":
* final Population population = null; // @replace substring='null' replacement="..."
* population.sort(Optimize.MINIMUM.ascending());
* }
*
* The code example above will populationSort the population according its
* fitness values in descending order, since lower values are better
* in this case.
*
* @param the type of the objects to compare.
* @return a new {@link Comparator} for the type {@code T}.
*/
public > Comparator ascending() {
return this::compare;
}
/**
* Return the best value, according to this optimization direction.
*
* @see #best()
*
* @param the fitness value type.
* @param a the first value.
* @param b the second value.
* @return the best value. If both values are equal, the first one is returned.
* @throws NullPointerException if one of the given arguments is {@code null}
*/
public > C best(final C a, final C b) {
return compare(b, a) > 0 ? b : a;
}
/**
* Return a {@code null}-friendly function which returns the best element of
* two values. E.g.
*
* {@snippet lang="java":
* assertNull(Optimize.MAXIMUM.best().apply(null, null));
* assertEquals(Optimize.MAXIMUM.best().apply(null, 4), (Integer)4);
* assertEquals(Optimize.MAXIMUM.best().apply(6, null), (Integer)6);
* }
*
* @see #best(Comparable, Comparable)
*
* @since 6.2
*
* @param the comparable argument type
* @return a {@code null}-friendly method which returns the best element of
* two values
*/
public > BinaryOperator best() {
return (a, b) -> switch (cmp(a, b)) {
case 2 -> best(a, b);
case -1 -> b;
default -> a;
};
}
/**
* Return the worst value, according to this optimization direction.
*
* @see #worst()
*
* @param the fitness value type.
* @param a the first value.
* @param b the second value.
* @return the worst value. If both values are equal, the first one is returned.
* @throws NullPointerException if one of the given arguments is {@code null}
*/
public > C worst(final C a, final C b) {
return compare(b, a) < 0 ? b : a;
}
/**
* Return a {@code null}-friendly function which returns the worst element
* of two values. E.g.
*
* {@snippet lang="java":
* assertNull(Optimize.MAXIMUM.worst().apply(null, null));
* assertEquals(Optimize.MAXIMUM.worst().apply(null, 4), (Integer)4);
* assertEquals(Optimize.MAXIMUM.worst().apply(6, null), (Integer)6);
* }
*
* @see #worst(Comparable, Comparable)
*
* @since 6.2
*
* @param the comparable argument type
* @return a {@code null}-friendly method which returns the worst element of
* two values
*/
public > BinaryOperator worst() {
return (a, b) -> switch (cmp(a, b)) {
case 2 -> worst(a, b);
case -1 -> b;
default -> a;
};
}
private static >
int cmp(final T a, final T b) {
if (a != null) {
if (b != null) {
return 2;
} else {
return 1;
}
} else {
if (b != null) {
return -1;
} else {
return 0;
}
}
}
}