Reproduction.java
1 package genetics; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 /** 7 * The Reproduction class defines how a parent population reproduces 8 * 9 * Offspring of a parent population are generated according to the fitness of the individuals in the parent population 10 * The genes of children are generated using crossing over and mutation 11 */ 12 public class Reproduction { 13 14 private static final double CROSSOVER_RATE = 0.5; 15 private static final double MUTATION_RATE = 0.025; 16 private static final double NEW_MUTATION_RATE = 0.025; 17 private static final int TOURNAMENT_SIZE = 4; 18 private static final boolean ELITISM = true; 19 20 /** 21 * @return The offspring of the input population 22 */ 23 public static Population reproduce(Population population, Map<String, Gene> genes) { 24 Population offspring = new Population(population.size(), population.getGeneration() + 1); 25 26 // Keep our best individual 27 if (ELITISM) { 28 offspring.setIndividual(0, population.getFittest()); 29 offspring.getIndividual(0).setFitness(0.0); 30 } 31 int elitismOffset = ELITISM ? 1 : 0; 32 33 // Cross the individuals 34 for (int i = elitismOffset; i < population.size(); i++) { 35 Individual indiv1 = tournamentSelection(population); 36 Individual indiv2 = tournamentSelection(population); 37 offspring.setIndividual(i, crossover(indiv1, indiv2)); 38 } 39 40 // Mutate new individuals 41 for (int i = elitismOffset; i < offspring.size(); i++) { 42 mutate(offspring.getIndividual(i), genes); 43 } 44 45 return offspring; 46 } 47 48 private static Individual crossover(Individual indA, Individual indB) { 49 HashMap<String, Double> chromosome = new HashMap<>(); 50 for (String gene : indA.getChromosome().keySet()){ 51 if (Math.random() <= CROSSOVER_RATE) { 52 chromosome.put(gene, indA.getAllele(gene)); 53 } else { 54 chromosome.put(gene, indB.getAllele(gene)); 55 } 56 } 57 return new Individual(chromosome); 58 } 59 60 private static void mutate(Individual individual, Map<String, Gene> genes) { 61 HashMap<String, Double> chromosome = new HashMap<>(); 62 for (HashMap.Entry<String, Double> allele : individual.getChromosome().entrySet()){ 63 Double value = allele.getValue(); 64 if (Math.random() <= MUTATION_RATE){ 65 Gene gene = genes.get(allele.getKey()); 66 value = gene.mutate(value); 67 } else if (Math.random() <= NEW_MUTATION_RATE){ 68 Gene gene = genes.get(allele.getKey()); 69 value = gene.generateAllele(); 70 } 71 chromosome.put(allele.getKey(), value); 72 } 73 individual.setChromosome(chromosome); 74 } 75 76 /** 77 * Creates a tournament population and returns the fittest individual in that population 78 */ 79 private static Individual tournamentSelection(Population population) { 80 Population tournament = new Population(TOURNAMENT_SIZE, 0); 81 for (int i = 0; i < TOURNAMENT_SIZE; i++) { 82 int randomId = (int) (Math.random() * population.size()); 83 tournament.setIndividual(i, population.getIndividual(randomId)); 84 } 85 return tournament.getFittest(); 86 } 87 }