1 package net.bmahe.genetics4j.core.selection; 2 3 import java.util.Comparator; 4 import java.util.List; 5 import java.util.random.RandomGenerator; 6 7 import org.apache.commons.lang3.Validate; 8 import org.apache.logging.log4j.LogManager; 9 import org.apache.logging.log4j.Logger; 10 11 import net.bmahe.genetics4j.core.Genotype; 12 import net.bmahe.genetics4j.core.Individual; 13 import net.bmahe.genetics4j.core.Population; 14 import net.bmahe.genetics4j.core.spec.AbstractEAConfiguration; 15 import net.bmahe.genetics4j.core.spec.selection.SelectionPolicy; 16 import net.bmahe.genetics4j.core.spec.selection.Tournament; 17 18 public class TournamentSelector<T extends Comparable<T>> implements Selector<T> { 19 public static final Logger logger = LogManager.getLogger(TournamentSelector.class); 20 21 private final SelectionPolicy selectionPolicy; 22 private final RandomGenerator randomGenerator; 23 24 public TournamentSelector(final SelectionPolicy _selectionPolicy, final RandomGenerator _randomGenerator) { 25 Validate.notNull(_selectionPolicy); 26 Validate.isInstanceOf(Tournament.class, _selectionPolicy); 27 Validate.notNull(_randomGenerator); 28 29 this.selectionPolicy = _selectionPolicy; 30 this.randomGenerator = _randomGenerator; 31 } 32 33 @Override 34 public Population<T> select(final AbstractEAConfiguration<T> eaConfiguration, final int numIndividuals, 35 final List<Genotype> population, final List<T> fitnessScore) { 36 Validate.notNull(eaConfiguration); 37 Validate.notNull(population); 38 Validate.notNull(fitnessScore); 39 Validate.isTrue(numIndividuals > 0); 40 Validate.isTrue(population.size() == fitnessScore.size()); 41 42 @SuppressWarnings("unchecked") 43 final Tournament<T> tournamentSelection = (Tournament<T>) selectionPolicy; 44 45 final Comparator<Individual<T>> baseComparator = tournamentSelection.comparator(); 46 final Comparator<Individual<T>> comparator = switch (eaConfiguration.optimization()) { 47 case MAXIMIZE -> baseComparator; 48 case MINIMIZE -> baseComparator.reversed(); 49 }; 50 51 logger.debug("Selecting {} individuals", numIndividuals); 52 53 final Population<T> selectedIndividuals = new Population<>(); 54 while (selectedIndividuals.size() < numIndividuals) { 55 56 Individual<T> bestIndividual = null; 57 58 for (int i = 0; i < tournamentSelection.numCandidates(); i++) { 59 final int candidateIndex = randomGenerator.nextInt(fitnessScore.size()); 60 final Individual<T> candidate = Individual.of(population.get(candidateIndex), 61 fitnessScore.get(candidateIndex)); 62 63 if (bestIndividual == null || comparator.compare(bestIndividual, candidate) < 0) { 64 bestIndividual = candidate; 65 } 66 } 67 68 selectedIndividuals.add(bestIndividual); 69 } 70 71 return selectedIndividuals; 72 } 73 }