Terminals.java
package net.bmahe.genetics4j.gp.math;
import java.util.List;
import java.util.Objects;
import java.util.random.RandomGenerator;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.apache.commons.lang3.Validate;
import net.bmahe.genetics4j.gp.OperationFactories;
import net.bmahe.genetics4j.gp.OperationFactory;
public class Terminals {
public final static String TYPE_COEFFICIENT = "Coefficient";
public final static String TYPE_COEFFICIENT_INT = "CoefficientInt";
public final static String TYPE_INPUT = "Input";
public final static String NAME_PI = "PI";
public final static String NAME_E = "E";
public static OperationFactory PI = OperationFactories.ofTerminal(NAME_PI, Double.class, () -> Math.PI);
public static OperationFactory E = OperationFactories.ofTerminal(NAME_E, Double.class, () -> Math.E);
public static OperationFactory Coefficient(final RandomGenerator randomGenerator, final double min,
final double max) {
return OperationFactories.ofOperationSupplier(new Class[] {}, Double.class, () -> {
final double value = randomGenerator.nextDouble() * (max - min) + min;
final var operationBuilder = ImmutableCoefficientOperation.builder();
operationBuilder.name(TYPE_COEFFICIENT)
.prettyName(TYPE_COEFFICIENT + "[" + value + "]")
.returnedType(Double.class)
.value(value);
return operationBuilder.build();
});
}
public static OperationFactory CoefficientRounded(final RandomGenerator randomGenerator, final int min,
final int max) {
return OperationFactories.ofOperationSupplier(new Class[] {}, Double.class, () -> {
final double value = randomGenerator.nextInt(max - min) + min;
final var operationBuilder = ImmutableCoefficientOperation.builder();
operationBuilder.name(TYPE_COEFFICIENT)
.prettyName("CoefficientRounded[" + value + "]")
.returnedType(Double.class)
.value(value);
return operationBuilder.build();
});
}
public static OperationFactory CoefficientInt(final RandomGenerator randomGenerator, final int min, final int max) {
return OperationFactories.ofOperationSupplier(new Class[] {}, Integer.class, () -> {
final int value = randomGenerator.nextInt(max - min) + min;
final var operationBuilder = ImmutableCoefficientOperation.builder();
operationBuilder.name(TYPE_COEFFICIENT_INT)
.prettyName("CoefficientInt[" + value + "]")
.returnedType(Integer.class)
.value(value);
return operationBuilder.build();
});
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T> OperationFactory Input(final int inputIndex, final Class<T> clazz) {
Validate.isTrue(inputIndex >= 0);
Objects.requireNonNull(clazz);
return OperationFactories.of(new Class[] {}, clazz, (inputSpec) -> {
final List<Class> types = inputSpec.types();
Validate.isTrue(types.get(inputIndex)
.isAssignableFrom(clazz));
final var operationBuilder = ImmutableInputOperation.builder();
operationBuilder.name(TYPE_INPUT)
.prettyName(TYPE_INPUT + "[" + inputIndex + "]")
.returnedType(clazz)
.index(inputIndex);
return operationBuilder.build();
});
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T> OperationFactory Input(final RandomGenerator randomGenerator, final Class<T> clazz) {
Objects.requireNonNull(randomGenerator);
Objects.requireNonNull(clazz);
return OperationFactories.of(new Class[] {}, clazz, (inputSpec) -> {
final List<Class> types = inputSpec.types();
final List<Integer> candidates = IntStream.range(0, types.size())
.filter((i) -> types.get(i)
.isAssignableFrom(clazz))
.boxed()
.collect(Collectors.toList());
if (candidates.isEmpty()) {
throw new IllegalArgumentException("No input with type " + clazz + " found");
}
final Integer inputIdx = candidates.get(randomGenerator.nextInt(candidates.size()));
final var operationBuilder = ImmutableInputOperation.builder();
operationBuilder.name(TYPE_INPUT)
.prettyName(TYPE_INPUT + "[" + inputIdx + "]")
.returnedType(clazz)
.index(inputIdx);
return operationBuilder.build();
});
}
public static OperationFactory InputDouble(final RandomGenerator randomGenerator) {
return Input(randomGenerator, Double.class);
}
public static OperationFactory InputString(final RandomGenerator randomGenerator) {
return Input(randomGenerator, String.class);
}
}