From adc5f58133142352c602ff7ddd6cb5bc752e8462 Mon Sep 17 00:00:00 2001 From: Fabian Becker Date: Mon, 27 Oct 2014 09:46:59 +0100 Subject: [PATCH] Some corrections to ABC. More cleanup. --- .../optimization/population/Population.java | 2 +- .../statistics/EvAStatisticalEvaluation.java | 2 +- .../strategies/ArtificialBeeColony.java | 33 +++++++++++-------- src/eva2/tools/math/Mathematics.java | 3 +- src/eva2/tools/math/RNG.java | 20 +++++++++-- 5 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/eva2/optimization/population/Population.java b/src/eva2/optimization/population/Population.java index a05e9ef5..7ff24498 100644 --- a/src/eva2/optimization/population/Population.java +++ b/src/eva2/optimization/population/Population.java @@ -24,7 +24,7 @@ import java.util.logging.Logger; /** * A basic implementation of an EA population. Manage a set of potential solutions - * in form of AbstractEAIndividuals. They can be sorted using an AbstractEAIndividualComparator. + * in form of AbstractEAIndividuals. They can be sorted using an EAIndividualComparator. * Optionally, a history list is kept storing a clone of the best individual of any generation. * The Population also provides for appropriate counting of function calls performed. * For initialization, the default individual initialization method may be used, as well as a diff --git a/src/eva2/optimization/statistics/EvAStatisticalEvaluation.java b/src/eva2/optimization/statistics/EvAStatisticalEvaluation.java index 6722b304..f1b8eea2 100644 --- a/src/eva2/optimization/statistics/EvAStatisticalEvaluation.java +++ b/src/eva2/optimization/statistics/EvAStatisticalEvaluation.java @@ -175,7 +175,7 @@ public class EvAStatisticalEvaluation { } public static double roundTo2DecimalPlaces(double value) { - DecimalFormat twoDForm = new DecimalFormat("#.##"); + DecimalFormat twoDForm = new DecimalFormat("##0.####E0"); String b = twoDForm.format(value); b = b.replace(',', '.'); return Double.valueOf(b); diff --git a/src/eva2/optimization/strategies/ArtificialBeeColony.java b/src/eva2/optimization/strategies/ArtificialBeeColony.java index 3d0ee076..ff3f5139 100644 --- a/src/eva2/optimization/strategies/ArtificialBeeColony.java +++ b/src/eva2/optimization/strategies/ArtificialBeeColony.java @@ -103,12 +103,12 @@ public class ArtificialBeeColony extends AbstractOptimizer implements Serializab AbstractEAIndividual newIndividual = (AbstractEAIndividual) indy.getClone(); double[] indyDoubleData = ((InterfaceDataTypeDouble) newIndividual).getDoubleData(); - int randomParam = RNG.randomInt(0, indyDoubleData.length - 1); - int neighbour = RNG.randomInt(0, this.population.size() - 1); + int neighbour = RNG.randomIntWithout(i, 0, this.population.size() - 1); double[] randomIndy = ((InterfaceDataTypeDouble) this.population.get(neighbour)).getDoubleData(); - double r = RNG.randomDouble(); - indyDoubleData[randomParam] = indyDoubleData[randomParam] + (indyDoubleData[randomParam] - randomIndy[randomParam]) * (r - 0.5) * 2.0; + int randomParam = RNG.randomInt(0, indyDoubleData.length - 1); + double r = RNG.randomDouble(-1.0, 1.0); + indyDoubleData[randomParam] += (indyDoubleData[randomParam] - randomIndy[randomParam]) * r; // Make sure new indy is in range Mathematics.projectToRange(indyDoubleData, ((InterfaceDataTypeDouble) newIndividual).getDoubleRange()); @@ -124,18 +124,26 @@ public class ArtificialBeeColony extends AbstractOptimizer implements Serializab } } + + this.population.incrFunctionCallsBy(this.population.size()); + /** * Send onlooker bees to food sources based on fitness proportional probablity */ int t = 0, i = 0; - double maxFitness = this.population.getBestFitness()[0]; + double sumFitness = 0.0; + for (Object individual : this.population) { + sumFitness += ((AbstractEAIndividual) individual).getFitness(0); + } while (t < this.population.size()) { double r = RNG.randomDouble(); /** - * Choose a food source depending on its probability to be chosen + * Choose a food source depending on its probability to be chosen. The probability + * is proportional to the */ - if (r < ((0.9 * (this.population.getEAIndividual(i).getFitness(0) / maxFitness)) + 0.1)) { + double pI = 1 - (this.population.getEAIndividual(i).getFitness(0) / sumFitness); + if (r < pI) { t++; // The current individual to compare to @@ -146,16 +154,17 @@ public class ArtificialBeeColony extends AbstractOptimizer implements Serializab double[] indyDoubleData = ((InterfaceDataTypeDouble) newIndividual).getDoubleData(); int randomParam = RNG.randomInt(0, indyDoubleData.length - 1); - int neighbour = RNG.randomInt(0, this.population.size() - 1); + int neighbour = RNG.randomIntWithout(i, 0, this.population.size() - 1); double[] randomIndy = ((InterfaceDataTypeDouble) this.population.get(neighbour)).getDoubleData(); - r = RNG.randomDouble(); - indyDoubleData[randomParam] = indyDoubleData[randomParam] + (indyDoubleData[randomParam] - randomIndy[randomParam]) * (r - 0.5) * 2.0; + r = RNG.randomDouble(-1.0, 1.0); + indyDoubleData[randomParam] += (indyDoubleData[randomParam] - randomIndy[randomParam]) * r; // Make sure new indy is in range Mathematics.projectToRange(indyDoubleData, ((InterfaceDataTypeDouble) newIndividual).getDoubleRange()); ((InterfaceDataTypeDouble) newIndividual).setDoubleGenotype(indyDoubleData); this.optimizationProblem.evaluate(newIndividual); + this.population.incrFunctionCalls(); if (newIndividual.getFitness(0) < indy.getFitness(0)) { newIndividual.setAge(1); @@ -191,8 +200,6 @@ public class ArtificialBeeColony extends AbstractOptimizer implements Serializab this.population.incrFunctionCalls(); } - this.population.incrFunctionCallsBy(this.population.size()); - /** * ToDo: This is ugly. * @@ -210,7 +217,7 @@ public class ArtificialBeeColony extends AbstractOptimizer implements Serializab private AbstractEAIndividual getOldestIndividual() { AbstractEAIndividual oldestIndy = this.population.getEAIndividual(0); for(int i = 1; i < this.population.size(); i++) { - if (oldestIndy.getAge() < this.population.getEAIndividual(i).getAge()) { + if (oldestIndy.getAge() > this.population.getEAIndividual(i).getAge()) { oldestIndy = this.population.getEAIndividual(i); } } diff --git a/src/eva2/tools/math/Mathematics.java b/src/eva2/tools/math/Mathematics.java index 68714a70..012d13d6 100644 --- a/src/eva2/tools/math/Mathematics.java +++ b/src/eva2/tools/math/Mathematics.java @@ -528,7 +528,8 @@ public class Mathematics { if (vector.length == 0) { return 0; } - return sum(vector) / (double) vector.length; + double sum = sum(vector); + return sum / (double) vector.length; } /** diff --git a/src/eva2/tools/math/RNG.java b/src/eva2/tools/math/RNG.java index 48f0b156..3bb93de8 100644 --- a/src/eva2/tools/math/RNG.java +++ b/src/eva2/tools/math/RNG.java @@ -86,7 +86,23 @@ public class RNG { } /** - * This method returns a evenly distributed int value. The boundarys are + * Returns a random int between lo and hi but not equal to ignore. + * + * @param ignore Value to ignore + * @param lo Lower bound. + * @param hi Upper bound. + * @return An int that is not equal to ignore + */ + public static int randomIntWithout(int ignore, int lo, int hi) { + int result = ignore; + while (result == ignore) { + result = randomInt(lo, hi); + } + return result; + } + + /** + * This method returns an evenly distributed int value. The boundaries are * included. * * @param lo Lower bound. @@ -134,7 +150,7 @@ public class RNG { } /** - * This method returns a evenly distributed int value. The boundarys are + * This method returns an evenly distributed int value. The boundaries are * included. * * @param lo Lower bound.