From aed6052aaae05d6611b2086f692a280d507f4b58 Mon Sep 17 00:00:00 2001 From: jsuyash1514 Date: Mon, 4 Mar 2019 13:40:02 +0530 Subject: [PATCH] Update Genetic algorithm implementation --- .../search/basic/local/GeneticAlgorithm.java | 90 +++++++++++-------- 1 file changed, 55 insertions(+), 35 deletions(-) diff --git a/core/src/main/java/aima/core/search/basic/local/GeneticAlgorithm.java b/core/src/main/java/aima/core/search/basic/local/GeneticAlgorithm.java index b989889b9a..ba53241b12 100644 --- a/core/src/main/java/aima/core/search/basic/local/GeneticAlgorithm.java +++ b/core/src/main/java/aima/core/search/basic/local/GeneticAlgorithm.java @@ -60,7 +60,7 @@ public class GeneticAlgorithm { * * @param population * a set of individuals - * @param fitnessFn + * @param fitnessFN * a function that measures the fitness of an individual * @return the best individual in the specified population, according to the * specified FITNESS-FN. @@ -73,18 +73,8 @@ public Individual geneticAlgorithm(Set> population, ToDoubleFun Set> new_population = new HashSet>(population.size()); // repeat do { - // x <- RANDOM-SELECTION(population, FITNESS-FN) - Individual x = randomSelection(population, fitnessFN); - // y <- RANDOM-SELECTION(population, FITNESS-FN) - Individual y = randomSelection(population, fitnessFN); - // child <- REPRODUCE(x, y) - Individual child = reproduce(x, y); - // if (small random probability) then child <- MUTATE(child) - if (isSmallRandomProbabilityOfMutation()) { - child = mutate(child); - } - // add child to new_population - new_population.add(child); + // population <- [MUTATE(RECOMBINE(SELECT(2, population, FITNESS-FN)))] + new_population.add(mutate(recombine(select(2, population, fitnessFN )))); } // until SIZE(new_population) = SIZE(population) while (new_population.size() != population.size()); population = new_population; @@ -94,13 +84,36 @@ public Individual geneticAlgorithm(Set> population, ToDoubleFun return bestIndividual; } - // function REPRODUCE(x, y) returns an individual - public Individual reproduce(Individual x, Individual y) { - // n <- LENGTH(x); + + public Set> select(int p, Set> population, ToDoubleFunction> fitnessFN){ + Set> selection = new HashSet>(2*p); + // selection <- a uniform random sample of 2*p individuals from population + do{ + selection.add(randomSelection(population,fitnessFN)); + } + while (selection.size() != 2*p); + + // return the top p individuals in selection, ranked by FITNESS-FN + Set> fittestIndividuals = new HashSet>(p); + do{ + Individual best = selectBestIndividual(selection,fitnessFN); + fittestIndividuals.add(best); + selection.remove(best); + } + while(fittestIndividuals.size() != p); + + return fittestIndividuals; + } + + public Individual recombine(Set> parentIndividuals){ + Iterator> parentIt = parentIndividuals.iterator(); + Individual x = parentIt.next(); + Individual y = parentIt.next(); + // n <- LENGTH(X) int n = x.length(); - // c <- random number from 1 to n + // c <- random number from 0 to n int c = random.nextInt(n); - // return APPEND(SUBSTRING(x, 1, c), SUBSTRING(y, c+1, n)) + // return APPEND(x[0:c], y[c:n]) return new Individual(x.substring(0, c), y.substring(c, n)); } @@ -154,34 +167,41 @@ public boolean isSmallRandomProbabilityOfMutation() { } public Individual mutate(Individual child) { - // We will mutate the child in place. - child.getRepresentation().set(random.nextInt(child.length()), alphabet.get(random.nextInt(alphabet.size()))); + // if (small random probability) then child <- MUTATE(child) + if(isSmallRandomProbabilityOfMutation()){ + // We will mutate the child in place. + child.getRepresentation().set(random.nextInt(child.length()), alphabet.get(random.nextInt(alphabet.size()))); + } return child; } public Individual selectBestIndividualIfReady(Set> population, ToDoubleFunction> fitnessFN) { - Individual best = null; - // until some individual is fit enough, or enough time has elapsed if (!executionController.isExecuting() || population.stream().anyMatch(fitEnoughPredicate)) { - double bestValue = 0; - Iterator> popIt = population.iterator(); - while (popIt.hasNext()) { - Individual current = popIt.next(); - double currentValue = fitnessFN.applyAsDouble(current); - if (best == null || currentValue > bestValue) { + return selectBestIndividual(population,fitnessFN); + } + return null; + } + + public Individual selectBestIndividual(Set> population, + ToDoubleFunction> fitnessFN) { + Individual best = null; + double bestValue = 0; + Iterator> popIt = population.iterator(); + while (popIt.hasNext()) { + Individual current = popIt.next(); + double currentValue = fitnessFN.applyAsDouble(current); + if (best == null || currentValue > bestValue) { + best = current; + bestValue = currentValue; + } else if (currentValue == bestValue) { + // Randomly break ties + if (random.nextBoolean()) { best = current; - bestValue = currentValue; - } else if (currentValue == bestValue) { - // Randomly break ties - if (random.nextBoolean()) { - best = current; - } } } } - return best; } }