View Javadoc
1   package net.bmahe.genetics4j.core.replacement;
2   
3   import java.util.List;
4   import java.util.Objects;
5   
6   import org.apache.commons.lang3.Validate;
7   import org.apache.logging.log4j.LogManager;
8   import org.apache.logging.log4j.Logger;
9   
10  import net.bmahe.genetics4j.core.Genotype;
11  import net.bmahe.genetics4j.core.Population;
12  import net.bmahe.genetics4j.core.selection.Selector;
13  import net.bmahe.genetics4j.core.spec.AbstractEAConfiguration;
14  import net.bmahe.genetics4j.core.spec.replacement.Elitism;
15  
16  public class ElitismImpl<T extends Comparable<T>> implements ReplacementStrategyImplementor<T> {
17  	final static public Logger logger = LogManager.getLogger(ElitismImpl.class);
18  
19  	private final Elitism elitismSpec;
20  	private final Selector<T> offspringSelector;
21  	private final Selector<T> survivorSelector;
22  
23  	public ElitismImpl(final Elitism _elistismSpec,
24  			final Selector<T> _offspringSelector,
25  			final Selector<T> _survivorSelector) {
26  		Objects.requireNonNull(_elistismSpec);
27  		Objects.requireNonNull(_offspringSelector);
28  		Objects.requireNonNull(_survivorSelector);
29  
30  		this.elitismSpec = _elistismSpec;
31  		this.offspringSelector = _offspringSelector;
32  		this.survivorSelector = _survivorSelector;
33  	}
34  
35  	@Override
36  	public Population<T> select(final AbstractEAConfiguration<T> eaConfiguration, final long generation,
37  			final int numIndividuals, final List<Genotype> population, final List<T> populationScores,
38  			final List<Genotype> offsprings, final List<T> offspringScores) {
39  		Objects.requireNonNull(eaConfiguration);
40  		Validate.isTrue(generation >= 0);
41  		Validate.isTrue(numIndividuals > 0);
42  		Objects.requireNonNull(population);
43  		Objects.requireNonNull(populationScores);
44  		Validate.isTrue(population.size() == populationScores.size());
45  		Objects.requireNonNull(offsprings);
46  		Objects.requireNonNull(offspringScores);
47  		Validate.isTrue(offsprings.size() == offspringScores.size());
48  		Validate.isTrue(elitismSpec.atLeastNumOffsprings() + elitismSpec.atLeastNumSurvivors() <= numIndividuals);
49  
50  		final int scaledOffspring = (int) (elitismSpec.offspringRatio() * numIndividuals);
51  		final int offspringNeeded = Math.max(scaledOffspring, elitismSpec.atLeastNumOffsprings());
52  		final int survivorNeeded = numIndividuals - offspringNeeded;
53  
54  		final int adjustedOffspringNeeded;
55  		final int adjustedSurvivorNeeded;
56  		if (survivorNeeded < elitismSpec.atLeastNumSurvivors()) {
57  			// Alternatively, it could be numIndividuals - elitismSpec.atLeastNumSurvivors()
58  			adjustedOffspringNeeded = offspringNeeded - (elitismSpec.atLeastNumSurvivors() - survivorNeeded);
59  			adjustedSurvivorNeeded = elitismSpec.atLeastNumSurvivors();
60  		} else {
61  			adjustedOffspringNeeded = offspringNeeded;
62  			adjustedSurvivorNeeded = survivorNeeded;
63  		}
64  
65  		logger.debug(
66  				"We have {} individuals requested and an offspring ratio of {}. Survivors:{}, Offsprings:{}",
67  					numIndividuals,
68  					elitismSpec.offspringRatio(),
69  					adjustedSurvivorNeeded,
70  					adjustedOffspringNeeded);
71  
72  		final Population<T> selected = new Population<>();
73  
74  		logger.info("Selecting {} offsprings", adjustedOffspringNeeded);
75  		final Population<T> selectedOffspring = offspringSelector
76  				.select(eaConfiguration, generation, adjustedOffspringNeeded, offsprings, offspringScores);
77  		selected.addAll(selectedOffspring);
78  
79  		logger.info("Selecting {} survivors", adjustedSurvivorNeeded);
80  		final Population<T> selectedSurvivors = survivorSelector
81  				.select(eaConfiguration, generation, adjustedSurvivorNeeded, population, populationScores);
82  		selected.addAll(selectedSurvivors);
83  
84  		return selected;
85  	}
86  }