View Javadoc
1   package net.bmahe.genetics4j.gp.postevaluationprocess;
2   
3   import java.util.Objects;
4   import java.util.function.Function;
5   import java.util.random.RandomGenerator;
6   
7   import org.apache.commons.lang3.Validate;
8   import org.immutables.value.Value;
9   
10  import net.bmahe.genetics4j.core.Genotype;
11  import net.bmahe.genetics4j.core.Population;
12  import net.bmahe.genetics4j.core.chromosomes.TreeChromosome;
13  import net.bmahe.genetics4j.core.spec.PostEvaluationProcessor;
14  
15  @Value.Immutable
16  public abstract class TarpeianMethod implements PostEvaluationProcessor<Double> {
17  
18  	@Value.Parameter
19  	public abstract RandomGenerator randomGenerator();
20  
21  	@Value.Parameter
22  	public abstract Function<Genotype, Integer> sizeFunction();
23  
24  	@Value.Parameter
25  	public abstract double probability();
26  
27  	@Value.Parameter
28  	public abstract double newValue();
29  
30  	@Value.Check
31  	protected void check() {
32  		Validate.inclusiveBetween(0.0d, 1.0d, probability());
33  	}
34  
35  	@Override
36  	public Population<Double> apply(final long generation, final Population<Double> population) {
37  		Validate.isTrue(generation >= 0);
38  		Objects.requireNonNull(population);
39  
40  		if (population.isEmpty()) {
41  			return population;
42  		}
43  
44  		final double averageSize = population.getAllGenotypes()
45  				.stream()
46  				.map(genotype -> sizeFunction().apply(genotype))
47  				.mapToInt(i -> i)
48  				.average()
49  				.getAsDouble();
50  
51  		final Population<Double> newPopulation = new Population<>();
52  		for (int i = 0; i < population.size(); i++) {
53  
54  			final Genotype genotype = population.getGenotype(i);
55  			final int size = sizeFunction().apply(genotype);
56  
57  			double fitness = population.getFitness(i);
58  			if (size > averageSize && randomGenerator().nextDouble() < probability()) {
59  				fitness = newValue();
60  			}
61  
62  			newPopulation.add(genotype, fitness);
63  		}
64  
65  		return newPopulation;
66  	}
67  
68  	public static TarpeianMethod of(final RandomGenerator randomGenerator,
69  			final Function<Genotype, Integer> sizeFunction, final double probability, final double newValue) {
70  		return ImmutableTarpeianMethod.of(randomGenerator, sizeFunction, probability, newValue);
71  	}
72  
73  	public static TarpeianMethod ofTreeChromosome(final RandomGenerator randomGenerator, final int chromosomeIndex,
74  			final double probability, final double newValue) {
75  
76  		return ImmutableTarpeianMethod.of(
77  				randomGenerator,
78  				genotype -> genotype.getChromosome(chromosomeIndex, TreeChromosome.class).getSize(),
79  				probability,
80  				newValue);
81  	}
82  }