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