TarpeianMethod.java
package net.bmahe.genetics4j.gp.postevaluationprocess;
import java.util.function.Function;
import java.util.random.RandomGenerator;
import org.apache.commons.lang3.Validate;
import org.immutables.value.Value;
import net.bmahe.genetics4j.core.Genotype;
import net.bmahe.genetics4j.core.Population;
import net.bmahe.genetics4j.core.chromosomes.TreeChromosome;
@Value.Immutable
public abstract class TarpeianMethod implements Function<Population<Double>, Population<Double>> {
@Value.Parameter
public abstract RandomGenerator randomGenerator();
@Value.Parameter
public abstract Function<Genotype, Integer> sizeFunction();
@Value.Parameter
public abstract double probability();
@Value.Parameter
public abstract double newValue();
@Value.Check
protected void check() {
Validate.inclusiveBetween(0.0d, 1.0d, probability());
}
@Override
public Population<Double> apply(final Population<Double> population) {
Validate.notNull(population);
if (population.isEmpty()) {
return population;
}
final double averageSize = population.getAllGenotypes()
.stream()
.map(genotype -> sizeFunction().apply(genotype))
.mapToInt(i -> i)
.average()
.getAsDouble();
final Population<Double> newPopulation = new Population<>();
for (int i = 0; i < population.size(); i++) {
final Genotype genotype = population.getGenotype(i);
final int size = sizeFunction().apply(genotype);
double fitness = population.getFitness(i);
if (size > averageSize && randomGenerator().nextDouble() < probability()) {
fitness = newValue();
}
newPopulation.add(genotype, fitness);
}
return newPopulation;
}
public static TarpeianMethod of(final RandomGenerator randomGenerator,
final Function<Genotype, Integer> sizeFunction, final double probability, final double newValue) {
return ImmutableTarpeianMethod.of(randomGenerator, sizeFunction, probability, newValue);
}
public static TarpeianMethod ofTreeChromosome(final RandomGenerator randomGenerator, final int chromosomeIndex,
final double probability, final double newValue) {
return ImmutableTarpeianMethod.of(randomGenerator,
(genotype) -> genotype.getChromosome(chromosomeIndex, TreeChromosome.class).getSize(),
probability,
newValue);
}
}