diff --git a/src/eva2/client/EvAClient.java b/src/eva2/client/EvAClient.java index 84b67e37..31ace0ca 100644 --- a/src/eva2/client/EvAClient.java +++ b/src/eva2/client/EvAClient.java @@ -772,15 +772,15 @@ public class EvAClient extends JFrame implements OptimizationStateListener { menuBar = new JMenuBar(); setJMenuBar(menuBar); menuModule = new JExtMenu("&Module"); - menuModule.add(actModuleLoad); + //menuModule.add(actModuleLoad); menuSelHosts = new JExtMenu("&Select Hosts"); - menuSelHosts.setToolTipText("Select a host for the server application"); - menuSelHosts.add(actHost); - menuSelHosts.add(actAvailableHost); - menuSelHosts.addSeparator(); - menuSelHosts.add(actKillHost); - menuSelHosts.add(actKillAllHosts); + //menuSelHosts.setToolTipText("Select a host for the server application"); + //menuSelHosts.add(actHost); + //menuSelHosts.add(actAvailableHost); + //menuSelHosts.addSeparator(); + //menuSelHosts.add(actKillHost); + //menuSelHosts.add(actKillAllHosts); menuHelp = new JExtMenu("&Help"); menuHelp.add(actHelp); @@ -790,13 +790,13 @@ public class EvAClient extends JFrame implements OptimizationStateListener { menuOptions = new JExtMenu("&Options"); menuOptions.add(actPreferences); - menuOptions.add(menuSelHosts); + //menuOptions.add(menuSelHosts); menuOptions.addSeparator(); menuOptions.add(actQuit); // this is accessible if no default module is given - if (showLoadModules) { - menuBar.add(menuModule); - } + //if (showLoadModules) { + // menuBar.add(menuModule); + //} menuBar.add(menuOptions); menuBar.add(((JExtDesktopPane) desktopPane).getWindowMenu()); diff --git a/src/eva2/server/go/InterfaceGOStandalone.java b/src/eva2/server/go/InterfaceGOStandalone.java index 0fc93c49..1e597eac 100644 --- a/src/eva2/server/go/InterfaceGOStandalone.java +++ b/src/eva2/server/go/InterfaceGOStandalone.java @@ -8,6 +8,6 @@ package eva2.server.go; * To change this template use Options | File Templates. */ public interface InterfaceGOStandalone { - public void startExperiment(); - public void setShow(boolean t); + void startExperiment(); + void setShow(boolean t); } diff --git a/src/eva2/server/go/InterfacePopulationChangedEventListener.java b/src/eva2/server/go/InterfacePopulationChangedEventListener.java index 63ccb0ba..4d22f838 100644 --- a/src/eva2/server/go/InterfacePopulationChangedEventListener.java +++ b/src/eva2/server/go/InterfacePopulationChangedEventListener.java @@ -14,5 +14,5 @@ public interface InterfacePopulationChangedEventListener { * @param source The source of the event. * @param name Could be used to indicate the nature of the event. */ - public void registerPopulationStateChanged(Object source, String name); + void registerPopulationStateChanged(Object source, String name); } diff --git a/src/eva2/server/go/strategies/BOA.java b/src/eva2/server/go/strategies/BOA.java index f30b414c..cf68faea 100644 --- a/src/eva2/server/go/strategies/BOA.java +++ b/src/eva2/server/go/strategies/BOA.java @@ -32,118 +32,115 @@ import java.util.logging.Logger; /** * Basic implementation of the Bayesian Optimization Algorithm - * + * * Martin Pelikan, David E. Goldberg and Erick Cantu-Paz: 'BOA: The Bayesian * Optimization Algorithm' the works by Martin Pelikan and David E. Goldberg. * Genetic and Evolutionary Computation Conference (GECCO-99), pp. 525-532 * (1999) - * + * * @author seitz - * + * */ public class BOA implements InterfaceOptimizer, java.io.Serializable { // private static boolean TRACE = false; - private static final Logger LOGGER = Logger.getLogger(BOA.class.getName()); - transient private InterfacePopulationChangedEventListener m_Listener = null; - private String m_Identifier = "BOA"; - - private int probDim = 8; - private int fitCrit = -1; - private int PopSize = 50; - private int numberOfParents = 3; - private transient BayNet network = null; - private Population population = new Population(); - private AbstractOptimizationProblem problem = new BKnapsackProblem(); - private AbstractEAIndividual template = null; - private double learningSetRatio = 0.5; - private double resampleRatio = 0.5; - private double upperProbLimit = 0.9; - private double lowerProbLimit = 0.1; - private int count = 0; - private String netFolder = "BOAOutput"; - private int[][] edgeRate = null; - - private BOAScoringMethods scoringMethod = BOAScoringMethods.BDM; - private boolean printNetworks = false; - private boolean printEdgeRate = false; - private boolean printTimestamps = false; - private boolean printMetrics = false; + private static final Logger LOGGER = Logger.getLogger(BOA.class.getName()); + transient private InterfacePopulationChangedEventListener m_Listener = null; + private String m_Identifier = "BOA"; + private int probDim = 8; + private int fitCrit = -1; + private int PopSize = 50; + private int numberOfParents = 3; + private transient BayNet network = null; + private Population population = new Population(); + private AbstractOptimizationProblem problem = new BKnapsackProblem(); + private AbstractEAIndividual template = null; + private double learningSetRatio = 0.5; + private double resampleRatio = 0.5; + private double upperProbLimit = 0.9; + private double lowerProbLimit = 0.1; + private int count = 0; + private String netFolder = "BOAOutput"; + private int[][] edgeRate = null; + private BOAScoringMethods scoringMethod = BOAScoringMethods.BDM; + private boolean printNetworks = false; + private boolean printEdgeRate = false; + private boolean printTimestamps = false; + private boolean printMetrics = false; // private boolean printExtraOutput = false; - public BOA() { + public BOA() { + } - } - - public BOA(int numberOfParents, int popSize, BOAScoringMethods method, - double learningSetRatio, double resampleRatio, String outputFolder, - double upperProbLimit, double lowerProbLimit, boolean printNetworks, - boolean printEdgeRate, boolean printMetrics, boolean printTimestamps) { - this.numberOfParents = numberOfParents; - this.PopSize = popSize; - this.scoringMethod = method; - this.learningSetRatio = learningSetRatio; - this.resampleRatio = resampleRatio; - this.netFolder = outputFolder; + public BOA(int numberOfParents, int popSize, BOAScoringMethods method, + double learningSetRatio, double resampleRatio, String outputFolder, + double upperProbLimit, double lowerProbLimit, boolean printNetworks, + boolean printEdgeRate, boolean printMetrics, boolean printTimestamps) { + this.numberOfParents = numberOfParents; + this.PopSize = popSize; + this.scoringMethod = method; + this.learningSetRatio = learningSetRatio; + this.resampleRatio = resampleRatio; + this.netFolder = outputFolder; // this.printExtraOutput = printExtraOutput; - this.upperProbLimit = upperProbLimit; - this.lowerProbLimit = lowerProbLimit; - this.printEdgeRate = printEdgeRate; - this.printNetworks = printNetworks; - this.printMetrics = printMetrics; - this.printTimestamps = printTimestamps; + this.upperProbLimit = upperProbLimit; + this.lowerProbLimit = lowerProbLimit; + this.printEdgeRate = printEdgeRate; + this.printNetworks = printNetworks; + this.printMetrics = printMetrics; + this.printTimestamps = printTimestamps; // if (printEdgeRate || printNetworks || printMetrics || printTimestamps) { // this.printExtraOutput = true; // } - } + } - public BOA(BOA b) { - this.m_Listener = b.m_Listener; - this.m_Identifier = b.m_Identifier; - this.probDim = b.probDim; - this.fitCrit = b.fitCrit; - this.PopSize = b.PopSize; - this.numberOfParents = b.numberOfParents; - this.network = (BayNet) b.network.clone(); - this.population = (Population) b.population.clone(); - this.problem = (AbstractOptimizationProblem) b.problem.clone(); - this.template = (AbstractEAIndividual) b.template.clone(); - this.learningSetRatio = b.learningSetRatio; - this.resampleRatio = b.resampleRatio; - this.upperProbLimit = b.upperProbLimit; - this.lowerProbLimit = b.lowerProbLimit; - this.count = b.count; - this.netFolder = b.netFolder; - this.scoringMethod = b.scoringMethod; - this.edgeRate = new int[b.edgeRate.length][b.edgeRate.length]; - for (int i = 0; i < this.edgeRate.length; i++) { - for (int j = 0; j < this.edgeRate[i].length; j++) { - this.edgeRate[i][j] = b.edgeRate[i][j]; - } - } - this.scoringMethod = b.scoringMethod; + public BOA(BOA b) { + this.m_Listener = b.m_Listener; + this.m_Identifier = b.m_Identifier; + this.probDim = b.probDim; + this.fitCrit = b.fitCrit; + this.PopSize = b.PopSize; + this.numberOfParents = b.numberOfParents; + this.network = (BayNet) b.network.clone(); + this.population = (Population) b.population.clone(); + this.problem = (AbstractOptimizationProblem) b.problem.clone(); + this.template = (AbstractEAIndividual) b.template.clone(); + this.learningSetRatio = b.learningSetRatio; + this.resampleRatio = b.resampleRatio; + this.upperProbLimit = b.upperProbLimit; + this.lowerProbLimit = b.lowerProbLimit; + this.count = b.count; + this.netFolder = b.netFolder; + this.scoringMethod = b.scoringMethod; + this.edgeRate = new int[b.edgeRate.length][b.edgeRate.length]; + for (int i = 0; i < this.edgeRate.length; i++) { + for (int j = 0; j < this.edgeRate[i].length; j++) { + this.edgeRate[i][j] = b.edgeRate[i][j]; + } + } + this.scoringMethod = b.scoringMethod; // this.printExtraOutput = b.printExtraOutput; - this.printNetworks = b.printNetworks; - this.printMetrics = b.printMetrics; - this.printEdgeRate = b.printEdgeRate; - this.printTimestamps = b.printTimestamps; - } + this.printNetworks = b.printNetworks; + this.printMetrics = b.printMetrics; + this.printEdgeRate = b.printEdgeRate; + this.printTimestamps = b.printTimestamps; + } @Override - public Object clone() { - return new BOA(this); - } + public Object clone() { + return new BOA(this); + } @Override - public String getName() { - return "Bayesian Optimization Algorithm"; - } + public String getName() { + return "Bayesian Optimization Algorithm"; + } - public static String globalInfo() { - return "Basic implementation of the Bayesian Optimization Algorithm based on the works by Martin Pelikan and David E. Goldberg."; - } + public static String globalInfo() { + return "Basic implementation of the Bayesian Optimization Algorithm based on the works by Martin Pelikan and David E. Goldberg."; + } - public void hideHideable() { + public void hideHideable() { // GenericObjectEditor // .setHideProperty(this.getClass(), "population", true); // GenericObjectEditor.setHideProperty(getClass(), "printNetworks", @@ -154,584 +151,574 @@ public class BOA implements InterfaceOptimizer, java.io.Serializable { // !printExtraOutput); // GenericObjectEditor.setHideProperty(getClass(), "printTimestamps", // !printExtraOutput); - } + } @Override - public void addPopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - this.m_Listener = ea; - } + public void addPopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + this.m_Listener = ea; + } - private void createDirectoryIfNeeded(String directoryName) { - File theDir = new File(directoryName); - // if the directory does not exist, create it - if (!theDir.exists()) { - LOGGER.log(Level.INFO, "creating directory: "+directoryName); - theDir.mkdir(); - } - } + private void createDirectoryIfNeeded(String directoryName) { + File theDir = new File(directoryName); + // if the directory does not exist, create it + if (!theDir.exists()) { + LOGGER.log(Level.INFO, "creating directory: " + directoryName); + theDir.mkdir(); + } + } @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener == ea) { - m_Listener = null; - return true; - } else { - return false; - } - } + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } - private static BitSet getBinaryData(AbstractEAIndividual indy) { - if (indy instanceof InterfaceGAIndividual) { - return ((InterfaceGAIndividual) indy).getBGenotype(); - } - else if (indy instanceof InterfaceDataTypeBinary) { - return ((InterfaceDataTypeBinary) indy).getBinaryData(); - } - else { - throw new RuntimeException( - "Unable to get binary representation for " - + indy.getClass()); - } - } + private static BitSet getBinaryData(AbstractEAIndividual indy) { + if (indy instanceof InterfaceGAIndividual) { + return ((InterfaceGAIndividual) indy).getBGenotype(); + } else if (indy instanceof InterfaceDataTypeBinary) { + return ((InterfaceDataTypeBinary) indy).getBinaryData(); + } else { + throw new RuntimeException( + "Unable to get binary representation for " + + indy.getClass()); + } + } - /** - * evaluate the given Individual and increments the counter. if the - * individual is null, only the counter is incremented - * - * @param indy - * the individual you want to evaluate - */ - private void evaluate(AbstractEAIndividual indy) { - // evaluate the given individual if it is not null - if (indy == null) { - LOGGER.log(Level.WARNING, "tried to evaluate null"); - return; - } - this.problem.evaluate(indy); - // increment the number of evaluations - this.population.incrFunctionCalls(); - } + /** + * evaluate the given Individual and increments the counter. if the + * individual is null, only the counter is incremented + * + * @param indy the individual you want to evaluate + */ + private void evaluate(AbstractEAIndividual indy) { + // evaluate the given individual if it is not null + if (indy == null) { + LOGGER.log(Level.WARNING, "tried to evaluate null"); + return; + } + this.problem.evaluate(indy); + // increment the number of evaluations + this.population.incrFunctionCalls(); + } - /** - * the default initialization - */ - private void defaultInit() { - this.count = 0; + /** + * the default initialization + */ + private void defaultInit() { + this.count = 0; // if (printExtraOutput) { - if (printTimestamps) { - printTimeStamp(); - } + if (printTimestamps) { + printTimeStamp(); + } // } - if (population == null) { - this.population = new Population(this.PopSize); - } else { - this.population.setTargetPopSize(this.PopSize); - } - this.template = this.problem.getIndividualTemplate(); - if (!(template instanceof InterfaceDataTypeBinary)) { - LOGGER.log(Level.WARNING, "Requiring binary data!"); - } else { - Object dim = BeanInspector.callIfAvailable(problem, - "getProblemDimension", null); - if (dim == null) { - LOGGER.log(Level.WARNING, "Coudn't get problem dimension!"); - } - probDim = (Integer) dim; - ((InterfaceDataTypeBinary) this.template) - .SetBinaryGenotype(new BitSet(probDim)); - } - this.network = new BayNet(this.probDim, upperProbLimit, lowerProbLimit); - this.network.setScoringMethod(this.scoringMethod); - this.edgeRate = new int[this.probDim][this.probDim]; - } - - @Override - public void init() { - defaultInit(); - this.problem.initPopulation(this.population); - this.evaluatePopulation(this.population); - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } - - private void evaluatePopulation(Population pop) { - for (int i = 0; i < pop.size(); i++) { - evaluate(pop.getEAIndividual(i)); - } - } - - @Override - public void initByPopulation(Population pop, boolean reset) { - if (reset) { - init(); - } else { - defaultInit(); - this.population = pop; - } - } - - private void generateGreedy(Population pop) { - this.network = new BayNet(this.probDim, upperProbLimit, lowerProbLimit); - this.network.setScoringMethod(this.scoringMethod); - boolean improvement = true; - this.network.initScoreArray(pop); - double score = this.network.getNewScore(pop, -1); - double score1 = score; - List> bestNetworks = new LinkedList>(); - while (improvement) { - improvement = false; - for (int i = 0; i < this.probDim; i++) { - for (int j = 0; j < this.probDim; j++) { - // if we are allowed to add the edge - if ((!this.network.hasEdge(i, j)) - && (i != j) - && (this.network.getNode(j).getNumberOfParents() < this.numberOfParents)) { - // add the edge - this.network.addEdge(i, j); - // if it is still acyclic - if (this.network.isACyclic(i, j)) { - // calculate the new score - double tmpScore = this.network.getNewScore(pop, j); - // if we have a score larger or equal to the current score - if (tmpScore >= score && tmpScore != score1) { - // if the score is equal - if (tmpScore == score) { - // add the edge to the list of possible new edges - bestNetworks - .add(new Pair(i, - j)); - // if we have a better score - } else { - // delete the current possible edges - bestNetworks.clear(); - // add the edge to the list fo possible new edges - bestNetworks - .add(new Pair(i, - j)); - // adapt the score - score = tmpScore; - // we could improve the network - improvement = true; - } - } - } - // remove the edge from the network and try the next one - this.network.removeEdge(i, j); - } - } - } - // if we found at least one edge that could improve the network - if (bestNetworks.size() > 0) { - // get one edge randomly from the list of possible edges - int val = RNG.randomInt(bestNetworks.size()); - Pair pair = bestNetworks.get(val); - // add it to the network - this.network.addEdge(pair.getHead(), pair.getTail()); - // adapt the array that allowes the fast calculation of the scores - this.network.updateScoreArray(pop, pair.getTail()); - } - // adapt the score - score = this.network.getNewScore(pop, -1); - score1 = score; - bestNetworks.clear(); - } - score = this.network.getScore(pop); - } - - /** - * Generate a Bayesian network with the individuals of the population as a - * reference Point - * - * @param pop - * the individuals the network is based on - */ - private void constructNetwork(Population pop) { - generateGreedy(pop); - } - - /** - * generate new individuals based on the bayesian network - * - * @return the new individuals - */ - private Population generateNewIndys(int sampleSetSize) { - Population pop = new Population(sampleSetSize); - LOGGER.log(Level.CONFIG, "Resampling " + sampleSetSize + " indies..."); - while (pop.size() < sampleSetSize) { - AbstractEAIndividual indy = (AbstractEAIndividual) this.template - .clone(); - BitSet data = this.network.sample(getBinaryData(indy)); - ((InterfaceDataTypeBinary) indy).SetBinaryGenotype(data); - evaluate(indy); - pop.add(indy); - } - return pop; - } - - /** - * Calculate a plausible number of individuals to be resampled per - * iteration. - * - * @return - */ - private int calcResampleSetSize() { - int result = (int) Math.min(PopSize, - Math.max(1.0, ((double) PopSize) * resampleRatio)); - return result; - } - - /** - * Calculate a plausible number of individuals from which the BayNet is - * learned. In principle this can be independent of the resampling set size. - * - * @return - */ - private int calcLearningSetSize() { - return (int) Math.min(PopSize, - Math.max(1.0, ((double) PopSize) * learningSetRatio)); - } - - /** - * remove the individuals in pop from the population - * @param pop - */ - public void remove(Population pop) { - for (Object indy : pop) { - this.population.remove(indy); - } - } - - private void printEdgeRate() { - String filename = this.netFolder + "/edgeRate.m"; - Writer w = null; - PrintWriter out = null; - String message = "edgeRate" + this.scoringMethod + " = ["; - createDirectoryIfNeeded(this.netFolder); - for (int i = 0; i < this.edgeRate.length; i++) { - for (int j = 0; j < this.edgeRate.length; j++) { - message += (((double) edgeRate[i][j]) / (this.count + 1)); - if (j != this.edgeRate.length - 1) { - message += ","; - } - } - if (i != this.edgeRate.length - 1) { - message += ";"; - } - } - message += "];"; - try { - w = new FileWriter(filename); - out = new PrintWriter(w); - out.write(message); - } catch (IOException e) { - e.printStackTrace(); - } finally { - out.close(); - try { - w.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - private void printNetworkToFile(String i) { - String filename = this.netFolder + "/network_" + i + ".graphml"; - Writer w = null; - PrintWriter out = null; - String message = this.network.generateYFilesCode(); - createDirectoryIfNeeded(this.netFolder); - try { - w = new FileWriter(filename); - out = new PrintWriter(w); - out.write(message); - } catch (Exception e) { - e.printStackTrace(); - } finally { - out.close(); - try { - w.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - private void printTimeStamp() { - String fileName = this.netFolder + "/timestamps.txt"; - Date d = new Date(); - DateFormat df = DateFormat.getTimeInstance(DateFormat.MEDIUM); - String message = this.count + "\t" + df.format(d) + "\n"; - createDirectoryIfNeeded(this.netFolder); - boolean exists = (new File(fileName)).exists(); - if (exists) { - try { - // Create file - FileWriter fstream = new FileWriter((fileName), true); - BufferedWriter out = new BufferedWriter(fstream); - - out.write(message); - out.newLine(); - // Close the output stream - out.close(); - } catch (Exception e) {// Catch exception if any - LOGGER.log(Level.WARNING, "Error: ", e); - } - - } else { - try { - // Create file - FileWriter fstream = new FileWriter((fileName), false); - BufferedWriter out = new BufferedWriter(fstream); - out.newLine(); - out.write(message); - out.newLine(); - // Close the output stream - out.close(); - } catch (Exception e) {// Catch exception if any - LOGGER.log(Level.WARNING, "Error: ", e); - } - } - } - - private void printMetrics(Population pop) { - this.network.setScoringMethod(BOAScoringMethods.BDM); - double bdmMetric = this.network.getScore(pop); - this.network.setScoringMethod(BOAScoringMethods.K2); - double k2Metric = this.network.getScore(pop); - this.network.setScoringMethod(BOAScoringMethods.BIC); - double bicMetric = this.network.getScore(pop); - this.network.setScoringMethod(this.scoringMethod); - String fileName = this.netFolder + "/" + "metrics.csv"; - createDirectoryIfNeeded(this.netFolder); - boolean exists = (new File(fileName)).exists(); - if (exists) { - try { - // Create file - FileWriter fstream = new FileWriter((fileName), true); - BufferedWriter out = new BufferedWriter(fstream); - - out.write("" + bdmMetric + "," + k2Metric + "," + bicMetric); - out.newLine(); - // Close the output stream - out.close(); - } catch (Exception e) {// Catch exception if any - LOGGER.log(Level.WARNING, "Error: ", e); - } - - } else { - try { - // Create file - FileWriter fstream = new FileWriter((fileName), false); - BufferedWriter out = new BufferedWriter(fstream); - out.write("BDMMetric, " + "K2Metric, " + "BIC"); - out.newLine(); - out.write("" + bdmMetric + "," + k2Metric + "," + bicMetric); - out.newLine(); - // Close the output stream - out.close(); - } catch (Exception e) {// Catch exception if any - LOGGER.log(Level.WARNING, "Error: ", e); - } - } - } - - @Override - public void optimize() { - this.problem.evaluatePopulationStart(this.population); - // get the best individuals from the population - Population best = this.population.getBestNIndividuals( - calcLearningSetSize(), this.fitCrit); - // generate the network with these individuals - constructNetwork(best); -// if(this.printExtraOutput && this.printEdgeRate){ - if(this.printEdgeRate){ - this.edgeRate = this.network.adaptEdgeRate(this.edgeRate); - } - // sample new individuals from the network - Population newlyGenerated = generateNewIndys(calcResampleSetSize()); - // remove the worst individuals from the population - Population toRemove = this.population.getWorstNIndividuals( - calcResampleSetSize(), this.fitCrit); - remove(toRemove); - // add the newly generated Individuals to the population - this.population.addAll(newlyGenerated); - this.count++; - // we are done with one generation - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - this.problem.evaluatePopulationEnd(this.population); - // print output if desired -// if (this.printExtraOutput) { - if (printNetworks) { - printNetworkToFile("" + this.count); - } - if (printEdgeRate) { - printEdgeRate(); - } - if (printMetrics) { - printMetrics(best); - } - if (printTimestamps) { - printTimeStamp(); - } -// } - } - - /** - * Something has changed - */ - protected void firePropertyChangedEvent(String name) { - if (this.m_Listener != null) { - this.m_Listener.registerPopulationStateChanged(this, name); + if (population == null) { + this.population = new Population(this.PopSize); + } else { + this.population.setTargetPopSize(this.PopSize); + } + this.template = this.problem.getIndividualTemplate(); + if (!(template instanceof InterfaceDataTypeBinary)) { + LOGGER.log(Level.WARNING, "Requiring binary data!"); + } else { + Object dim = BeanInspector.callIfAvailable(problem, + "getProblemDimension", null); + if (dim == null) { + LOGGER.log(Level.WARNING, "Coudn't get problem dimension!"); } - } + probDim = (Integer) dim; + ((InterfaceDataTypeBinary) this.template) + .SetBinaryGenotype(new BitSet(probDim)); + } + this.network = new BayNet(this.probDim, upperProbLimit, lowerProbLimit); + this.network.setScoringMethod(this.scoringMethod); + this.edgeRate = new int[this.probDim][this.probDim]; + } @Override - public Population getPopulation() { - return this.population; - } + public void init() { + defaultInit(); + this.problem.initPopulation(this.population); + this.evaluatePopulation(this.population); + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + } + + private void evaluatePopulation(Population pop) { + for (int i = 0; i < pop.size(); i++) { + evaluate(pop.getEAIndividual(i)); + } + } @Override - public void setPopulation(Population pop) { - this.population = pop; - } + public void initByPopulation(Population pop, boolean reset) { + if (reset) { + init(); + } else { + defaultInit(); + this.population = pop; + } + } + + private void generateGreedy(Population pop) { + this.network = new BayNet(this.probDim, upperProbLimit, lowerProbLimit); + this.network.setScoringMethod(this.scoringMethod); + boolean improvement = true; + this.network.initScoreArray(pop); + double score = this.network.getNewScore(pop, -1); + double score1 = score; + List> bestNetworks = new LinkedList>(); + while (improvement) { + improvement = false; + for (int i = 0; i < this.probDim; i++) { + for (int j = 0; j < this.probDim; j++) { + // if we are allowed to add the edge + if ((!this.network.hasEdge(i, j)) + && (i != j) + && (this.network.getNode(j).getNumberOfParents() < this.numberOfParents)) { + // add the edge + this.network.addEdge(i, j); + // if it is still acyclic + if (this.network.isACyclic(i, j)) { + // calculate the new score + double tmpScore = this.network.getNewScore(pop, j); + // if we have a score larger or equal to the current score + if (tmpScore >= score && tmpScore != score1) { + // if the score is equal + if (tmpScore == score) { + // add the edge to the list of possible new edges + bestNetworks + .add(new Pair(i, + j)); + // if we have a better score + } else { + // delete the current possible edges + bestNetworks.clear(); + // add the edge to the list fo possible new edges + bestNetworks + .add(new Pair(i, + j)); + // adapt the score + score = tmpScore; + // we could improve the network + improvement = true; + } + } + } + // remove the edge from the network and try the next one + this.network.removeEdge(i, j); + } + } + } + // if we found at least one edge that could improve the network + if (bestNetworks.size() > 0) { + // get one edge randomly from the list of possible edges + int val = RNG.randomInt(bestNetworks.size()); + Pair pair = bestNetworks.get(val); + // add it to the network + this.network.addEdge(pair.getHead(), pair.getTail()); + // adapt the array that allowes the fast calculation of the scores + this.network.updateScoreArray(pop, pair.getTail()); + } + // adapt the score + score = this.network.getNewScore(pop, -1); + score1 = score; + bestNetworks.clear(); + } + score = this.network.getScore(pop); + } + + /** + * Generate a Bayesian network with the individuals of the population as a + * reference Point + * + * @param pop the individuals the network is based on + */ + private void constructNetwork(Population pop) { + generateGreedy(pop); + } + + /** + * generate new individuals based on the bayesian network + * + * @return the new individuals + */ + private Population generateNewIndys(int sampleSetSize) { + Population pop = new Population(sampleSetSize); + LOGGER.log(Level.CONFIG, "Resampling " + sampleSetSize + " indies..."); + while (pop.size() < sampleSetSize) { + AbstractEAIndividual indy = (AbstractEAIndividual) this.template + .clone(); + BitSet data = this.network.sample(getBinaryData(indy)); + ((InterfaceDataTypeBinary) indy).SetBinaryGenotype(data); + evaluate(indy); + pop.add(indy); + } + return pop; + } + + /** + * Calculate a plausible number of individuals to be resampled per + * iteration. + * + * @return + */ + private int calcResampleSetSize() { + int result = (int) Math.min(PopSize, + Math.max(1.0, ((double) PopSize) * resampleRatio)); + return result; + } + + /** + * Calculate a plausible number of individuals from which the BayNet is + * learned. In principle this can be independent of the resampling set size. + * + * @return + */ + private int calcLearningSetSize() { + return (int) Math.min(PopSize, + Math.max(1.0, ((double) PopSize) * learningSetRatio)); + } + + /** + * remove the individuals in pop from the population + * + * @param pop + */ + public void remove(Population pop) { + for (Object indy : pop) { + this.population.remove(indy); + } + } + + private void printEdgeRate() { + String filename = this.netFolder + "/edgeRate.m"; + Writer w = null; + PrintWriter out = null; + String message = "edgeRate" + this.scoringMethod + " = ["; + createDirectoryIfNeeded(this.netFolder); + for (int i = 0; i < this.edgeRate.length; i++) { + for (int j = 0; j < this.edgeRate.length; j++) { + message += (((double) edgeRate[i][j]) / (this.count + 1)); + if (j != this.edgeRate.length - 1) { + message += ","; + } + } + if (i != this.edgeRate.length - 1) { + message += ";"; + } + } + message += "];"; + try { + w = new FileWriter(filename); + out = new PrintWriter(w); + out.write(message); + } catch (IOException e) { + e.printStackTrace(); + } finally { + out.close(); + try { + w.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + private void printNetworkToFile(String i) { + String filename = this.netFolder + "/network_" + i + ".graphml"; + Writer w = null; + PrintWriter out = null; + String message = this.network.generateYFilesCode(); + createDirectoryIfNeeded(this.netFolder); + try { + w = new FileWriter(filename); + out = new PrintWriter(w); + out.write(message); + } catch (Exception e) { + e.printStackTrace(); + } finally { + out.close(); + try { + w.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + private void printTimeStamp() { + String fileName = this.netFolder + "/timestamps.txt"; + Date d = new Date(); + DateFormat df = DateFormat.getTimeInstance(DateFormat.MEDIUM); + String message = this.count + "\t" + df.format(d) + "\n"; + createDirectoryIfNeeded(this.netFolder); + boolean exists = (new File(fileName)).exists(); + if (exists) { + try { + // Create file + FileWriter fstream = new FileWriter((fileName), true); + BufferedWriter out = new BufferedWriter(fstream); + + out.write(message); + out.newLine(); + // Close the output stream + out.close(); + } catch (Exception e) {// Catch exception if any + LOGGER.log(Level.WARNING, "Error: ", e); + } + + } else { + try { + // Create file + FileWriter fstream = new FileWriter((fileName), false); + BufferedWriter out = new BufferedWriter(fstream); + out.newLine(); + out.write(message); + out.newLine(); + // Close the output stream + out.close(); + } catch (Exception e) {// Catch exception if any + LOGGER.log(Level.WARNING, "Error: ", e); + } + } + } + + private void printMetrics(Population pop) { + this.network.setScoringMethod(BOAScoringMethods.BDM); + double bdmMetric = this.network.getScore(pop); + this.network.setScoringMethod(BOAScoringMethods.K2); + double k2Metric = this.network.getScore(pop); + this.network.setScoringMethod(BOAScoringMethods.BIC); + double bicMetric = this.network.getScore(pop); + this.network.setScoringMethod(this.scoringMethod); + String fileName = this.netFolder + "/" + "metrics.csv"; + createDirectoryIfNeeded(this.netFolder); + boolean exists = (new File(fileName)).exists(); + if (exists) { + try { + // Create file + FileWriter fstream = new FileWriter((fileName), true); + BufferedWriter out = new BufferedWriter(fstream); + + out.write("" + bdmMetric + "," + k2Metric + "," + bicMetric); + out.newLine(); + // Close the output stream + out.close(); + } catch (Exception e) {// Catch exception if any + LOGGER.log(Level.WARNING, "Error: ", e); + } + + } else { + try { + // Create file + FileWriter fstream = new FileWriter((fileName), false); + BufferedWriter out = new BufferedWriter(fstream); + out.write("BDMMetric, " + "K2Metric, " + "BIC"); + out.newLine(); + out.write("" + bdmMetric + "," + k2Metric + "," + bicMetric); + out.newLine(); + // Close the output stream + out.close(); + } catch (Exception e) {// Catch exception if any + LOGGER.log(Level.WARNING, "Error: ", e); + } + } + } @Override - public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(this.population); - } + public void optimize() { + this.problem.evaluatePopulationStart(this.population); + // get the best individuals from the population + Population best = this.population.getBestNIndividuals( + calcLearningSetSize(), this.fitCrit); + // generate the network with these individuals + constructNetwork(best); +// if(this.printExtraOutput && this.printEdgeRate){ + if (this.printEdgeRate) { + this.edgeRate = this.network.adaptEdgeRate(this.edgeRate); + } + // sample new individuals from the network + Population newlyGenerated = generateNewIndys(calcResampleSetSize()); + // remove the worst individuals from the population + Population toRemove = this.population.getWorstNIndividuals( + calcResampleSetSize(), this.fitCrit); + remove(toRemove); + // add the newly generated Individuals to the population + this.population.addAll(newlyGenerated); + this.count++; + // we are done with one generation + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + this.problem.evaluatePopulationEnd(this.population); + // print output if desired +// if (this.printExtraOutput) { + if (printNetworks) { + printNetworkToFile("" + this.count); + } + if (printEdgeRate) { + printEdgeRate(); + } + if (printMetrics) { + printMetrics(best); + } + if (printTimestamps) { + printTimeStamp(); + } +// } + } + + /** + * Something has changed + */ + protected void firePropertyChangedEvent(String name) { + if (this.m_Listener != null) { + this.m_Listener.registerPopulationStateChanged(this, name); + } + } @Override - public void setIdentifier(String name) { - this.m_Identifier = name; - } + public Population getPopulation() { + return this.population; + } @Override - public String getIdentifier() { - return this.m_Identifier; - } + public void setPopulation(Population pop) { + this.population = pop; + } @Override - public void setProblem(InterfaceOptimizationProblem problem) { - this.problem = (AbstractOptimizationProblem) problem; - } + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(this.population); + } @Override - public InterfaceOptimizationProblem getProblem() { - return this.problem; - } + public void setIdentifier(String name) { + this.m_Identifier = name; + } @Override - public String getStringRepresentation() { - return "Bayesian Network"; - } + public String getIdentifier() { + return this.m_Identifier; + } @Override - public void freeWilly() { + public void setProblem(InterfaceOptimizationProblem problem) { + this.problem = (AbstractOptimizationProblem) problem; + } - } + @Override + public InterfaceOptimizationProblem getProblem() { + return this.problem; + } - // ------------------------------- - // -------------GUI--------------- - // ------------------------------- + @Override + public String getStringRepresentation() { + return "Bayesian Network"; + } - public int getNumberOfParents() { - return this.numberOfParents; - } + // ------------------------------- + // -------------GUI--------------- + // ------------------------------- + public int getNumberOfParents() { + return this.numberOfParents; + } - public void setNumberOfParents(int i) { - this.numberOfParents = i; - } + public void setNumberOfParents(int i) { + this.numberOfParents = i; + } - public String numberOfParentsTipText() { - return "The maximum number of parents a node in the Bayesian Network can have"; - } + public String numberOfParentsTipText() { + return "The maximum number of parents a node in the Bayesian Network can have"; + } - public String replaceNetworkTipText() { - return "if set, the network will be completely replaced. If not, it will be tried to improve the last network, if that is not possible, it will be replaced"; - } + public String replaceNetworkTipText() { + return "if set, the network will be completely replaced. If not, it will be tried to improve the last network, if that is not possible, it will be replaced"; + } - public BOAScoringMethods getNetworkGenerationMethod() { - return this.scoringMethod; - } + public BOAScoringMethods getNetworkGenerationMethod() { + return this.scoringMethod; + } - public void setNetworkGenerationMethod(BOAScoringMethods n) { - this.scoringMethod = n; - } + public void setNetworkGenerationMethod(BOAScoringMethods n) { + this.scoringMethod = n; + } - public String networkGenerationMethodTipText() { - return "The Method with which the Bayesian Network will be gererated"; - } + public String networkGenerationMethodTipText() { + return "The Method with which the Bayesian Network will be gererated"; + } - public int getPopulationSize() { - return PopSize; - } + public int getPopulationSize() { + return PopSize; + } - public void setPopulationSize(int popSize) { - PopSize = popSize; - } + public void setPopulationSize(int popSize) { + PopSize = popSize; + } - public String populationSizeTipText() { - return "Define the pool size used by BOA"; - } + public String populationSizeTipText() { + return "Define the pool size used by BOA"; + } - public double getResamplingRatio() { - return resampleRatio; - } + public double getResamplingRatio() { + return resampleRatio; + } - public void setResamplingRatio(double resampleRat) { - this.resampleRatio = resampleRat; - } + public void setResamplingRatio(double resampleRat) { + this.resampleRatio = resampleRat; + } - public String resamplingRatioTipText() { - return "Ratio of individuals to be resampled from the Bayesian network per iteration"; - } + public String resamplingRatioTipText() { + return "Ratio of individuals to be resampled from the Bayesian network per iteration"; + } - public double getLearningRatio() { - return learningSetRatio; - } + public double getLearningRatio() { + return learningSetRatio; + } - public void setLearningRatio(double rat) { - this.learningSetRatio = rat; - } + public void setLearningRatio(double rat) { + this.learningSetRatio = rat; + } - public String learningRatioTipText() { - return "Ratio of individuals to be used to learn the Bayesian network"; - } + public String learningRatioTipText() { + return "Ratio of individuals to be used to learn the Bayesian network"; + } - public double getProbLimitHigh() { - return upperProbLimit; - } + public double getProbLimitHigh() { + return upperProbLimit; + } - public void setProbLimitHigh(double upperProbLimit) { - this.upperProbLimit = upperProbLimit; - } + public void setProbLimitHigh(double upperProbLimit) { + this.upperProbLimit = upperProbLimit; + } - public String probLimitHighTipText() { - return "the upper limit of the probability to set one Bit to 1"; - } + public String probLimitHighTipText() { + return "the upper limit of the probability to set one Bit to 1"; + } - public double getProbLimitLow() { - return lowerProbLimit; - } + public double getProbLimitLow() { + return lowerProbLimit; + } - public void setProbLimitLow(double lowerProbLimit) { - this.lowerProbLimit = lowerProbLimit; - } + public void setProbLimitLow(double lowerProbLimit) { + this.lowerProbLimit = lowerProbLimit; + } - public String probLimitLowTipText() { - return "the lower limit of the probability to set one Bit to 1"; - } + public String probLimitLowTipText() { + return "the lower limit of the probability to set one Bit to 1"; + } - public String[] customPropertyOrder() { - return new String[] { "learningRatio", "resamplingRatio" }; - } + public String[] customPropertyOrder() { + return new String[]{"learningRatio", "resamplingRatio"}; + } // public boolean isPrintExtraOutput() { // return this.printExtraOutput; // } - // public void setPrintExtraOutput(boolean b) { // this.printExtraOutput = b; // GenericObjectEditor.setHideProperty(getClass(), "printNetworks", @@ -743,242 +730,238 @@ public class BOA implements InterfaceOptimizer, java.io.Serializable { // GenericObjectEditor.setHideProperty(getClass(), "printTimestamps", // !printExtraOutput); // } - // public String printExtraOutputTipText() { // return "do you want to print extra output files"; // } + public boolean isPrintNetworks() { + return this.printNetworks; + } - public boolean isPrintNetworks() { - return this.printNetworks; - } + public void setPrintNetworks(boolean b) { + this.printNetworks = b; + } - public void setPrintNetworks(boolean b) { - this.printNetworks = b; - } + public String printNetworksTipText() { + return "Print the underlying networks of each generation"; + } - public String printNetworksTipText() { - return "Print the underlying networks of each generation"; - } + public boolean isPrintEdgeRate() { + return this.printEdgeRate; + } - public boolean isPrintEdgeRate() { - return this.printEdgeRate; - } + public void setPrintEdgeRate(boolean b) { + this.printEdgeRate = b; + } - public void setPrintEdgeRate(boolean b) { - this.printEdgeRate = b; - } + public String printEdgeRateTipText() { + return "Print the rate with which each edge is used in the optimization run"; + } - public String printEdgeRateTipText() { - return "Print the rate with which each edge is used in the optimization run"; - } + public boolean isPrintMetrics() { + return this.printMetrics; + } - public boolean isPrintMetrics() { - return this.printMetrics; - } + public void setPrintMetrics(boolean b) { + this.printMetrics = b; + } - public void setPrintMetrics(boolean b) { - this.printMetrics = b; - } + public String printMetricsTipText() { + return "Print the values of all the metrics for every network"; + } - public String printMetricsTipText() { - return "Print the values of all the metrics for every network"; - } + public boolean isPrintTimestamps() { + return this.printTimestamps; + } - public boolean isPrintTimestamps() { - return this.printTimestamps; - } + public void setPrintTimestamps(boolean b) { + this.printTimestamps = b; + } - public void setPrintTimestamps(boolean b) { - this.printTimestamps = b; - } + public String printTimestampsTipText() { + return "Print the time starting time and a timestamp after each generation"; + } - public String printTimestampsTipText() { - return "Print the time starting time and a timestamp after each generation"; - } - + public static void main(String[] args) { + Population pop = new Population(); + GAIndividualBinaryData indy1 = new GAIndividualBinaryData(); + indy1.setBinaryDataLength(8); + GAIndividualBinaryData indy2 = (GAIndividualBinaryData) indy1.clone(); + GAIndividualBinaryData indy3 = (GAIndividualBinaryData) indy1.clone(); + GAIndividualBinaryData indy4 = (GAIndividualBinaryData) indy1.clone(); + GAIndividualBinaryData indy5 = (GAIndividualBinaryData) indy1.clone(); + BitSet data1 = indy1.getBinaryData(); + BitSet data2 = indy2.getBinaryData(); + BitSet data3 = indy3.getBinaryData(); + BitSet data4 = indy4.getBinaryData(); + BitSet data5 = indy5.getBinaryData(); + BitSet data6 = indy5.getBinaryData(); + BitSet data7 = indy5.getBinaryData(); + BitSet data8 = indy5.getBinaryData(); + BitSet data9 = indy5.getBinaryData(); + BitSet data10 = indy5.getBinaryData(); + BitSet data11 = indy5.getBinaryData(); + BitSet data12 = indy5.getBinaryData(); + BitSet data13 = indy5.getBinaryData(); + BitSet data14 = indy5.getBinaryData(); + BitSet data15 = indy5.getBinaryData(); + BitSet data16 = indy5.getBinaryData(); - public static void main(String[] args) { - Population pop = new Population(); - GAIndividualBinaryData indy1 = new GAIndividualBinaryData(); - indy1.setBinaryDataLength(8); - GAIndividualBinaryData indy2 = (GAIndividualBinaryData) indy1.clone(); - GAIndividualBinaryData indy3 = (GAIndividualBinaryData) indy1.clone(); - GAIndividualBinaryData indy4 = (GAIndividualBinaryData) indy1.clone(); - GAIndividualBinaryData indy5 = (GAIndividualBinaryData) indy1.clone(); - BitSet data1 = indy1.getBinaryData(); - BitSet data2 = indy2.getBinaryData(); - BitSet data3 = indy3.getBinaryData(); - BitSet data4 = indy4.getBinaryData(); - BitSet data5 = indy5.getBinaryData(); - BitSet data6 = indy5.getBinaryData(); - BitSet data7 = indy5.getBinaryData(); - BitSet data8 = indy5.getBinaryData(); - BitSet data9 = indy5.getBinaryData(); - BitSet data10 = indy5.getBinaryData(); - BitSet data11 = indy5.getBinaryData(); - BitSet data12 = indy5.getBinaryData(); - BitSet data13 = indy5.getBinaryData(); - BitSet data14 = indy5.getBinaryData(); - BitSet data15 = indy5.getBinaryData(); - BitSet data16 = indy5.getBinaryData(); + data1.set(0, true); + data1.set(1, false); + data1.set(2, true); + data1.set(3, false); + data1.set(4, true); + data1.set(5, true); + data1.set(6, false); + data1.set(7, false); - data1.set(0, true); - data1.set(1, false); - data1.set(2, true); - data1.set(3, false); - data1.set(4, true); - data1.set(5, true); - data1.set(6, false); - data1.set(7, false); + data5.set(0, true); + data5.set(1, false); + data5.set(2, true); + data5.set(3, false); + data5.set(4, false); + data5.set(5, true); + data5.set(6, true); + data5.set(7, true); + data6.set(0, true); + data6.set(1, false); + data6.set(2, true); + data6.set(3, false); + data6.set(4, true); + data6.set(5, true); + data6.set(6, false); + data6.set(7, false); + data7.set(0, true); + data7.set(1, false); + data7.set(2, true); + data7.set(3, false); + data7.set(4, true); + data7.set(5, true); + data7.set(6, false); + data7.set(7, false); - data5.set(0, true); - data5.set(1, false); - data5.set(2, true); - data5.set(3, false); - data5.set(4, false); - data5.set(5, true); - data5.set(6, true); - data5.set(7, true); - data6.set(0, true); - data6.set(1, false); - data6.set(2, true); - data6.set(3, false); - data6.set(4, true); - data6.set(5, true); - data6.set(6, false); - data6.set(7, false); - data7.set(0, true); - data7.set(1, false); - data7.set(2, true); - data7.set(3, false); - data7.set(4, true); - data7.set(5, true); - data7.set(6, false); - data7.set(7, false); + data2.set(0, true); + data2.set(1, false); + data2.set(2, true); + data2.set(3, false); + data2.set(4, true); + data2.set(5, true); + data2.set(6, false); + data2.set(7, false); + data8.set(0, true); + data8.set(1, false); + data8.set(2, true); + data8.set(3, false); + data8.set(4, true); + data8.set(5, true); + data8.set(6, false); + data8.set(7, false); + data9.set(0, true); + data9.set(1, false); + data9.set(2, true); + data9.set(3, false); + data9.set(4, true); + data9.set(5, true); + data9.set(6, false); + data9.set(7, false); + data10.set(0, true); + data10.set(1, false); + data10.set(2, true); + data10.set(3, false); + data10.set(4, true); + data10.set(5, true); + data10.set(6, false); + data10.set(7, false); - data2.set(0, true); - data2.set(1, false); - data2.set(2, true); - data2.set(3, false); - data2.set(4, true); - data2.set(5, true); - data2.set(6, false); - data2.set(7, false); - data8.set(0, true); - data8.set(1, false); - data8.set(2, true); - data8.set(3, false); - data8.set(4, true); - data8.set(5, true); - data8.set(6, false); - data8.set(7, false); - data9.set(0, true); - data9.set(1, false); - data9.set(2, true); - data9.set(3, false); - data9.set(4, true); - data9.set(5, true); - data9.set(6, false); - data9.set(7, false); - data10.set(0, true); - data10.set(1, false); - data10.set(2, true); - data10.set(3, false); - data10.set(4, true); - data10.set(5, true); - data10.set(6, false); - data10.set(7, false); + data3.set(0, true); + data3.set(1, false); + data3.set(2, true); + data3.set(3, false); + data3.set(4, false); + data3.set(5, false); + data3.set(6, true); + data3.set(7, true); + data11.set(0, true); + data11.set(1, false); + data11.set(2, true); + data11.set(3, false); + data11.set(4, false); + data11.set(5, false); + data11.set(6, true); + data11.set(7, true); + data12.set(0, true); + data12.set(1, false); + data12.set(2, true); + data12.set(3, false); + data12.set(4, false); + data12.set(5, false); + data12.set(6, true); + data12.set(7, true); + data13.set(0, true); + data13.set(1, false); + data13.set(2, true); + data13.set(3, false); + data13.set(4, false); + data13.set(5, false); + data13.set(6, true); + data13.set(7, true); - data3.set(0, true); - data3.set(1, false); - data3.set(2, true); - data3.set(3, false); - data3.set(4, false); - data3.set(5, false); - data3.set(6, true); - data3.set(7, true); - data11.set(0, true); - data11.set(1, false); - data11.set(2, true); - data11.set(3, false); - data11.set(4, false); - data11.set(5, false); - data11.set(6, true); - data11.set(7, true); - data12.set(0, true); - data12.set(1, false); - data12.set(2, true); - data12.set(3, false); - data12.set(4, false); - data12.set(5, false); - data12.set(6, true); - data12.set(7, true); - data13.set(0, true); - data13.set(1, false); - data13.set(2, true); - data13.set(3, false); - data13.set(4, false); - data13.set(5, false); - data13.set(6, true); - data13.set(7, true); - - data4.set(0, true); - data4.set(1, false); - data4.set(2, true); - data4.set(3, false); - data4.set(4, false); - data4.set(5, false); - data4.set(6, true); - data4.set(7, true); - data14.set(0, true); - data14.set(1, false); - data14.set(2, true); - data14.set(3, false); - data14.set(4, false); - data14.set(5, false); - data14.set(6, true); - data14.set(7, true); - data15.set(0, true); - data15.set(1, false); - data15.set(2, true); - data15.set(3, false); - data15.set(4, false); - data15.set(5, false); - data15.set(6, true); - data15.set(7, true); - data16.set(0, true); - data16.set(1, false); - data16.set(2, true); - data16.set(3, false); - data16.set(4, false); - data16.set(5, false); - data16.set(6, true); - data16.set(7, true); - - // data5.set(0, true); - // data5.set(1, true); - // data5.set(2, true); - indy1.SetBinaryGenotype(data1); - indy2.SetBinaryGenotype(data2); - indy3.SetBinaryGenotype(data3); - indy4.SetBinaryGenotype(data4); - indy5.SetBinaryGenotype(data5); - pop.add(indy1); - pop.add(indy2); - pop.add(indy3); - pop.add(indy4); - pop.add(indy5); - BOA b = new BOA(); - b.init(); - b.optimize(); - b.optimize(); - b.optimize(); - b.optimize(); - b.optimize(); - // b.generateGreedy(pop); - // System.out.println(pop.getStringRepresentation()); - // b.print(); - // b.printNetworkToFile("test"); - } + data4.set(0, true); + data4.set(1, false); + data4.set(2, true); + data4.set(3, false); + data4.set(4, false); + data4.set(5, false); + data4.set(6, true); + data4.set(7, true); + data14.set(0, true); + data14.set(1, false); + data14.set(2, true); + data14.set(3, false); + data14.set(4, false); + data14.set(5, false); + data14.set(6, true); + data14.set(7, true); + data15.set(0, true); + data15.set(1, false); + data15.set(2, true); + data15.set(3, false); + data15.set(4, false); + data15.set(5, false); + data15.set(6, true); + data15.set(7, true); + data16.set(0, true); + data16.set(1, false); + data16.set(2, true); + data16.set(3, false); + data16.set(4, false); + data16.set(5, false); + data16.set(6, true); + data16.set(7, true); + // data5.set(0, true); + // data5.set(1, true); + // data5.set(2, true); + indy1.SetBinaryGenotype(data1); + indy2.SetBinaryGenotype(data2); + indy3.SetBinaryGenotype(data3); + indy4.SetBinaryGenotype(data4); + indy5.SetBinaryGenotype(data5); + pop.add(indy1); + pop.add(indy2); + pop.add(indy3); + pop.add(indy4); + pop.add(indy5); + BOA b = new BOA(); + b.init(); + b.optimize(); + b.optimize(); + b.optimize(); + b.optimize(); + b.optimize(); + // b.generateGreedy(pop); + // System.out.println(pop.getStringRepresentation()); + // b.print(); + // b.printNetworkToFile("test"); + } } \ No newline at end of file diff --git a/src/eva2/server/go/strategies/BinaryScatterSearch.java b/src/eva2/server/go/strategies/BinaryScatterSearch.java index 1808b460..cb0d4fb2 100644 --- a/src/eva2/server/go/strategies/BinaryScatterSearch.java +++ b/src/eva2/server/go/strategies/BinaryScatterSearch.java @@ -27,875 +27,899 @@ import java.util.BitSet; /** * A BinaryScatterSearch implementation taken mainly from [i]. - * + * * @author Alex * - * F. Gortazar, A. Duarte, M. Laguna and R. Marti: Black Box Scatter Search for General Classes of Binary Optimization Problems - * Computers and Operations research, vol. 37, no. 11, pp. 1977-1986 (2010) + * F. Gortazar, A. Duarte, M. Laguna and R. Marti: Black Box Scatter Search for + * General Classes of Binary Optimization Problems Computers and Operations + * research, vol. 37, no. 11, pp. 1977-1986 (2010) */ public class BinaryScatterSearch implements InterfaceOptimizer, java.io.Serializable, InterfacePopulationChangedEventListener { - private static boolean TRACE = false; - transient private InterfacePopulationChangedEventListener m_Listener = null; - private String m_Identifier = "BinaryScatterSearch"; + private static boolean TRACE = false; + transient private InterfacePopulationChangedEventListener m_Listener = null; + private String m_Identifier = "BinaryScatterSearch"; + private int MaxImpIter = 5; + private int poolSize = 100; + private int refSetSize = 10; + private int fitCrit = -1; + private int probDim = -1; + private int generationCycle = 500; + private double th1 = 0.5; + private double th2 = 0.5; + private double g1 = 1.0 / 3.0; + private double g2 = 1.0 / 3.0; + private boolean firstTime = true; + private AbstractEAIndividual template = null; + private AbstractOptimizationProblem problem = new B1Problem(); + private Population pool = new Population(); + private Population refSet = new Population(10); + private AdaptiveCrossoverEAMixer cross = new AdaptiveCrossoverEAMixer(new CM1(), new CM2(), new CM3(), new CM4(), new CM5(), new CM6(), new CM7()); - private int MaxImpIter = 5; - private int poolSize = 100; - private int refSetSize = 10; - private int fitCrit = -1; - private int probDim = -1; - private int generationCycle = 500; - private double th1 = 0.5; - private double th2 = 0.5; - private double g1 = 1.0/3.0; - private double g2 = 1.0/3.0; - private boolean firstTime = true; - private AbstractEAIndividual template = null; - private AbstractOptimizationProblem problem = new B1Problem(); - private Population pool = new Population(); - private Population refSet = new Population(10); - private AdaptiveCrossoverEAMixer cross = new AdaptiveCrossoverEAMixer(new CM1(), new CM2(), new CM3(), new CM4(), new CM5(), new CM6(), new CM7()); + /** + * Create a new BinaryScatterSearch with default values + */ + public BinaryScatterSearch() { + } - /** - * Create a new BinaryScatterSearch with default values - */ - public BinaryScatterSearch(){ - } + /** + * Create a new BinaryScatterSearch with the same parameters as the given + * BinaryScatterSearch + * + * @param b + */ + public BinaryScatterSearch(BinaryScatterSearch b) { + this.m_Listener = b.m_Listener; + this.m_Identifier = b.m_Identifier; + this.MaxImpIter = b.MaxImpIter; + this.poolSize = b.poolSize; + this.refSetSize = b.refSetSize; + this.fitCrit = b.fitCrit; + this.probDim = b.probDim; + this.generationCycle = b.generationCycle; + this.th1 = b.th1; + this.th2 = b.th2; + this.g1 = b.g1; + this.g2 = b.g2; + this.firstTime = b.firstTime; + this.template = (AbstractEAIndividual) b.template.clone(); + this.problem = (AbstractOptimizationProblem) b.problem.clone(); + this.pool = (Population) b.pool.clone(); + this.refSet = (Population) b.refSet.clone(); + this.cross = b.cross; + } - /** - * Create a new BinaryScatterSearch with the same parameters as the given BinaryScatterSearch - * @param b - */ - public BinaryScatterSearch(BinaryScatterSearch b){ - this.m_Listener = b.m_Listener; - this.m_Identifier = b.m_Identifier; - this.MaxImpIter = b.MaxImpIter; - this.poolSize = b.poolSize; - this.refSetSize = b.refSetSize; - this.fitCrit = b.fitCrit; - this.probDim = b.probDim; - this.generationCycle= b.generationCycle; - this.th1 = b.th1; - this.th2 = b.th2; - this.g1 = b.g1; - this.g2 = b.g2; - this.firstTime = b.firstTime; - this.template = (AbstractEAIndividual) b.template.clone(); - this.problem = (AbstractOptimizationProblem) b.problem.clone(); - this.pool = (Population) b.pool.clone(); - this.refSet = (Population) b.refSet.clone(); - this.cross = b.cross; - } + /** + * Create a new BinaryScatterSearch with the given Parameters + * + * @param refSetS the refSetSize + * @param poolS the poolSize + * @param lowerThreshold the lower Boundary for the local Search + * @param upperThreshold the upper Boundary for the local Search + * @param perCentFirstIndGenerator how many individuals (in prospect of the + * poolSize) are generated through the first Generator + * @param perCentSecondIndGenerator how many individuals (in prospect of the + * poolSize) are generated through the second Generator + * @param prob the Problem + */ + public BinaryScatterSearch( + int refSetS, int poolS, double lowerThreshold, double upperThreshold, + double perCentFirstIndGenerator, double perCentSecondIndGenerator, AbstractOptimizationProblem prob) { + this.refSetSize = refSetS; + this.poolSize = poolS; + this.th1 = lowerThreshold; + this.th2 = upperThreshold; + this.g1 = perCentFirstIndGenerator; + this.g2 = perCentSecondIndGenerator; + this.problem = prob; + } - /** - * Create a new BinaryScatterSearch with the given Parameters - * @param refSetS the refSetSize - * @param poolS the poolSize - * @param lowerThreshold the lower Boundary for the local Search - * @param upperThreshold the upper Boundary for the local Search - * @param perCentFirstIndGenerator how many individuals (in prospect of the poolSize) are generated through the first Generator - * @param perCentSecondIndGenerator how many individuals (in prospect of the poolSize) are generated through the second Generator - * @param prob the Problem - */ - public BinaryScatterSearch( - int refSetS, int poolS, double lowerThreshold, double upperThreshold, - double perCentFirstIndGenerator, double perCentSecondIndGenerator, AbstractOptimizationProblem prob) { - this.refSetSize = refSetS; - this.poolSize= poolS; - this.th1 = lowerThreshold; - this.th2 = upperThreshold; - this.g1 = perCentFirstIndGenerator; - this.g2 = perCentSecondIndGenerator; - this.problem = prob; - } + /** + * Create a new BinaryScatterSearch with the given Parameters + * + * @param refSetS the refSetSize + * @param poolS the poolSize + * @param lowerThreshold the lower Boundary for the local Search + * @param upperThreshold the upper Boundary for the local Search + * @param perCentFirstIndGenerator how many individuals (in prospect of the + * poolSize) are generated through the first Generator + * @param perCentSecondIndGenerator how many individuals (in prospect of the + * poolSize) are generated through the second Generator + * @param prob the Problem + * @param cross the Crossover-Operators + */ + public BinaryScatterSearch( + int refSetS, int poolS, double lowerThreshold, double upperThreshold, + double perCentFirstIndGenerator, double perCentSecondIndGenerator, + AbstractOptimizationProblem prob, AdaptiveCrossoverEAMixer cross) { + this.refSetSize = refSetS; + this.poolSize = poolS; + this.th1 = lowerThreshold; + this.th2 = upperThreshold; + this.g1 = perCentFirstIndGenerator; + this.g2 = perCentSecondIndGenerator; + this.problem = prob; + this.cross = cross; + } - /** - * Create a new BinaryScatterSearch with the given Parameters - * @param refSetS the refSetSize - * @param poolS the poolSize - * @param lowerThreshold the lower Boundary for the local Search - * @param upperThreshold the upper Boundary for the local Search - * @param perCentFirstIndGenerator how many individuals (in prospect of the poolSize) are generated through the first Generator - * @param perCentSecondIndGenerator how many individuals (in prospect of the poolSize) are generated through the second Generator - * @param prob the Problem - * @param cross the Crossover-Operators - */ - public BinaryScatterSearch( - int refSetS, int poolS, double lowerThreshold, double upperThreshold, - double perCentFirstIndGenerator, double perCentSecondIndGenerator, - AbstractOptimizationProblem prob, AdaptiveCrossoverEAMixer cross) { - this.refSetSize = refSetS; - this.poolSize= poolS; - this.th1 = lowerThreshold; - this.th2 = upperThreshold; - this.g1 = perCentFirstIndGenerator; - this.g2 = perCentSecondIndGenerator; - this.problem = prob; - this.cross = cross; - } - - /** - * @return a copy of the current BinaryScatterSearch - */ + /** + * @return a copy of the current BinaryScatterSearch + */ @Override - public Object clone(){ - return new BinaryScatterSearch(this); - } + public Object clone() { + return new BinaryScatterSearch(this); + } @Override - public String getName() { - return "BSS"; - } + public String getName() { + return "BSS"; + } @Override - public void addPopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - this.m_Listener = ea; - } + public void addPopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + this.m_Listener = ea; + } @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } - /** - * evaluate the given Individual and increments the counter. if the individual is null, only the counter is incremented - * @param indy the individual you want to evaluate - */ - private void evaluate(AbstractEAIndividual indy){ - // evaluate the given individual if it is not null - if(indy == null){ - System.err.println("tried to evaluate null"); - return; - } - this.problem.evaluate(indy); - // increment the number of evaluations - this.refSet.incrFunctionCalls(); - } + /** + * evaluate the given Individual and increments the counter. if the + * individual is null, only the counter is incremented + * + * @param indy the individual you want to evaluate + */ + private void evaluate(AbstractEAIndividual indy) { + // evaluate the given individual if it is not null + if (indy == null) { + System.err.println("tried to evaluate null"); + return; + } + this.problem.evaluate(indy); + // increment the number of evaluations + this.refSet.incrFunctionCalls(); + } - /** - * Default initialization - */ - private void defaultInit(){ - this.refSet = new Population(); - this.template = this.problem.getIndividualTemplate(); - if (!(template instanceof InterfaceDataTypeBinary)){ - System.err.println("Requiring binary data!"); - }else{ - Object dim = BeanInspector.callIfAvailable(problem, "getProblemDimension", null); - if (dim==null) { - System.err.println("Couldnt get problem dimension!"); - } - probDim = (Integer)dim; - ((InterfaceDataTypeBinary)this.template).SetBinaryGenotype(new BitSet(probDim)); - } - this.firstTime = true; - this.cross.init(this.template, problem, refSet, Double.MAX_VALUE); - refSet.addPopulationChangedEventListener(this); - this.refSet.setNotifyEvalInterval(this.generationCycle); - } - - @Override - public void init() { - defaultInit(); - initRefSet(diversify()); - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } - - @Override - public void initByPopulation(Population pop, boolean reset) { - defaultInit(); - initRefSet(diversify(pop)); - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } - - /** - * - * @return a new diversified Population - */ - private Population diversify(){ - return diversify(new Population()); - } - - /** - * - * @param pop the initial Population - * @return a diversified Population with all the Individuals in the initial Population - */ - private Population diversify(Population pop){ - int numToInit = this.poolSize - pop.size(); - if (numToInit>0) { - pop.addAll(generateG1((int)(numToInit * this.g1))); - if (TRACE) { - System.out.println("s1: " + pop.size()); - } - generateG2(pop, (int)(numToInit * this.g2)); - if (TRACE) { - System.out.println("s2: " + pop.size()); - } - generateG3(pop, poolSize-pop.size()); - if (TRACE) { - System.out.println("s3: " + pop.size()); - } - } - return pop; - } - - /** - * Generate a new Population with diverse Individuals starting with 000...000, - * then 010101...01, 101010...10, 001001001...001, 110110110...110 and so on - * The returned population is evaluated. - * @param pop the initial Population - * @return the new Population - */ - private Population generateG1(int numToInit){ - Population pop = generateG1Pop(numToInit, this.template); - for (int i=0; i 0) { + pop.addAll(generateG1((int) (numToInit * this.g1))); + if (TRACE) { + System.out.println("s1: " + pop.size()); } - else { - throw new RuntimeException("Unable to get binary representation for " + indy.getClass()); - } - } - - /** - * calculate the sum of all the FitnessValues of the individuals that have a '0' at the i-th position - * @param i the position - * @param pop the population - * @return the sum - */ - private static double calculateSumPI0(int i, Population pop){ - double result = 0; - for(int j=0; j> list = new ArrayList>(); - for(int i=0; i< this.refSet.size(); i++){ - AbstractEAIndividual indy = this.refSet.getEAIndividual(i); - list.add(Population.getClosestFarthestIndy(indy, rest, new GenotypeMetricBitSet(), false)); - } - Pair pair = list.get(0); - for(Pair p: list){ - if(p.getTail()0 && best.getBestEAIndividual().getFitness(0) order(ArrayList list){ - ArrayList result = new ArrayList(); - for(Integer s: list){ - boolean done = false; - if(result.isEmpty()){ - result.add(s); - }else{ - for(int i=0; iscore(result.get(i), this.refSet)&&!done){ - result.add(i,s); - done = true; - } - } - if(!done){ - result.add(s); - } - } - } - return result; - } - - /** - * Do a local search - * @param indy the individual that will be improved - * @return the new improved individual - */ - private AbstractEAIndividual improve(AbstractEAIndividual indy){ - AbstractEAIndividual tmpIndy = (AbstractEAIndividual) indy.clone(); - BitSet data = ((InterfaceDataTypeBinary)tmpIndy).getBinaryData(); - ArrayList cl = new ArrayList(); - int localIter = 0; - for(int i=0; i=this.th1){ - cl.add(i); - } - } - } - cl = order(cl); - boolean improvement = true; - while(improvement && localIter < this.MaxImpIter){ - improvement = false; - for(int i:cl){ - data.flip(i); - ((InterfaceDataTypeBinary) tmpIndy).SetBinaryGenotype(data); - evaluate(tmpIndy); - if(tmpIndy.getFitness(0) generateSubsets(){ - ArrayList result = new ArrayList(); - for(int i=0; i=2){ - AbstractEAIndividual indy1 = pop.getEAIndividual(0); - pop.remove(0); - // Because some Crossover-Methods need the score, we need to give them the RefSet - for(int i=0; i0){ - result = pop.getBestEAIndividual(); - }else{ - System.err.println("Population empty"); - //return null; - } - return result; - } - - /** - * look if the individual is already in the population - * @param indy the Individual to be tested - * @param pop the population in where to search - * @return is the individual already in the Population - */ - private boolean contains(InterfaceDataTypeBinary indy, Population pop){ - if(pop.size()<=0){ - return false; - }else{ - BitSet data = indy.getBinaryData(); - for(int i=0; i newSubsets = generateSubsets(); - for(int i=0; i> list = new ArrayList>(); + for (int i = 0; i < this.refSet.size(); i++) { + AbstractEAIndividual indy = this.refSet.getEAIndividual(i); + list.add(Population.getClosestFarthestIndy(indy, rest, new GenotypeMetricBitSet(), false)); + } + Pair pair = list.get(0); + for (Pair p : list) { + if (p.getTail() < pair.getTail()) { + pair = p; + } + } + this.refSet.add(rest.getEAIndividual(pair.getHead())); + rest.remove(pair.getHead()); + } + } else { + Population best = this.pool.getBestNIndividuals(this.refSetSize, this.fitCrit); + while (best.size() > 0 && best.getBestEAIndividual().getFitness(0) < this.refSet.getWorstEAIndividual().getFitness(0)) { + if (!contains((InterfaceDataTypeBinary) best.getBestIndividual(), this.refSet)) { + refSetChanged = true; + this.refSet.remove(this.refSet.getWorstEAIndividual()); + this.refSet.add(best.getBestIndividual()); + } + best.remove(best.getBestEAIndividual()); + } + } + this.firstTime = false; + return refSetChanged; + } + + /** + * Order the given List according to the score of the given values + * + * @param list the initial List + * @return the ordered List + */ + private ArrayList order(ArrayList list) { + ArrayList result = new ArrayList(); + for (Integer s : list) { + boolean done = false; + if (result.isEmpty()) { + result.add(s); + } else { + for (int i = 0; i < result.size(); i++) { + if (score(s, this.refSet) > score(result.get(i), this.refSet) && !done) { + result.add(i, s); + done = true; + } + } + if (!done) { + result.add(s); + } + } + } + return result; + } + + /** + * Do a local search + * + * @param indy the individual that will be improved + * @return the new improved individual + */ + private AbstractEAIndividual improve(AbstractEAIndividual indy) { + AbstractEAIndividual tmpIndy = (AbstractEAIndividual) indy.clone(); + BitSet data = ((InterfaceDataTypeBinary) tmpIndy).getBinaryData(); + ArrayList cl = new ArrayList(); + int localIter = 0; + for (int i = 0; i < data.size(); i++) { + if (data.get(i)) { + if (score(i, this.refSet) <= this.th2) { + cl.add(i); + } + } else { + if (score(i, this.refSet) >= this.th1) { + cl.add(i); + } + } + } + cl = order(cl); + boolean improvement = true; + while (improvement && localIter < this.MaxImpIter) { + improvement = false; + for (int i : cl) { + data.flip(i); + ((InterfaceDataTypeBinary) tmpIndy).SetBinaryGenotype(data); + evaluate(tmpIndy); + if (tmpIndy.getFitness(0) < indy.getFitness(0)) { + improvement = true; + indy = (AbstractEAIndividual) tmpIndy.clone(); + data = ((InterfaceDataTypeBinary) tmpIndy).getBinaryData(); + } else { + tmpIndy = (AbstractEAIndividual) indy.clone(); + } + } + cl = order(cl); + for (int i = 0; i < cl.size() - 1; i++) { + boolean valI = ((InterfaceDataTypeBinary) tmpIndy).getBinaryData().get(i); + for (int j = i + 1; j < cl.size(); j++) { + boolean valJ = ((InterfaceDataTypeBinary) tmpIndy).getBinaryData().get(i); + if (valJ != valI) { + data.set(i, valJ); + data.set(j, valI); + ((InterfaceDataTypeBinary) tmpIndy).SetBinaryGenotype(data); + evaluate(tmpIndy); + if (tmpIndy.getFitness(0) < indy.getFitness(0)) { + improvement = true; + indy = (AbstractEAIndividual) tmpIndy.clone(); + data = ((InterfaceDataTypeBinary) tmpIndy).getBinaryData(); + i = cl.size(); + j = cl.size(); + } else { + tmpIndy = (AbstractEAIndividual) indy.clone(); + } + } + } + } + localIter++; + } + return indy; + } + + /** + * Combine all the individuals in the reference Set (always 2) + * + * @return the List with all the combinations + */ + public ArrayList generateSubsets() { + ArrayList result = new ArrayList(); + for (int i = 0; i < this.refSet.size(); i++) { + for (int j = i + 1; j < this.refSet.size(); j++) { + Population tmp = new Population(); + tmp.add(this.refSet.getIndividual(i)); + tmp.add(this.refSet.getIndividual(j)); + result.add((Population) tmp.clone()); + } + } + return result; + } + + /** + * combine the first individual with the second one + * + * @param pop the Population + * @return the new Individual + */ + public AbstractEAIndividual combineSolution(Population pop) { + AbstractEAIndividual result = (AbstractEAIndividual) template.clone(); + if (pop.size() >= 2) { + AbstractEAIndividual indy1 = pop.getEAIndividual(0); + pop.remove(0); + // Because some Crossover-Methods need the score, we need to give them the RefSet + for (int i = 0; i < this.refSet.size(); i++) { + pop.add(this.refSet.getEAIndividual(i)); + } + this.cross.update(indy1, problem, refSet, indy1.getFitness(0)); + result = this.cross.mate(indy1, pop)[0]; + //result = indy1.mateWith(s)[0]; + } else if (pop.size() > 0) { + result = pop.getBestEAIndividual(); + } else { + System.err.println("Population empty"); + //return null; + } + return result; + } + + /** + * look if the individual is already in the population + * + * @param indy the Individual to be tested + * @param pop the population in where to search + * @return is the individual already in the Population + */ + private boolean contains(InterfaceDataTypeBinary indy, Population pop) { + if (pop.size() <= 0) { + return false; + } else { + BitSet data = indy.getBinaryData(); + for (int i = 0; i < pop.size(); i++) { + BitSet tmpData = ((InterfaceDataTypeBinary) pop.getEAIndividual(i)).getBinaryData(); + if (tmpData.equals(data)) { + return true; + } + } + return false; + } + } @Override - public void registerPopulationStateChanged(Object source, String name) { - // The events of the interim hill climbing population will be caught here - if (name.compareTo(Population.funCallIntervalReached) == 0) { - // set funcalls to real value - refSet.SetFunctionCalls(((Population)source).getFunctionCalls()); + public void optimize() { + problem.evaluatePopulationStart(refSet); + int funCallsStart = this.refSet.getFunctionCalls(); + do { + // generate a new Pool + this.pool = new Population(); + ArrayList newSubsets = generateSubsets(); + for (int i = 0; i < newSubsets.size(); i++) { + Population s = newSubsets.get(i); + AbstractEAIndividual x = combineSolution(s); + if (!contains((InterfaceDataTypeBinary) x, this.pool) && this.pool.size() <= this.poolSize) { + this.pool.add(x); + } + } + this.refSet.incrFunctionCallsBy(this.pool.size()); + // increase the number of evaluations by the number of evaluations that are performed in the crossover-step + for (int i = 0; i < this.cross.getEvaluations(); i++) { + this.refSet.incrFunctionCalls(); + } + // reset the extra evaluations + this.cross.resetEvaluations(); + // get the best half of the Populations + Population best = this.refSet.getBestNIndividuals(this.refSetSize / 2, fitCrit); + // do a local search on the better half of the reference Set + for (int i = 0; i < best.size(); i++) { + AbstractEAIndividual indy = best.getEAIndividual(i); + AbstractEAIndividual x = improve((AbstractEAIndividual) indy.clone()); + if (x.getFitness(0) < indy.getFitness(0) && !contains((InterfaceDataTypeBinary) x, this.refSet)) { + this.refSet.remove(indy); + this.refSet.add(x); + } + } + // update the referenceSet + boolean changed = refSetUpdate(false); + // if no change occurred, replace the worst half of the referenceSet + if (!changed) { + refSetUpdate(true); + } + } while (refSet.getFunctionCalls() - funCallsStart < generationCycle); + problem.evaluatePopulationEnd(refSet); + } - // System.out.println("FunCallIntervalReached at " + (((Population)source).getFunctionCalls())); + @Override + public Population getPopulation() { + return this.refSet; + } - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } - } + @Override + public void setPopulation(Population pop) { + this.refSet = pop; + this.refSetSize = pop.getTargetSize(); + } - //----------GUI---------- + public String populationTipText() { + return "The Population"; + } - public int getPoolSize(){ - return this.poolSize; - } + @Override + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(this.refSet); + } - public void setPoolSize(int i){ - this.poolSize = i; - } + @Override + public void setIdentifier(String name) { + this.m_Identifier = name; + } - public String poolSizeTipText(){ - return "The number of individuals created in the diversification step"; - } + @Override + public String getIdentifier() { + return this.m_Identifier; + } - public double getThresholdHigh(){ - return th2; - } + @Override + public void setProblem(InterfaceOptimizationProblem problem) { + this.problem = (AbstractOptimizationProblem) problem; + } - public void setThresholdHigh(double t){ - this.th2 = t; - } + @Override + public InterfaceOptimizationProblem getProblem() { + return this.problem; + } - public String thresholdHighTipText(){ - return "Only scores set to 0 with a value below this value will be improved"; - } + @Override + public String getStringRepresentation() { + return "BinaryScatterSearch"; + } - public double getThresholdLow(){ - return th1; - } + protected void firePropertyChangedEvent(String name) { + if (this.m_Listener != null) { + this.m_Listener.registerPopulationStateChanged(this, name); + } + } - public void setThresholdLow(double t){ - this.th1 = t; - } + @Override + public void registerPopulationStateChanged(Object source, String name) { + // The events of the interim hill climbing population will be caught here + if (name.compareTo(Population.funCallIntervalReached) == 0) { + // set funcalls to real value + refSet.SetFunctionCalls(((Population) source).getFunctionCalls()); - public String thresholdLowTipText(){ - return "Only scores set to 1 with a value above this value will be improved"; - } + // System.out.println("FunCallIntervalReached at " + (((Population)source).getFunctionCalls())); - public int getLocalSearchSteps(){ - return this.MaxImpIter; - } + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + } + } - public void setLocalSearchSteps(int i){ - this.MaxImpIter = i; - } + //----------GUI---------- + public int getPoolSize() { + return this.poolSize; + } - public String localSearchStepsTipText(){ - return "Maximum number of local search iterations"; - } + public void setPoolSize(int i) { + this.poolSize = i; + } - public AdaptiveCrossoverEAMixer getCrossoverMethods(){ - return this.cross; - } + public String poolSizeTipText() { + return "The number of individuals created in the diversification step"; + } + public double getThresholdHigh() { + return th2; + } - public void setCrossoverMethods(AdaptiveCrossoverEAMixer c){ - this.cross = c; - } + public void setThresholdHigh(double t) { + this.th2 = t; + } - public String crossoverMethodsTipText(){ - return "The crossover Methods used to create the pool"; - } - - public int getGenerationCycle(){ - return this.generationCycle; - } - - public void setGenerationCycle(int i){ - this.generationCycle = i; - } - - public String generationCycleTipText(){ - return "The number of evaluations done in every generation Cycle"; - } - - public double getPerCentFirstGenMethod(){ - return this.g1; - } - - public void setPerCentFirstGenMethod(double d){ - this.g1 = d; - } - - public String perCentFirstGenMethodTipText(){ - return "The number of individuals generated with the first Generation Method. The percentage, that is not covered with the first and the second method will be covered with a third method"; - } - - public double getPerCentSecondGenMethod(){ - return this.g2; - } - - public void setPerCentSecondGenMethod(double d){ - this.g2 = d; - } - - public String perCentSecondGenMethodTipText(){ - return "The number of individuals generated with the second Generation Method. The percentage, that is not covered with the first and the second method will be covered with a third method"; - } - - public static String globalInfo(){ - return "A basic implementation of a Binary ScatterSearch"; - } + public String thresholdHighTipText() { + return "Only scores set to 0 with a value below this value will be improved"; + } + + public double getThresholdLow() { + return th1; + } + + public void setThresholdLow(double t) { + this.th1 = t; + } + + public String thresholdLowTipText() { + return "Only scores set to 1 with a value above this value will be improved"; + } + + public int getLocalSearchSteps() { + return this.MaxImpIter; + } + + public void setLocalSearchSteps(int i) { + this.MaxImpIter = i; + } + + public String localSearchStepsTipText() { + return "Maximum number of local search iterations"; + } + + public AdaptiveCrossoverEAMixer getCrossoverMethods() { + return this.cross; + } + + public void setCrossoverMethods(AdaptiveCrossoverEAMixer c) { + this.cross = c; + } + + public String crossoverMethodsTipText() { + return "The crossover Methods used to create the pool"; + } + + public int getGenerationCycle() { + return this.generationCycle; + } + + public void setGenerationCycle(int i) { + this.generationCycle = i; + } + + public String generationCycleTipText() { + return "The number of evaluations done in every generation Cycle"; + } + + public double getPerCentFirstGenMethod() { + return this.g1; + } + + public void setPerCentFirstGenMethod(double d) { + this.g1 = d; + } + + public String perCentFirstGenMethodTipText() { + return "The number of individuals generated with the first Generation Method. The percentage, that is not covered with the first and the second method will be covered with a third method"; + } + + public double getPerCentSecondGenMethod() { + return this.g2; + } + + public void setPerCentSecondGenMethod(double d) { + this.g2 = d; + } + + public String perCentSecondGenMethodTipText() { + return "The number of individuals generated with the second Generation Method. The percentage, that is not covered with the first and the second method will be covered with a third method"; + } + + public static String globalInfo() { + return "A basic implementation of a Binary ScatterSearch"; + } } diff --git a/src/eva2/server/go/strategies/CHCAdaptiveSearchAlgorithm.java b/src/eva2/server/go/strategies/CHCAdaptiveSearchAlgorithm.java index 128d10dd..946db074 100644 --- a/src/eva2/server/go/strategies/CHCAdaptiveSearchAlgorithm.java +++ b/src/eva2/server/go/strategies/CHCAdaptiveSearchAlgorithm.java @@ -1,6 +1,5 @@ package eva2.server.go.strategies; - import eva2.server.go.InterfacePopulationChangedEventListener; import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.InterfaceGAIndividual; @@ -15,50 +14,49 @@ import eva2.server.go.problems.InterfaceOptimizationProblem; import eva2.tools.math.RNG; import java.util.BitSet; -/** This is an implementation of the CHC Adaptive Search Algorithm by Eshelman. It is - * limited to binary data and is based on massively disruptive crossover. I'm not - * sure whether i've implemented this correctly, but i definitely wasn't able to make - * it competitive to a standard GA.. *sigh* - * This is a implementation of the CHC Adaptive Search Algorithm (Cross generational - * elitist selection, Heterogeneous recombination and Cataclysmic mutation). - * Citation: - * - * Copyright: Copyright (c) 2003 - * Company: University of Tuebingen, Computer Architecture - * @author Felix Streichert - * @version: $Revision: 307 $ - * $Date: 2007-12-04 14:31:47 +0100 (Tue, 04 Dec 2007) $ - * $Author: mkron $ +/** + * This is an implementation of the CHC Adaptive Search Algorithm by Eshelman. + * It is limited to binary data and is based on massively disruptive crossover. + * I'm not sure whether i've implemented this correctly, but i definitely wasn't + * able to make it competitive to a standard GA.. *sigh* This is a + * implementation of the CHC Adaptive Search Algorithm (Cross generational + * elitist selection, Heterogeneous recombination and Cataclysmic mutation). + * Citation: + * + * Copyright: Copyright (c) 2003 Company: University of Tuebingen, Computer + * Architecture + * + * @author Felix Streichert + * @version: $Revision: 307 $ $Date: 2007-12-04 14:31:47 +0100 (Tue, 04 Dec + * 2007) $ $Author: mkron $ */ - public class CHCAdaptiveSearchAlgorithm implements InterfaceOptimizer, java.io.Serializable { - private double m_InitialDifferenceThreshold = 0.25; - private int m_DifferenceThreshold; - private double m_DivergenceRate = 0.35; - private boolean m_UseElitism = true; - private int m_NumberOfPartners = 1; - private Population m_Population = new Population(); - private InterfaceOptimizationProblem m_Problem = new B1Problem(); - private InterfaceSelection m_RecombSelectionOperator = new SelectRandom(); - private InterfaceSelection m_PopulSelectionOperator = new SelectBestSingle(); - - transient private String m_Identifier = ""; + private double m_InitialDifferenceThreshold = 0.25; + private int m_DifferenceThreshold; + private double m_DivergenceRate = 0.35; + private boolean m_UseElitism = true; + private int m_NumberOfPartners = 1; + private Population m_Population = new Population(); + private InterfaceOptimizationProblem m_Problem = new B1Problem(); + private InterfaceSelection m_RecombSelectionOperator = new SelectRandom(); + private InterfaceSelection m_PopulSelectionOperator = new SelectBestSingle(); + transient private String m_Identifier = ""; transient private InterfacePopulationChangedEventListener m_Listener; public CHCAdaptiveSearchAlgorithm() { } public CHCAdaptiveSearchAlgorithm(CHCAdaptiveSearchAlgorithm a) { - this.m_Population = (Population)a.m_Population.clone(); - this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone(); - this.m_InitialDifferenceThreshold = a.m_InitialDifferenceThreshold; - this.m_DifferenceThreshold = a.m_DifferenceThreshold; - this.m_DivergenceRate = a.m_DivergenceRate; - this.m_NumberOfPartners = a.m_NumberOfPartners; - this.m_UseElitism = a.m_UseElitism; - this.m_RecombSelectionOperator = (InterfaceSelection)a.m_RecombSelectionOperator.clone(); - this.m_PopulSelectionOperator = (InterfaceSelection)a.m_PopulSelectionOperator.clone(); + this.m_Population = (Population) a.m_Population.clone(); + this.m_Problem = (InterfaceOptimizationProblem) a.m_Problem.clone(); + this.m_InitialDifferenceThreshold = a.m_InitialDifferenceThreshold; + this.m_DifferenceThreshold = a.m_DifferenceThreshold; + this.m_DivergenceRate = a.m_DivergenceRate; + this.m_NumberOfPartners = a.m_NumberOfPartners; + this.m_UseElitism = a.m_UseElitism; + this.m_RecombSelectionOperator = (InterfaceSelection) a.m_RecombSelectionOperator.clone(); + this.m_PopulSelectionOperator = (InterfaceSelection) a.m_PopulSelectionOperator.clone(); } @Override @@ -69,9 +67,9 @@ public class CHCAdaptiveSearchAlgorithm implements InterfaceOptimizer, java.io.S @Override public void init() { this.m_Problem.initPopulation(this.m_Population); - AbstractEAIndividual tmpIndy = ((AbstractEAIndividual)(this.m_Population.get(0))); + AbstractEAIndividual tmpIndy = ((AbstractEAIndividual) (this.m_Population.get(0))); if (tmpIndy instanceof InterfaceGAIndividual) { - this.m_DifferenceThreshold = (int)(((InterfaceGAIndividual)tmpIndy).getGenotypeLength()*this.m_InitialDifferenceThreshold); + this.m_DifferenceThreshold = (int) (((InterfaceGAIndividual) tmpIndy).getGenotypeLength() * this.m_InitialDifferenceThreshold); } else { System.out.println("Problem does not apply InterfaceGAIndividual, which is the only individual type valid for CHC!"); } @@ -80,31 +78,34 @@ public class CHCAdaptiveSearchAlgorithm implements InterfaceOptimizer, java.io.S this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** This method will init the optimizer with a given population - * @param pop The initial population - * @param reset If true the population is reset. + /** + * This method will init the optimizer with a given population + * + * @param pop The initial population + * @param reset If true the population is reset. */ @Override public void initByPopulation(Population pop, boolean reset) { - this.m_Population = (Population)pop.clone(); + this.m_Population = (Population) pop.clone(); if (reset) { this.m_Population.init(); } - AbstractEAIndividual tmpIndy = ((AbstractEAIndividual)(this.m_Population.get(0))); + AbstractEAIndividual tmpIndy = ((AbstractEAIndividual) (this.m_Population.get(0))); if (tmpIndy instanceof InterfaceGAIndividual) { - this.m_DifferenceThreshold = (int)(((InterfaceGAIndividual)tmpIndy).getGenotypeLength()*this.m_InitialDifferenceThreshold); + this.m_DifferenceThreshold = (int) (((InterfaceGAIndividual) tmpIndy).getGenotypeLength() * this.m_InitialDifferenceThreshold); } else { System.out.println("Problem does not apply InterfaceGAIndividual, which is the only individual type valid for CHC!"); } if (reset) { - this.evaluatePopulation(this.m_Population); + this.evaluatePopulation(this.m_Population); this.firePropertyChangedEvent(Population.nextGenerationPerformed); } } - /** This method will evaluate the current population using the - * given problem. + /** + * This method will evaluate the current population using the given problem. + * * @param population The population that is to be evaluated */ private void evaluatePopulation(Population population) { @@ -112,29 +113,30 @@ public class CHCAdaptiveSearchAlgorithm implements InterfaceOptimizer, java.io.S population.incrGeneration(); } - /** This method will generate the offspring population from the - * given population of evaluated individuals. + /** + * This method will generate the offspring population from the given + * population of evaluated individuals. */ private Population generateChildren() { - Population result = this.m_Population.cloneWithoutInds(), parents, partners; - AbstractEAIndividual[] offSprings; - AbstractEAIndividual tmpIndy; + Population result = this.m_Population.cloneWithoutInds(), parents, partners; + AbstractEAIndividual[] offSprings; + AbstractEAIndividual tmpIndy; result.clear(); // this.m_NormationOperator.computeSelectionProbability(this.m_Population, "Fitness"); //System.out.println("Population:"+this.m_Population.getSolutionRepresentationFor()); this.m_PopulSelectionOperator.prepareSelection(this.m_Population); this.m_RecombSelectionOperator.prepareSelection(this.m_Population); - parents = this.m_PopulSelectionOperator.selectFrom(this.m_Population, this.m_Population.getTargetSize()); + parents = this.m_PopulSelectionOperator.selectFrom(this.m_Population, this.m_Population.getTargetSize()); //System.out.println("Parents:"+parents.getSolutionRepresentationFor()); for (int i = 0; i < parents.size(); i++) { - tmpIndy = ((AbstractEAIndividual)parents.get(i)); + tmpIndy = ((AbstractEAIndividual) parents.get(i)); if (tmpIndy == null) { - System.out.println("Individual null "+i); + System.out.println("Individual null " + i); } if (this.m_Population == null) { - System.out.println("population null "+i); + System.out.println("population null " + i); } partners = this.m_RecombSelectionOperator.findPartnerFor(tmpIndy, this.m_Population, this.m_NumberOfPartners); @@ -149,20 +151,22 @@ public class CHCAdaptiveSearchAlgorithm implements InterfaceOptimizer, java.io.S return result; } - /** This method computes the Hamming Distance between n-Individuals + /** + * This method computes the Hamming Distance between n-Individuals + * * @param dad * @param partners * @return The maximal Hamming Distance between dad and the partners */ private int computeHammingDistance(AbstractEAIndividual dad, Population partners) { - int result = 0, tmpDist; - BitSet tmpB1, tmpB2; + int result = 0, tmpDist; + BitSet tmpB1, tmpB2; - tmpB1 = ((InterfaceGAIndividual)dad).getBGenotype(); + tmpB1 = ((InterfaceGAIndividual) dad).getBGenotype(); for (int i = 0; i < partners.size(); i++) { tmpB2 = ((InterfaceGAIndividual) partners.get(i)).getBGenotype(); tmpDist = 0; - for (int j = 0; j < ((InterfaceGAIndividual)dad).getGenotypeLength(); j++) { + for (int j = 0; j < ((InterfaceGAIndividual) dad).getGenotypeLength(); j++) { if (tmpB1.get(j) == tmpB2.get(j)) { tmpDist++; } @@ -172,25 +176,26 @@ public class CHCAdaptiveSearchAlgorithm implements InterfaceOptimizer, java.io.S return result; } - /** This method method replaces the current population with copies of the current - * best individual but all but one are randomized with a very high mutation rate. + /** + * This method method replaces the current population with copies of the + * current best individual but all but one are randomized with a very high + * mutation rate. */ private void diverge() { - AbstractEAIndividual best = this.m_Population.getBestEAIndividual(); - InterfaceGAIndividual mutant; - BitSet tmpBitSet; + AbstractEAIndividual best = this.m_Population.getBestEAIndividual(); + InterfaceGAIndividual mutant; + BitSet tmpBitSet; this.m_Population.clear(); this.m_Population.add(best); for (int i = 1; i < this.m_Population.getTargetSize(); i++) { - mutant = (InterfaceGAIndividual)best.clone(); - tmpBitSet = mutant.getBGenotype(); + mutant = (InterfaceGAIndividual) best.clone(); + tmpBitSet = mutant.getBGenotype(); for (int j = 0; j < mutant.getGenotypeLength(); j++) { if (RNG.flipCoin(this.m_DivergenceRate)) { if (tmpBitSet.get(j)) { tmpBitSet.clear(j); - } - else { + } else { tmpBitSet.set(j); } } @@ -199,7 +204,7 @@ public class CHCAdaptiveSearchAlgorithm implements InterfaceOptimizer, java.io.S this.m_Population.add(mutant); } if (best instanceof InterfaceGAIndividual) { - this.m_DifferenceThreshold = (int)(this.m_DivergenceRate* (1-this.m_DivergenceRate) * ((InterfaceGAIndividual)best).getGenotypeLength()); + this.m_DifferenceThreshold = (int) (this.m_DivergenceRate * (1 - this.m_DivergenceRate) * ((InterfaceGAIndividual) best).getGenotypeLength()); } this.evaluatePopulation(this.m_Population); @@ -237,39 +242,46 @@ public class CHCAdaptiveSearchAlgorithm implements InterfaceOptimizer, java.io.S public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { this.m_Listener = ea; } + @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - - /** Something has changed + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } + + /** + * Something has changed */ - protected void firePropertyChangedEvent (String name) { + protected void firePropertyChangedEvent(String name) { if (this.m_Listener != null) { this.m_Listener.registerPopulationStateChanged(this, name); } } - /** This method will set the problem that is to be optimized + /** + * This method will set the problem that is to be optimized + * * @param problem */ @Override - public void setProblem (InterfaceOptimizationProblem problem) { + public void setProblem(InterfaceOptimizationProblem problem) { this.m_Problem = problem; } + @Override - public InterfaceOptimizationProblem getProblem () { + public InterfaceOptimizationProblem getProblem() { return this.m_Problem; } - /** This method will return a string describing all properties of the optimizer - * and the applied methods. + /** + * This method will return a string describing all properties of the + * optimizer and the applied methods. + * * @return A descriptive string */ @Override @@ -277,41 +289,42 @@ public class CHCAdaptiveSearchAlgorithm implements InterfaceOptimizer, java.io.S String result = ""; result += "CHC Adaptive Search Algorithm:\n"; result += "Optimization Problem: "; - result += this.m_Problem.getStringRepresentationForProblem(this) +"\n"; + result += this.m_Problem.getStringRepresentationForProblem(this) + "\n"; result += this.m_Population.getStringRepresentation(); return result; } - /** This method allows you to set an identifier for the algorithm - * @param name The indenifier + /** + * This method allows you to set an identifier for the algorithm + * + * @param name The indenifier */ @Override - public void setIdentifier(String name) { + public void setIdentifier(String name) { this.m_Identifier = name; } - @Override - public String getIdentifier() { - return this.m_Identifier; - } - /** This method is required to free the memory on a RMIServer, - * but there is nothing to implement. - */ @Override - public void freeWilly() { - + public String getIdentifier() { + return this.m_Identifier; } -/********************************************************************************************************************** - * These are for GUI - */ - /** This method returns a global info string + /** + * ******************************************************************************************************************** + * These are for GUI + */ + /** + * This method returns a global info string + * * @return description */ public static String globalInfo() { return "This is an implementation of the CHC Adaptive Search Algorithm by Eselman."; } - /** This method will return a naming String + + /** + * This method will return a naming String + * * @return The name of the algorithm */ @Override @@ -319,26 +332,30 @@ public class CHCAdaptiveSearchAlgorithm implements InterfaceOptimizer, java.io.S return "CHC"; } - /** Assuming that all optimizer will store thier data in a population - * we will allow acess to this population to query to current state - * of the optimizer. + /** + * Assuming that all optimizer will store thier data in a population we will + * allow acess to this population to query to current state of the + * optimizer. + * * @return The population of current solutions to a given problem. */ @Override public Population getPopulation() { return this.m_Population; } + @Override - public void setPopulation(Population pop){ + public void setPopulation(Population pop) { this.m_Population = pop; } + public String populationTipText() { return "Edit the properties of the population used."; } - + @Override public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(getPopulation()); + return new SolutionSet(getPopulation()); } // /** This method will set the normation method that is to be used. @@ -353,21 +370,26 @@ public class CHCAdaptiveSearchAlgorithm implements InterfaceOptimizer, java.io.S // public String normationMethodTipText() { // return "Select the normation method."; // } - - /** Enable/disable elitism. + /** + * Enable/disable elitism. + * * @param elitism */ - public void setElitism (boolean elitism) { + public void setElitism(boolean elitism) { this.m_UseElitism = elitism; } + public boolean getElitism() { return this.m_UseElitism; } + public String elitismTipText() { return "Enable/disable elitism."; } - /** The number of mating partners needed to create offsprings. + /** + * The number of mating partners needed to create offsprings. + * * @param partners */ public void setNumberOfPartners(int partners) { @@ -376,9 +398,11 @@ public class CHCAdaptiveSearchAlgorithm implements InterfaceOptimizer, java.io.S } this.m_NumberOfPartners = partners; } + public int getNumberOfPartners() { return this.m_NumberOfPartners; } + public String numberOfPartnersTipText() { return "The number of mating partners needed to create offsprings."; } diff --git a/src/eva2/server/go/strategies/ClusterBasedNichingEA.java b/src/eva2/server/go/strategies/ClusterBasedNichingEA.java index 04fa7d37..d5bb2478 100644 --- a/src/eva2/server/go/strategies/ClusterBasedNichingEA.java +++ b/src/eva2/server/go/strategies/ClusterBasedNichingEA.java @@ -41,138 +41,135 @@ import java.util.LinkedList; import java.util.List; import java.util.PriorityQueue; -/** The infamous clustering based niching EA, still under construction. - * It should be able to identify and track multiple global/local optima - * at the same time. - * +/** + * The infamous clustering based niching EA, still under construction. It should + * be able to identify and track multiple global/local optima at the same time. + * * Notes: For std. GA, the mutation rate may have to reduced, because the * initial step size tends to be rel. large and easily disperse clustered - * species (so that they fall below the minimum swarm size and the local - * optimum is lost). - * + * species (so that they fall below the minimum swarm size and the local optimum + * is lost). + * * For the CBN-PSO remember to use the IndividualDataMetric so that the - * remembered positions are used for clustering (which are rel. stable - - * so that species clustering actually makes sense). - * - * Copyright: Copyright (c) 2010 - * Company: University of Tuebingen, Computer Architecture - * @author Felix Streichert, Marcel Kronfeld + * remembered positions are used for clustering (which are rel. stable - so that + * species clustering actually makes sense). + * + * Copyright: Copyright (c) 2010 Company: University of Tuebingen, Computer + * Architecture + * + * @author Felix Streichert, Marcel Kronfeld */ - public class ClusterBasedNichingEA implements InterfacePopulationChangedEventListener, InterfaceAdditionalPopulationInformer, InterfaceOptimizer, java.io.Serializable { - private static final long serialVersionUID = -3143069327594708609L; - private Population m_Population = new Population(); - private transient Population m_Archive = new Population(); - private ArrayList m_Species = new ArrayList(); - private Population m_Undifferentiated = new Population(); - private transient Population m_doomedPop = new Population(); - - private InterfaceOptimizationProblem m_Problem = new B1Problem(); - private InterfaceOptimizer m_Optimizer = new GeneticAlgorithm(); - private InterfaceClustering m_CAForSpeciesDifferentation = new ClusteringDensityBased(); - private InterfaceClustering m_CAForSpeciesMerging = new ClusteringDensityBased(); - - private double clusterDiffDist = 0.05; + + private static final long serialVersionUID = -3143069327594708609L; + private Population m_Population = new Population(); + private transient Population m_Archive = new Population(); + private ArrayList m_Species = new ArrayList(); + private Population m_Undifferentiated = new Population(); + private transient Population m_doomedPop = new Population(); + private InterfaceOptimizationProblem m_Problem = new B1Problem(); + private InterfaceOptimizer m_Optimizer = new GeneticAlgorithm(); + private InterfaceClustering m_CAForSpeciesDifferentation = new ClusteringDensityBased(); + private InterfaceClustering m_CAForSpeciesMerging = new ClusteringDensityBased(); + private double clusterDiffDist = 0.05; // private double clusterMergeDist = 0.0001; // private Distraction distraction = null; - private boolean useDistraction = false; + private boolean useDistraction = false; // private double distrDefaultStrength = .7; - private double epsilonBound = 1e-10; - - transient private String m_Identifier = ""; + private double epsilonBound = 1e-10; + transient private String m_Identifier = ""; transient private InterfacePopulationChangedEventListener m_Listener; - - private int m_SpeciesCycle = 1; + private int m_SpeciesCycle = 1; // from which size on is a species considered active // private int m_actSpecSize = 2; - private int m_minGroupSize = 3; + private int m_minGroupSize = 3; // private boolean m_UseClearing = false; // private boolean m_UseArchive = true; - private boolean m_UseSpeciesDifferentiation = true; - private boolean m_mergeSpecies = true; - private int m_PopulationSize = 50; - private int convergedCnt = 0; - private int collisions = 0; + private boolean m_UseSpeciesDifferentiation = true; + private boolean m_mergeSpecies = true; + private int m_PopulationSize = 50; + private int convergedCnt = 0; + private int collisions = 0; + private static boolean TRACE = false, TRACE_STATE = false, TRACE_EVTS = false; + private int m_ShowCycle = 0; + transient private TopoPlot m_Topology; + private int haltingWindow = 15; + private double muLambdaRatio = 0.5; + private int sleepTime = 0; + private int m_maxSpeciesSize = 15; + private AbstractEAIndividualComparator reduceSizeComparator = new AbstractEAIndividualComparator(); + private AbstractEAIndividualComparator histComparator = new AbstractEAIndividualComparator("", -1, true); + protected ParameterControlManager paramControl = new ParameterControlManager(); + private double avgDistForConvergence = 0.1; // Upper bound for average indy distance in a species in the test for convergence - private static boolean TRACE = false, TRACE_STATE=false, TRACE_EVTS=false; - private int m_ShowCycle = 0; - transient private TopoPlot m_Topology; - private int haltingWindow = 15; - private double muLambdaRatio = 0.5; - private int sleepTime = 0; - private int m_maxSpeciesSize = 15; - private AbstractEAIndividualComparator reduceSizeComparator = new AbstractEAIndividualComparator(); - private AbstractEAIndividualComparator histComparator = new AbstractEAIndividualComparator("", -1, true); - - protected ParameterControlManager paramControl = new ParameterControlManager(); - private double avgDistForConvergence = 0.1; // Upper bound for average indy distance in a species in the test for convergence - - public ClusterBasedNichingEA() { + public ClusterBasedNichingEA() { this.m_CAForSpeciesMerging = new ClusteringDensityBased(); // ((ClusteringDensityBased)this.m_CAForSpeciesMerging).setMinimumGroupSize(m_minGroupSize); // if (useDistraction) distraction = new Distraction(distrDefaultStrength, Distraction.METH_BEST); } - /********************************************************************************************************************** + /** + * ******************************************************************************************************************** * These are for InterfaceParamControllable */ + public Object[] getParamControl() { + List ctrlbls = ParameterControlManager.listOfControllables(this); + ctrlbls.add(paramControl); + return ctrlbls.toArray(); + // this works - however differently than when returning a ParameterControlManager + // Only instances are returned which + } - public Object[] getParamControl() { - List ctrlbls = ParameterControlManager.listOfControllables(this); - ctrlbls.add(paramControl); - return ctrlbls.toArray(); - // this works - however differently than when returning a ParameterControlManager - // Only instances are returned which - } - - /** - * This method is necessary to allow access from the Processor. - * @return - */ + /** + * This method is necessary to allow access from the Processor. + * + * @return + */ // public ParameterControlManager getParamControl() { // return paramControl; // } - - public ParamAdaption[] getParameterControl() { - return paramControl.getSingleAdapters(); - } - public void setParameterControl(ParamAdaption[] paramControl) { - this.paramControl.setSingleAdapters(paramControl); - } - public String parameterControlTipText() { - return "You may define dynamic paramter control strategies using the parameter name."; - } - - public void addParameterControl(ParamAdaption pa) { - this.paramControl.addSingleAdapter(pa); - } - + public ParamAdaption[] getParameterControl() { + return paramControl.getSingleAdapters(); + } + + public void setParameterControl(ParamAdaption[] paramControl) { + this.paramControl.setSingleAdapters(paramControl); + } + + public String parameterControlTipText() { + return "You may define dynamic paramter control strategies using the parameter name."; + } + + public void addParameterControl(ParamAdaption pa) { + this.paramControl.addSingleAdapter(pa); + } + public ClusterBasedNichingEA(ClusterBasedNichingEA a) { - this.epsilonBound = a.epsilonBound; - this.m_Population = (Population)a.m_Population.clone(); - this.m_Archive = (Population)a.m_Archive.clone(); - this.m_doomedPop = (Population)a.m_doomedPop.clone(); - this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone(); - this.m_Optimizer = (InterfaceOptimizer)a.m_Optimizer.clone(); - this.m_Species = (ArrayList)(a.m_Species.clone()); - this.m_Undifferentiated = (Population)a.m_Undifferentiated.clone(); - this.m_CAForSpeciesMerging = (InterfaceClustering)this.m_CAForSpeciesMerging.clone(); - this.m_CAForSpeciesDifferentation = (InterfaceClustering)this.m_CAForSpeciesDifferentation.clone(); - this.m_SpeciesCycle = a.m_SpeciesCycle; - this.m_minGroupSize = a.m_minGroupSize; - this.m_UseSpeciesDifferentiation = a.m_UseSpeciesDifferentiation; - this.m_mergeSpecies = a.m_mergeSpecies; - this.m_PopulationSize = a.m_PopulationSize; - this.haltingWindow = a.haltingWindow; - this.m_maxSpeciesSize = a.m_maxSpeciesSize; - this.muLambdaRatio = a.muLambdaRatio; - this.sleepTime = a.sleepTime; - this.convergedCnt = a.convergedCnt; - this.collisions = a.collisions; - this.clusterDiffDist = a.clusterDiffDist; - this.useDistraction = a.useDistraction; - this.m_ShowCycle = a.m_ShowCycle; - this.m_maxSpeciesSize = a.m_maxSpeciesSize; + this.epsilonBound = a.epsilonBound; + this.m_Population = (Population) a.m_Population.clone(); + this.m_Archive = (Population) a.m_Archive.clone(); + this.m_doomedPop = (Population) a.m_doomedPop.clone(); + this.m_Problem = (InterfaceOptimizationProblem) a.m_Problem.clone(); + this.m_Optimizer = (InterfaceOptimizer) a.m_Optimizer.clone(); + this.m_Species = (ArrayList) (a.m_Species.clone()); + this.m_Undifferentiated = (Population) a.m_Undifferentiated.clone(); + this.m_CAForSpeciesMerging = (InterfaceClustering) this.m_CAForSpeciesMerging.clone(); + this.m_CAForSpeciesDifferentation = (InterfaceClustering) this.m_CAForSpeciesDifferentation.clone(); + this.m_SpeciesCycle = a.m_SpeciesCycle; + this.m_minGroupSize = a.m_minGroupSize; + this.m_UseSpeciesDifferentiation = a.m_UseSpeciesDifferentiation; + this.m_mergeSpecies = a.m_mergeSpecies; + this.m_PopulationSize = a.m_PopulationSize; + this.haltingWindow = a.haltingWindow; + this.m_maxSpeciesSize = a.m_maxSpeciesSize; + this.muLambdaRatio = a.muLambdaRatio; + this.sleepTime = a.sleepTime; + this.convergedCnt = a.convergedCnt; + this.collisions = a.collisions; + this.clusterDiffDist = a.clusterDiffDist; + this.useDistraction = a.useDistraction; + this.m_ShowCycle = a.m_ShowCycle; + this.m_maxSpeciesSize = a.m_maxSpeciesSize; } @Override @@ -182,75 +179,77 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis @Override public void init() { - if (m_Undifferentiated==null) { + if (m_Undifferentiated == null) { this.m_Undifferentiated = new Population(m_PopulationSize); + } else { + m_Undifferentiated.resetProperties(); + m_Undifferentiated.setTargetSize(m_PopulationSize); } - else { - m_Undifferentiated.resetProperties(); - m_Undifferentiated.setTargetSize(m_PopulationSize); - } this.m_Undifferentiated.setUseHistory(true); this.m_Problem.initPopulation(this.m_Undifferentiated); this.m_Optimizer.initByPopulation(m_Undifferentiated, true); - m_Undifferentiated=this.m_Optimizer.getPopulation(); // some optimizers clone the given one. + m_Undifferentiated = this.m_Optimizer.getPopulation(); // some optimizers clone the given one. if (m_Optimizer instanceof EvolutionStrategies) { - EvolutionStrategies es = (EvolutionStrategies)m_Optimizer; - es.setLambda(getPopulationSize()); - es.setMu((int)(muLambdaRatio*(double)getPopulationSize())); + EvolutionStrategies es = (EvolutionStrategies) m_Optimizer; + es.setLambda(getPopulationSize()); + es.setMu((int) (muLambdaRatio * (double) getPopulationSize())); } // this.m_Optimizer.init(); m_doomedPop = m_Undifferentiated.cloneWithoutInds(); - if (m_Undifferentiated.getFunctionCalls()!=m_PopulationSize) { - System.err.println("Whats that in CBN!?"); + if (m_Undifferentiated.getFunctionCalls() != m_PopulationSize) { + System.err.println("Whats that in CBN!?"); } initDefaults(false); - } + } public void hideHideable() { - GenericObjectEditor.setHideProperty(this.getClass(), "population", true); - setMaxSpeciesSize(getMaxSpeciesSize()); - setUseMerging(isUseMerging()); + GenericObjectEditor.setHideProperty(this.getClass(), "population", true); + setMaxSpeciesSize(getMaxSpeciesSize()); + setUseMerging(isUseMerging()); } - - /** + + /** * Do not reinitialize the main population! - * + * * @param evalPop */ private void initDefaults(boolean evalPop) { - this.m_Optimizer.addPopulationChangedEventListener(this); - this.m_Undifferentiated.setTargetSize(this.m_PopulationSize); - this.m_Species = new ArrayList(); - this.m_Archive = m_Undifferentiated.cloneWithoutInds(); + this.m_Optimizer.addPopulationChangedEventListener(this); + this.m_Undifferentiated.setTargetSize(this.m_PopulationSize); + this.m_Species = new ArrayList(); + this.m_Archive = m_Undifferentiated.cloneWithoutInds(); // if (useDistraction) distraction = new Distraction(distrDefaultStrength, Distraction.METH_BEST); - convergedCnt = 0; - collisions=0; - if (evalPop) { + convergedCnt = 0; + collisions = 0; + if (evalPop) { this.evaluatePopulation(this.m_Undifferentiated); } - this.m_Optimizer.initByPopulation(m_Undifferentiated, false); - this.m_Undifferentiated = m_Optimizer.getPopulation(); // required for changes to the population by the optimizer - m_Population = m_Undifferentiated; - this.firePropertyChangedEvent("FirstGenerationPerformed"); + this.m_Optimizer.initByPopulation(m_Undifferentiated, false); + this.m_Undifferentiated = m_Optimizer.getPopulation(); // required for changes to the population by the optimizer + m_Population = m_Undifferentiated; + this.firePropertyChangedEvent("FirstGenerationPerformed"); } - - /** This method will init the optimizer with a given population - * @param pop The initial population - * @param reset If true the population is reset. + + /** + * This method will init the optimizer with a given population + * + * @param pop The initial population + * @param reset If true the population is reset. */ @Override public void initByPopulation(Population pop, boolean reset) { - this.m_Undifferentiated = (Population)pop.clone(); + this.m_Undifferentiated = (Population) pop.clone(); if (reset) { this.m_Undifferentiated.init(); } - initDefaults(reset); + initDefaults(reset); } - /** This method will evaluate the current population using the - * given problem. + /** + * This method will evaluate the current population using the given problem. + * * @param population The population that is to be evaluated */ private void evaluatePopulation(Population population) { @@ -259,38 +258,38 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis } private void plot(int gen) { - if (!(this.m_Problem instanceof TF1Problem) && !(this.m_Problem instanceof Interface2DBorderProblem)) { + if (!(this.m_Problem instanceof TF1Problem) && !(this.m_Problem instanceof Interface2DBorderProblem)) { return; } - double[] a = new double[2]; + double[] a = new double[2]; a[0] = 0.0; a[1] = 0.0; if (this.m_Problem instanceof TF1Problem) { // now i need to plot the pareto fronts - Plot plot = new Plot("TF3Problem at gen. "+gen, "y1", "y2", a, a); - plot.setUnconnectedPoint(0,0,0); - plot.setUnconnectedPoint(1,5,0); - GraphPointSet mySet = new GraphPointSet(10, plot.getFunctionArea()); - DPoint point; + Plot plot = new Plot("TF3Problem at gen. " + gen, "y1", "y2", a, a); + plot.setUnconnectedPoint(0, 0, 0); + plot.setUnconnectedPoint(1, 5, 0); + GraphPointSet mySet = new GraphPointSet(10, plot.getFunctionArea()); + DPoint point; mySet.setConnectedMode(false); for (int i = 0; i < this.m_Undifferentiated.size(); i++) { - AbstractEAIndividual indy = (AbstractEAIndividual)this.m_Undifferentiated.get(i); - double [] d = indy.getFitness(); + AbstractEAIndividual indy = (AbstractEAIndividual) this.m_Undifferentiated.get(i); + double[] d = indy.getFitness(); point = new DPoint(d[0], d[1]); point.setIcon(new Chart2DDPointIconCircle()); mySet.addDPoint(point); } for (int i = 0; i < this.m_Species.size(); i++) { - mySet = new GraphPointSet(10+i, plot.getFunctionArea()); + mySet = new GraphPointSet(10 + i, plot.getFunctionArea()); mySet.setConnectedMode(false); - Population pop = (Population)this.m_Species.get(i); + Population pop = (Population) this.m_Species.get(i); // ArchivingAllDomiating arch = new ArchivingAllDomiating(); // arch.plotParetoFront(pop, plot); for (int j = 0; j < pop.size(); j++) { - AbstractEAIndividual indy = (AbstractEAIndividual)pop.get(j); - double [] d = indy.getFitness(); + AbstractEAIndividual indy = (AbstractEAIndividual) pop.get(j); + double[] d = indy.getFitness(); point = new DPoint(d[0], d[1]); - point.setIcon(new Chart2DDPointIconText("P"+j)); + point.setIcon(new Chart2DDPointIconText("P" + j)); mySet.addDPoint(point); } @@ -298,28 +297,28 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis } if (this.m_Problem instanceof Interface2DBorderProblem) { - DPointSet popRep = new DPointSet(); + DPointSet popRep = new DPointSet(); InterfaceDataTypeDouble tmpIndy1; - Population pop; + Population pop; - this.m_Topology = new TopoPlot("CBN-Species at gen. " + gen,"x","y",a,a); + this.m_Topology = new TopoPlot("CBN-Species at gen. " + gen, "x", "y", a, a); this.m_Topology.setParams(50, 50); - this.m_Topology.setTopology((Interface2DBorderProblem)this.m_Problem); + this.m_Topology.setTopology((Interface2DBorderProblem) this.m_Problem); //draw the undifferentiated for (int i = 0; i < this.m_Undifferentiated.size(); i++) { - tmpIndy1 = (InterfaceDataTypeDouble)this.m_Undifferentiated.get(i); + tmpIndy1 = (InterfaceDataTypeDouble) this.m_Undifferentiated.get(i); popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1])); } this.m_Topology.getFunctionArea().addDElement(popRep); //draw the species for (int i = 0; i < this.m_Species.size(); i++) { - pop = (Population)this.m_Species.get(i); + pop = (Population) this.m_Species.get(i); plotPopConnected(m_Topology, pop); } if (!useDistraction) { - for (int i = 0; i < this.m_Archive.size(); i++) { - plotIndy(m_Topology, 'x',(InterfaceDataTypeDouble)m_Archive.get(i)); - } + for (int i = 0; i < this.m_Archive.size(); i++) { + plotIndy(m_Topology, 'x', (InterfaceDataTypeDouble) m_Archive.get(i)); + } } else { // for (int i = 0; i < this.distraction.getDistractorSetSize(); i++) { // plotPosFit('#',distraction.getDistractorCenter(i), distraction.getDistractorStrength(i)); @@ -328,60 +327,60 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis } } - public static void plotPopConnected(TopoPlot tp, Population pop) { - DPointSet popRep; - InterfaceDataTypeDouble tmpIndy1; - if (pop.size()>1) { - for (int j = 0; j < pop.size(); j++) { - popRep = new DPointSet(); - tmpIndy1 = (InterfaceDataTypeDouble)pop.get(j); - popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1])); - tp.getFunctionArea().addDElement(popRep); + public static void plotPopConnected(TopoPlot tp, Population pop) { + DPointSet popRep; + InterfaceDataTypeDouble tmpIndy1; + if (pop.size() > 1) { + for (int j = 0; j < pop.size(); j++) { + popRep = new DPointSet(); + tmpIndy1 = (InterfaceDataTypeDouble) pop.get(j); + popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1])); + tp.getFunctionArea().addDElement(popRep); - plotLine(tp, pop.getEAIndividual(j), pop.getBestEAIndividual()); - } - } else { - // this is an inactive species - plotIndy(tp, '+',(InterfaceDataTypeDouble)pop.get(0)); - } - } + plotLine(tp, pop.getEAIndividual(j), pop.getBestEAIndividual()); + } + } else { + // this is an inactive species + plotIndy(tp, '+', (InterfaceDataTypeDouble) pop.get(0)); + } + } - public static void plotLine(TopoPlot tp, AbstractEAIndividual indy1, - AbstractEAIndividual indy2) { + public static void plotLine(TopoPlot tp, AbstractEAIndividual indy1, + AbstractEAIndividual indy2) { // DPointSet popRep; - double[] pos1, pos2; - if (indy1 instanceof InterfaceDataTypeDouble) { - pos1=((InterfaceDataTypeDouble)indy1).getDoubleData(); - } - else { - pos1=(indy1).getDoublePosition(); - } - if (indy2 instanceof InterfaceDataTypeDouble) { - pos2=((InterfaceDataTypeDouble)indy2).getDoubleData(); - } - else { - pos2 =(indy2).getDoublePosition(); - } - tp.getFunctionArea().drawLine(pos1, pos2); - } + double[] pos1, pos2; + if (indy1 instanceof InterfaceDataTypeDouble) { + pos1 = ((InterfaceDataTypeDouble) indy1).getDoubleData(); + } else { + pos1 = (indy1).getDoublePosition(); + } + if (indy2 instanceof InterfaceDataTypeDouble) { + pos2 = ((InterfaceDataTypeDouble) indy2).getDoubleData(); + } else { + pos2 = (indy2).getDoublePosition(); + } + tp.getFunctionArea().drawLine(pos1, pos2); + } - public static void plotIndy(Plot p, char c, InterfaceDataTypeDouble tmpIndy) { - plotPosFit(p, c, tmpIndy.getDoubleData(), ((AbstractEAIndividual)tmpIndy).getFitness(0)); - } + public static void plotIndy(Plot p, char c, InterfaceDataTypeDouble tmpIndy) { + plotPosFit(p, c, tmpIndy.getDoubleData(), ((AbstractEAIndividual) tmpIndy).getFitness(0)); + } - public static void plotPosFit(Plot p, char c, double[] position, double fitness) { - DPointSet popRep; - popRep = new DPointSet(); - popRep.addDPoint(new DPoint(position[0], position[1])); - double d = Math.round(100*fitness)/(double)100; - DPointIcon icon = new Chart2DDPointIconText(c+""+d); - ((Chart2DDPointIconText)icon).setIcon(new Chart2DDPointIconCircle()); - popRep.setIcon(icon); - p.getFunctionArea().addDElement(popRep); - } + public static void plotPosFit(Plot p, char c, double[] position, double fitness) { + DPointSet popRep; + popRep = new DPointSet(); + popRep.addDPoint(new DPoint(position[0], position[1])); + double d = Math.round(100 * fitness) / (double) 100; + DPointIcon icon = new Chart2DDPointIconText(c + "" + d); + ((Chart2DDPointIconText) icon).setIcon(new Chart2DDPointIconCircle()); + popRep.setIcon(icon); + p.getFunctionArea().addDElement(popRep); + } - /** This method is called to generate n freshly initialized individuals - * @param n Number of new individuals + /** + * This method is called to generate n freshly initialized individuals + * + * @param n Number of new individuals * @return A population of new individuals */ private Population initializeIndividuals(int n) { @@ -396,53 +395,53 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis return result; } - /** - * This method checks whether a species is converged, i.e. the best fitness has not improved - * for a number of generations. - * - * @param pop The species to test + /** + * This method checks whether a species is converged, i.e. the best fitness + * has not improved for a number of generations. + * + * @param pop The species to test * @return True if converged. */ private boolean testSpeciesForConvergence(Population pop) { - int histLen = pop.getHistoryLength(); + int histLen = pop.getHistoryLength(); if (histLen < haltingWindow) { // System.out.println("not long enough... gen " + pop.getGeneration()); - return false; + return false; } else { // TODO: undo: InterfaceTerminator convergenceTerminator = new DiversityTerminator(epsilonBound,new PhenotypeMetric(),0); // boolean term = convergenceTerminator.isTerminated(pop); - - InterfaceTerminator convergenceTerminator = new HistoryConvergenceTerminator(haltingWindow, epsilonBound, 0, false); - boolean term = convergenceTerminator.isTerminated(pop); + + InterfaceTerminator convergenceTerminator = new HistoryConvergenceTerminator(haltingWindow, epsilonBound, 0, false); + boolean term = convergenceTerminator.isTerminated(pop); // if (term) { // System.out.println("Conv spec. aged " + pop.getGeneration() + " with meas. " + BeanInspector.toString(pop.getPopulationMeasures())); // } - if (term) { - // this case is especially relevant if sequential niching is "faked" using the CBN approach, - // because in this case, the niching parameter is very large and the single (sequentially build) species - // may be still spread throughout the search space and still not improve for the given halting window. - // Omitting this causes high numbers of phantom solutions which are far from converged optima - double[] specMeas = pop.getPopulationMeasures(); - if (specMeas[0]>avgDistForConvergence ) { + if (term) { + // this case is especially relevant if sequential niching is "faked" using the CBN approach, + // because in this case, the niching parameter is very large and the single (sequentially build) species + // may be still spread throughout the search space and still not improve for the given halting window. + // Omitting this causes high numbers of phantom solutions which are far from converged optima + double[] specMeas = pop.getPopulationMeasures(); + if (specMeas[0] > avgDistForConvergence) { // if (getClusterDiffDist()<=0.5) // System.err.println("ALTERNATIVE BREAK, FORBIDDING CONVERGENCE! sig=" + getClusterDiffDist() + " / avD="+ specMeas[0]); - InterfaceTerminator convTerm2 = new HistoryConvergenceTerminator(2*haltingWindow, epsilonBound, 0, false); - term = convTerm2.isTerminated(pop); - if (term) { + InterfaceTerminator convTerm2 = new HistoryConvergenceTerminator(2 * haltingWindow, epsilonBound, 0, false); + term = convTerm2.isTerminated(pop); + if (term) { // System.out.println("Twice the halting window passed without improvement and still no phenotypic convergence!!!"); - return true; - } else { + return true; + } else { return false; } - } - } - - if (term) { + } + } + + if (term) { // System.out.println(); - } - // TODO something like this may be used as additional convergence criterion. - // it influences the number of local optima archived and seems to increase the score, but not the best-found solutions, at least for a large clustering parameter + } + // TODO something like this may be used as additional convergence criterion. + // it influences the number of local optima archived and seems to increase the score, but not the best-found solutions, at least for a large clustering parameter // System.out.println("Terminated, subswarm measures: " + BeanInspector.toString(pop.getPopulationMeasures())); // if (m_Optimizer instanceof ParticleSwarmOptimization) { // double swarmSp = ParticleSwarmOptimization.getPopulationVelSpeed(pop, 2, ParticleSwarmOptimization.partVelKey, null, null)[0]; @@ -453,75 +452,77 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis // } // } // } - return term; + return term; } } /** - * Define the criterion by which individual improvement is judged. The original version defined - * improvement strictly, but for some EA this should be done more laxly. E.g. DE will hardly ever - * stop improving slightly, so optionally use an epsilon-bound: improvement only counts if it is - * larger than epsilon in case useEpsilonBound is true. - * + * Define the criterion by which individual improvement is judged. The + * original version defined improvement strictly, but for some EA this + * should be done more laxly. E.g. DE will hardly ever stop improving + * slightly, so optionally use an epsilon-bound: improvement only counts if + * it is larger than epsilon in case useEpsilonBound is true. + * * @param firstIndy * @param secIndy - * @return true if the second individual has improved in relation to the first one + * @return true if the second individual has improved in relation to the + * first one */ private boolean testSecondForImprovement(AbstractEAIndividual firstIndy, AbstractEAIndividual secIndy) { - if (epsilonBound > 0) { - double fitDiff = (new ObjectiveSpaceMetric()).distance(firstIndy, secIndy); - boolean ret = (secIndy.isDominatingDebConstraints(firstIndy)); - ret = ret && (fitDiff > epsilonBound); // there is improvement if the second is dominant and the fitness difference is larger than epsilon - return ret; - } else { - return (histComparator.compare(firstIndy, secIndy)>0); + if (epsilonBound > 0) { + double fitDiff = (new ObjectiveSpaceMetric()).distance(firstIndy, secIndy); + boolean ret = (secIndy.isDominatingDebConstraints(firstIndy)); + ret = ret && (fitDiff > epsilonBound); // there is improvement if the second is dominant and the fitness difference is larger than epsilon + return ret; + } else { + return (histComparator.compare(firstIndy, secIndy) > 0); // return (secIndy.isDominatingDebConstraints(firstIndy)); - } + } } - - private Population optimizeSpecies(Population species, boolean minorPlot) { - m_Optimizer.setPopulation(species); -// m_Optimizer.initByPopulation(species, false); - if (m_Optimizer instanceof EvolutionStrategies) { - EvolutionStrategies es = (EvolutionStrategies)m_Optimizer; - int mu = Math.max(1,(int)(muLambdaRatio*species.size())); - if (mu >= species.size()) { - if (TRACE) { - System.err.println("warning, muLambdaRatio produced mu >= lambda.. reducing to mu=lambda-1"); - } - mu = Math.max(1,species.size() - 1); - } - es.setMu(mu); - es.setLambda(species.size()); - if (TRACE) { - System.out.println("mu: "+es.getMu() + " / lambda: " + es.getLambda()); - } - } - if (TRACE) { - System.out.println("Bef: spec size: " + species.size() + ", target size " + species.getTargetSize()); - System.out.println("Best bef: " + BeanInspector.toString(m_Optimizer.getPopulation().getBestFitness())); - } - - if (BeanInspector.hasMethod(m_Optimizer, "getLastModelPopulation", null)!=null) { - Object pc = BeanInspector.callIfAvailable(m_Optimizer, "getLastTrainingPatterns", null); -// System.out.println("MAPSO train set bef optSpec: " + BeanInspector.callIfAvailable(pc, "getStringRepresentation", null)); - } - this.m_Optimizer.optimize(); - Population retPop = m_Optimizer.getPopulation(); - - if (TRACE) { - System.out.println("Aft: spec size: " + retPop.size() + ", target size " + retPop.getTargetSize()); - System.out.println("Best aft: " + BeanInspector.toString(retPop.getBestFitness())); - } - if (retPop.size() != retPop.getTargetSize()) { - if (TRACE) { + private Population optimizeSpecies(Population species, boolean minorPlot) { + m_Optimizer.setPopulation(species); +// m_Optimizer.initByPopulation(species, false); + if (m_Optimizer instanceof EvolutionStrategies) { + EvolutionStrategies es = (EvolutionStrategies) m_Optimizer; + int mu = Math.max(1, (int) (muLambdaRatio * species.size())); + if (mu >= species.size()) { + if (TRACE) { + System.err.println("warning, muLambdaRatio produced mu >= lambda.. reducing to mu=lambda-1"); + } + mu = Math.max(1, species.size() - 1); + } + es.setMu(mu); + es.setLambda(species.size()); + if (TRACE) { + System.out.println("mu: " + es.getMu() + " / lambda: " + es.getLambda()); + } + } + if (TRACE) { + System.out.println("Bef: spec size: " + species.size() + ", target size " + species.getTargetSize()); + System.out.println("Best bef: " + BeanInspector.toString(m_Optimizer.getPopulation().getBestFitness())); + } + + if (BeanInspector.hasMethod(m_Optimizer, "getLastModelPopulation", null) != null) { + Object pc = BeanInspector.callIfAvailable(m_Optimizer, "getLastTrainingPatterns", null); +// System.out.println("MAPSO train set bef optSpec: " + BeanInspector.callIfAvailable(pc, "getStringRepresentation", null)); + } + + this.m_Optimizer.optimize(); + Population retPop = m_Optimizer.getPopulation(); + + if (TRACE) { + System.out.println("Aft: spec size: " + retPop.size() + ", target size " + retPop.getTargetSize()); + System.out.println("Best aft: " + BeanInspector.toString(retPop.getBestFitness())); + } + if (retPop.size() != retPop.getTargetSize()) { + if (TRACE) { System.out.println("correcting popsize after opt: " + retPop.getTargetSize() + " to " + retPop.size()); } - retPop.synchSize(); - } - + retPop.synchSize(); + } + // if (useDistraction) { // distraction step // if ((distraction != null) && (!distraction.isEmpty())) { // System.out.println("Distraction step!!!"); @@ -536,48 +537,48 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis // } // } // } - return retPop; + return retPop; } - + @Override public void optimize() { - Population reinitPop = null; - if (TRACE_STATE) { - printState("---- CBN Optimizing", m_doomedPop); - // System.out.println("-Funcalls: "+m_Undifferentiated.getFunctionCalls()); - } - if (m_doomedPop.size()>0) { - reinitPop = this.initializeIndividuals(m_doomedPop.size()); // do not add these to undifferentiated yet, that would mess up the evaluation count - m_doomedPop.clear(); + Population reinitPop = null; + if (TRACE_STATE) { + printState("---- CBN Optimizing", m_doomedPop); + // System.out.println("-Funcalls: "+m_Undifferentiated.getFunctionCalls()); + } + if (m_doomedPop.size() > 0) { + reinitPop = this.initializeIndividuals(m_doomedPop.size()); // do not add these to undifferentiated yet, that would mess up the evaluation count + m_doomedPop.clear(); // if (TRACE) // System.out.println("At " + m_Undifferentiated.getFunctionCalls() + " reinited " + reinitPop.size() + " indies... "); - } - int countIndies = (reinitPop != null ? reinitPop.size() : 0) + m_Undifferentiated.size(); - for (int i=0; i 0) { - if (m_Undifferentiated.getGeneration()<=1) { + if (this.m_ShowCycle > 0) { + if (m_Undifferentiated.getGeneration() <= 1) { plot(m_Undifferentiated.getGeneration()); } } if (sleepTime > 0) { - try { - Thread.sleep(sleepTime); - } catch (InterruptedException e) { - e.printStackTrace(); - } + try { + Thread.sleep(sleepTime); + } catch (InterruptedException e) { + e.printStackTrace(); + } } - + // species evolution phase // optimize D_0 this.m_Undifferentiated.synchSize(); - if (m_Undifferentiated.size()>0) { + if (m_Undifferentiated.size() > 0) { // this.capMutationRate(this.m_Undifferentiated, 0); // MK this sets mutation rate to 0! why? possibly to guarantee contraction of the species? - m_Undifferentiated.putData(InterfaceSpeciesAware.populationTagKey, InterfaceSpeciesAware.explorerPopTag); + m_Undifferentiated.putData(InterfaceSpeciesAware.populationTagKey, InterfaceSpeciesAware.explorerPopTag); m_Undifferentiated = optimizeSpecies(m_Undifferentiated, false); } else { m_Undifferentiated.incrGeneration(); @@ -587,56 +588,56 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis // optimize the clustered species for (int i = this.m_Species.size() - 1; i >= 0; i--) { if (TRACE) { - System.out.println("-Deme " + i + " size: " + ((Population)this.m_Species.get(i)).size()); + System.out.println("-Deme " + i + " size: " + ((Population) this.m_Species.get(i)).size()); } - curSpecies = ((Population)this.m_Species.get(i)); + curSpecies = ((Population) this.m_Species.get(i)); curSpecies.SetFunctionCalls(0); curSpecies.synchSize(); // if (isActive(curSpecies)) { // Lets have only active species... - if ((haltingWindow > 0) && (this.testSpeciesForConvergence(curSpecies))) { + if ((haltingWindow > 0) && (this.testSpeciesForConvergence(curSpecies))) { ///////////////////////////////////////////// Halting Window ///////////////////////////////////////////////// // if (this.m_Debug) { // System.out.println("Undiff.Size: " + this.m_Undifferentiated.size() +"/"+this.m_Undifferentiated.getPopulationSize()); // System.out.println("Diff.Size : " + ((Population)this.m_Species.get(i)).size() +"/"+((Population)this.m_Species.get(i)).getPopulationSize()); // } - convergedCnt++; - if (TRACE_EVTS) { - System.out.println("!!!! Converged Spec!"); - } - if (TRACE) { - testSpeciesForConvergence(curSpecies); - System.out.print("--Converged: "+convergedCnt + " - " + testSpeciesForConvergence(curSpecies)); - } - if (TRACE) { - System.out.println(curSpecies.getBestEAIndividual()); - } - - // memorize the best one.... + convergedCnt++; + if (TRACE_EVTS) { + System.out.println("!!!! Converged Spec!"); + } + if (TRACE) { + testSpeciesForConvergence(curSpecies); + System.out.print("--Converged: " + convergedCnt + " - " + testSpeciesForConvergence(curSpecies)); + } + if (TRACE) { + System.out.println(curSpecies.getBestEAIndividual()); + } + + // memorize the best one.... // AbstractEAIndividual best = (AbstractEAIndividual)curSpecies.getBestEAIndividual().getClone(); - AbstractEAIndividual best = curSpecies.getBestHistoric(); // usually we want the best alltogether - if (best == null) { - best = (AbstractEAIndividual)curSpecies.getBestEAIndividual().getClone(); - } + AbstractEAIndividual best = curSpecies.getBestHistoric(); // usually we want the best alltogether + if (best == null) { + best = (AbstractEAIndividual) curSpecies.getBestEAIndividual().getClone(); + } // if (useDistraction) { // Add distractor! // if (distraction == null) distraction = new Distraction(distrDefaultStrength, Distraction.METH_BEST); // distraction.addDistractorFrom(curSpecies); // System.out.println("** Adding distractor! " + BeanInspector.toString(distraction.getDistractionCenter(curSpecies, distraction.getDistractionMethod().getSelectedTagID()))); // } - int toReinit=0; - if (true) { //if (m_UseArchive) { - m_Archive.add(best); + int toReinit = 0; + if (true) { //if (m_UseArchive) { + m_Archive.add(best); // System.out.println((""+ m_Population.getFunctionCalls() + " " + (BeanInspector.toString(best.getDoublePosition())).replaceAll(";|\\[|\\]", ""))); - m_Species.remove(i); // remove the converged Species - toReinit=curSpecies.size(); - } + m_Species.remove(i); // remove the converged Species + toReinit = curSpecies.size(); + } // else { // // reset the converged species to inactivity size = 1 // toReinit=curSpecies.size()-1; // deactivateSpecies(curSpecies, best, null); // } - // those will not be optimized anymore, so we dont need to doom them, but can directly add them to undiff! - m_Undifferentiated.addPopulation(initializeIndividuals(toReinit)); - m_Undifferentiated.incrFunctionCallsBy(toReinit); + // those will not be optimized anymore, so we dont need to doom them, but can directly add them to undiff! + m_Undifferentiated.addPopulation(initializeIndividuals(toReinit)); + m_Undifferentiated.incrFunctionCallsBy(toReinit); // if (this.m_Debug) { // System.out.println("Undiff.Size: " + this.m_Undifferentiated.size() +"/"+this.m_Undifferentiated.getPopulationSize()); @@ -644,46 +645,46 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis // } // if (this.m_Debug) System.out.println("--------------------------End converged"); ////////////////////////////////////////////////////////////////////////////////////////////////////////////// - } else { - // actually optimize D_i + } else { + // actually optimize D_i // this.capMutationRate(curSpecies, 0.05); - curSpecies.putData(InterfaceSpeciesAware.populationTagKey, InterfaceSpeciesAware.localPopTag); - Population optimizedSpec = optimizeSpecies(curSpecies, true); - this.m_Species.set(i, optimizedSpec); - curSpecies = ((Population)this.m_Species.get(i)); // reset to expected population, just to be sure - } + curSpecies.putData(InterfaceSpeciesAware.populationTagKey, InterfaceSpeciesAware.localPopTag); + Population optimizedSpec = optimizeSpecies(curSpecies, true); + this.m_Species.set(i, optimizedSpec); + curSpecies = ((Population) this.m_Species.get(i)); // reset to expected population, just to be sure + } // } // This is necessary to keep track of the function calls needed m_Undifferentiated.incrFunctionCallsBy(curSpecies.getFunctionCalls()); if (TRACE) { - System.out.println("### funcalls: "+m_Undifferentiated.getFunctionCalls()); + System.out.println("### funcalls: " + m_Undifferentiated.getFunctionCalls()); } } - + ////////////////////// synchronized (m_Population) { // fill the m_Population instance with the current individuals from undiff, spec, etc. - this.m_Population = (Population)this.m_Undifferentiated.clone(); - m_Population.setUseHistory(true); - for (int i = 0; i < this.m_Species.size(); i++) { - this.m_Population.addPopulation((Population)this.m_Species.get(i)); - } - if (m_doomedPop.size()>0) { + this.m_Population = (Population) this.m_Undifferentiated.clone(); + m_Population.setUseHistory(true); + for (int i = 0; i < this.m_Species.size(); i++) { + this.m_Population.addPopulation((Population) this.m_Species.get(i)); + } + if (m_doomedPop.size() > 0) { m_Population.addPopulation(reinitPop); } // this is just so that the numbers match up... - m_Population.synchSize(); + m_Population.synchSize(); } - + ////////////////////// - if ((this.m_Undifferentiated.getFunctionCalls()+(reinitPop==null ? 0 : (reinitPop.size()))) % this.m_PopulationSize != 0) { - if (TRACE) { + if ((this.m_Undifferentiated.getFunctionCalls() + (reinitPop == null ? 0 : (reinitPop.size()))) % this.m_PopulationSize != 0) { + if (TRACE) { System.out.println("### mismatching number of funcalls, inactive species?"); }// Correcting by " + (m_PopulationSize - (m_Undifferentiated.getFunctionCalls() % m_PopulationSize))); // if (TRACE) System.out.println("### undiff " + ((isActive(m_Undifferentiated)) ? "active!" : "inactive!")); // m_Undifferentiated.incrFunctionCallsBy(m_PopulationSize - (m_Undifferentiated.getFunctionCalls() % m_PopulationSize)); } //else if (TRACE) System.out.println("### undiff active: " + isActive(m_Undifferentiated)); - + // possible species differentiation and convergence - if (this.m_Undifferentiated.getGeneration()%this.m_SpeciesCycle == 0) { + if (this.m_Undifferentiated.getGeneration() % this.m_SpeciesCycle == 0) { if (TRACE) { System.out.println("Species cycle:"); } @@ -694,10 +695,10 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis if (TRACE) { printState("---Species Differentation", reinitPop); } - Population[] clusters; - ArrayList newSpecies = new ArrayList(); + Population[] clusters; + ArrayList newSpecies = new ArrayList(); //cluster the undifferentiated population - clusters = this.m_CAForSpeciesDifferentation.cluster(this.m_Undifferentiated, m_Population); + clusters = this.m_CAForSpeciesDifferentation.cluster(this.m_Undifferentiated, m_Population); if (TRACE) { System.out.println("clustered undiff to " + clusters.length); } @@ -707,28 +708,28 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis } replaceUndifferentiated(clusters[0]); for (int i = 0; i < this.m_Species.size(); i++) { // loop old species - curSpecies = this.m_Species.get(i); + curSpecies = this.m_Species.get(i); // if (curSpecies.size()>m_minGroupSize) { // only active populations are clustered - // check if a species has differentiated any further - clusters = this.m_CAForSpeciesDifferentation.cluster(curSpecies, m_Population); - if (TRACE) { + // check if a species has differentiated any further + clusters = this.m_CAForSpeciesDifferentation.cluster(curSpecies, m_Population); + if (TRACE) { System.out.println("clustered " + i + " to " + clusters.length); } - if (clusters[0].size()>0) { + if (clusters[0].size() > 0) { mergeToFirst(m_Undifferentiated, clusters[0], false); } - for (int j = 1; j < clusters.length; j++) { // set up new species - // this is treated as a split only if more than one cluster was found - // so if clustering results in a list of size 2: [undiff,spec], the curSpecies only is maintained. - if (clusters.length<=2) { - clusters[j].addDataFromPopulation(curSpecies); - } // copy earlier data to corresponding new cluster - else { - splitFromFirst(curSpecies, clusters[j], true); - } - newSpecies.add(clusters[j]); - + for (int j = 1; j < clusters.length; j++) { // set up new species + // this is treated as a split only if more than one cluster was found + // so if clustering results in a list of size 2: [undiff,spec], the curSpecies only is maintained. + if (clusters.length <= 2) { + clusters[j].addDataFromPopulation(curSpecies); + } // copy earlier data to corresponding new cluster + else { + splitFromFirst(curSpecies, clusters[j], true); } + newSpecies.add(clusters[j]); + + } // } else { // // small populations are kept directly // newSpecies.add(curSpecies); @@ -742,33 +743,33 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis //if (this.m_Show) this.plot(); } // end of species differentiation - // plot the populations - if (this.m_ShowCycle > 0) { - if ((this.m_Undifferentiated.getGeneration() <= 2) || (this.m_Undifferentiated.getGeneration()%this.m_ShowCycle == 0)) { + // plot the populations + if (this.m_ShowCycle > 0) { + if ((this.m_Undifferentiated.getGeneration() <= 2) || (this.m_Undifferentiated.getGeneration() % this.m_ShowCycle == 0)) { this.plot(this.m_Undifferentiated.getGeneration()); } } - if (this.m_mergeSpecies && (m_Species.size()>0)) { + if (this.m_mergeSpecies && (m_Species.size() > 0)) { ///////////////////////////// species merging phase if (TRACE) { - System.out.println("-Species merge:"); + System.out.println("-Species merge:"); } // first test if loners belong to any species int[] assocSpec = m_CAForSpeciesMerging.associateLoners(m_Undifferentiated, m_Species.toArray(new Population[m_Species.size()]), m_Population); - for (int i=m_Undifferentiated.size()-1; i>=0; i--) { // backwards or die! - if (assocSpec[i]>=0) { - if (TRACE_EVTS) { - System.out.println("!!! Loner merge to " + i ); - } - // loner i should be merged to species assocSpec[i] - AbstractEAIndividual tmpIndy = (AbstractEAIndividual)this.m_Undifferentiated.get(i); - if (m_Topology!=null) { - plotLine(m_Topology, tmpIndy, m_Species.get(assocSpec[i]).getBestEAIndividual()); - } + for (int i = m_Undifferentiated.size() - 1; i >= 0; i--) { // backwards or die! + if (assocSpec[i] >= 0) { + if (TRACE_EVTS) { + System.out.println("!!! Loner merge to " + i); + } + // loner i should be merged to species assocSpec[i] + AbstractEAIndividual tmpIndy = (AbstractEAIndividual) this.m_Undifferentiated.get(i); + if (m_Topology != null) { + plotLine(m_Topology, tmpIndy, m_Species.get(assocSpec[i]).getBestEAIndividual()); + } this.m_Undifferentiated.remove(i); m_Species.get(assocSpec[i]).add(tmpIndy); // TODO merge information from loners? - } + } } if (TRACE) { printState("---After loner-merges", reinitPop); @@ -776,58 +777,58 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis Population spec1, spec2; // test if species are close to already archived solutions - deactivate them if so assocSpec = m_CAForSpeciesMerging.associateLoners(m_Archive, m_Species.toArray(new Population[m_Species.size()]), m_Population); - PriorityQueue specToRemove = new PriorityQueue(5,Collections.reverseOrder()); // backwards sorted or DIE! - for (int i=m_Archive.size()-1; i>=0; i--) { - if (assocSpec[i]>=0) { - AbstractEAIndividual aIndy = m_Archive.getEAIndividual(i); - spec1 = (Population)this.m_Species.get(assocSpec[i]); - // archived solution corresponds to an existing species - if (!specToRemove.contains(assocSpec[i])) { - // the species has not yet been deactivated - specToRemove.add(assocSpec[i]); - collisions ++; - if (TRACE) { - System.out.println("Inactive merge - resetting " + spec1.size() + " surplus indies"); - } - if (spec1.getBestEAIndividual().isDominating(aIndy)) { - // update the archived one with the better one? No rather not - it may happen that a large species is assoctiated which is quite large and spans over several optima - in that case an earlier found may get lost + PriorityQueue specToRemove = new PriorityQueue(5, Collections.reverseOrder()); // backwards sorted or DIE! + for (int i = m_Archive.size() - 1; i >= 0; i--) { + if (assocSpec[i] >= 0) { + AbstractEAIndividual aIndy = m_Archive.getEAIndividual(i); + spec1 = (Population) this.m_Species.get(assocSpec[i]); + // archived solution corresponds to an existing species + if (!specToRemove.contains(assocSpec[i])) { + // the species has not yet been deactivated + specToRemove.add(assocSpec[i]); + collisions++; + if (TRACE) { + System.out.println("Inactive merge - resetting " + spec1.size() + " surplus indies"); + } + if (spec1.getBestEAIndividual().isDominating(aIndy)) { + // update the archived one with the better one? No rather not - it may happen that a large species is assoctiated which is quite large and spans over several optima - in that case an earlier found may get lost // m_Archive.set(i, spec1.getBestEAIndividual()); - } - if (TRACE_EVTS) { - System.out.println("!!! Reinit Spec " + assocSpec[i] + ", fit " + spec1.getBestEAIndividual()); - } - m_doomedPop.addPopulation(spec1); - } - } + } + if (TRACE_EVTS) { + System.out.println("!!! Reinit Spec " + assocSpec[i] + ", fit " + spec1.getBestEAIndividual()); + } + m_doomedPop.addPopulation(spec1); + } + } } int lastRemoved = Integer.MAX_VALUE; while (!specToRemove.isEmpty()) { // backwards sorted or DIE! - int specIndex = specToRemove.poll(); - if (specIndex > lastRemoved) { + int specIndex = specToRemove.poll(); + if (specIndex > lastRemoved) { System.err.println("Stupid queue!!!"); } - if (TRACE) { + if (TRACE) { System.out.println("Removing species at index " + specIndex); } - m_Species.remove(specIndex); // warning, dont try to remove Integer object but index i! - lastRemoved = specIndex; + m_Species.remove(specIndex); // warning, dont try to remove Integer object but index i! + lastRemoved = specIndex; } if (TRACE) { printState("---After archive-merges", reinitPop); } // Now test if species should be merged among each other for (int i1 = 0; i1 < this.m_Species.size(); i1++) { - spec1 = (Population)this.m_Species.get(i1); - for (int i2 = i1+1; i2 < this.m_Species.size(); i2++) { - spec2 = (Population)this.m_Species.get(i2); + spec1 = (Population) this.m_Species.get(i1); + for (int i2 = i1 + 1; i2 < this.m_Species.size(); i2++) { + spec2 = (Population) this.m_Species.get(i2); if (this.m_CAForSpeciesMerging.mergingSpecies(spec1, spec2, m_Population)) { - - if (TRACE_EVTS || TRACE) { - System.out.println("!!! -Merging species (" + i1 +", " +i2 +") ["+spec1.size()+"/"+spec2.size()+"]"); + + if (TRACE_EVTS || TRACE) { + System.out.println("!!! -Merging species (" + i1 + ", " + i2 + ") [" + spec1.size() + "/" + spec2.size() + "]"); } - mergeToFirst(spec1, spec2, true); - this.m_Species.remove(i2); - i2--; + mergeToFirst(spec1, spec2, true); + this.m_Species.remove(i2); + i2--; } } } @@ -837,61 +838,61 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis } /// end of species merging if (m_maxSpeciesSize >= m_minGroupSize) { - // reinit worst n individuals from all species which are too large - for (int i=0; im_maxSpeciesSize) { - if (TRACE_EVTS) { - System.out.println("!!! Reinit indies " + (m_maxSpeciesSize - curSpec.size())); + // reinit worst n individuals from all species which are too large + for (int i = 0; i < m_Species.size(); i++) { + Population curSpec = m_Species.get(i); + if (curSpec.size() > m_maxSpeciesSize) { + if (TRACE_EVTS) { + System.out.println("!!! Reinit indies " + (m_maxSpeciesSize - curSpec.size())); + } + ArrayList sorted = curSpec.getSorted(reduceSizeComparator); + for (int k = m_maxSpeciesSize; k < sorted.size(); k++) { + if (curSpec.remove(sorted.get(k))) { + m_doomedPop.add(sorted.get(k)); } - ArrayList sorted = curSpec.getSorted(reduceSizeComparator); - for (int k=m_maxSpeciesSize; k0)) { - m_Undifferentiated.addPopulation(reinitPop); - m_Undifferentiated.incrFunctionCallsBy(reinitPop.size()); + if ((reinitPop != null) && (reinitPop.size() > 0)) { + m_Undifferentiated.addPopulation(reinitPop); + m_Undifferentiated.incrFunctionCallsBy(reinitPop.size()); } - m_Undifferentiated.setTargetSize(m_Undifferentiated.size()); + m_Undifferentiated.setTargetSize(m_Undifferentiated.size()); // output the result if (TRACE) { System.out.println("-Funcalls: " + this.m_Undifferentiated.getFunctionCalls()); } - + synchronized (m_Population) { // fill the m_Population instance with the current individuals from undiff, spec, etc. - this.m_Population = (Population)this.m_Undifferentiated.clone(); - m_Population.setUseHistory(true); - for (int i = 0; i < this.m_Species.size(); i++) { - this.m_Population.addPopulation((Population)this.m_Species.get(i)); - } - if (m_doomedPop.size()>0) { + this.m_Population = (Population) this.m_Undifferentiated.clone(); + m_Population.setUseHistory(true); + for (int i = 0; i < this.m_Species.size(); i++) { + this.m_Population.addPopulation((Population) this.m_Species.get(i)); + } + if (m_doomedPop.size() > 0) { m_Population.addPopulation(m_doomedPop); } // this is just so that the numbers match up... - m_Population.synchSize(); - if (TRACE) { - System.out.println("Doomed size: " + m_doomedPop.size()); - System.out.println("Population size: " + this.m_Population.size()); - } - if (m_Population.size()!=m_PopulationSize) { - System.err.println("Warning: Invalid population size in CBNEA! " + m_Population.size()); - } - if (TRACE_STATE) { - printState("---- EoCBN", m_doomedPop); - System.out.println("Archive: " + m_Archive.getStringRepresentation()); - } + m_Population.synchSize(); + if (TRACE) { + System.out.println("Doomed size: " + m_doomedPop.size()); + System.out.println("Population size: " + this.m_Population.size()); + } + if (m_Population.size() != m_PopulationSize) { + System.err.println("Warning: Invalid population size in CBNEA! " + m_Population.size()); + } + if (TRACE_STATE) { + printState("---- EoCBN", m_doomedPop); + System.out.println("Archive: " + m_Archive.getStringRepresentation()); + } } // if (TRACE) { // // this is just a test adding all species centers as distractors with high strength @@ -901,26 +902,26 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis // System.out.println("species distract best towards " + BeanInspector.toString(distVect)); // } // } - + this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - + /** * Initialize the clustering method for differentiation. - * + * */ private void initClustering() { - if (getClusterDiffDist()>0) { // assume that it should be set - if (this.m_CAForSpeciesDifferentation instanceof InterfaceClusteringDistanceParam) { - ((InterfaceClusteringDistanceParam)m_CAForSpeciesDifferentation).setClustDistParam(getClusterDiffDist()); - if (TRACE) { - System.out.println("### Clustering distance parameter set to "+ getClusterDiffDist()); - } - } else { + if (getClusterDiffDist() > 0) { // assume that it should be set + if (this.m_CAForSpeciesDifferentation instanceof InterfaceClusteringDistanceParam) { + ((InterfaceClusteringDistanceParam) m_CAForSpeciesDifferentation).setClustDistParam(getClusterDiffDist()); + if (TRACE) { + System.out.println("### Clustering distance parameter set to " + getClusterDiffDist()); + } + } else { EVAERROR.errorMsgOnce("Warning: cluster distance is defined in CBN but the clustering method " + m_CAForSpeciesDifferentation.getClass() + " cant interpret it!"); } - } - this.m_CAForSpeciesDifferentation.initClustering(m_Population); + } + this.m_CAForSpeciesDifferentation.initClustering(m_Population); } // @@ -938,52 +939,51 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis // pop.synchSize(); // return pop; // } - - /** + /** * Replace the undifferentiated population with the given one. - * + * * @param pop */ - private void replaceUndifferentiated(Population pop) { + private void replaceUndifferentiated(Population pop) { // System.out.println("Adding " + pop.size() + " as undiff."); - m_Undifferentiated.clear(); - m_Undifferentiated.addPopulation(pop); - } + m_Undifferentiated.clear(); + m_Undifferentiated.addPopulation(pop); + } - private void printState(String headline, Population reinit) { - System.out.print(headline + ", Gen. " + this.m_Undifferentiated.getGeneration()); - System.out.print(" - Undiff.: " + specTag(m_Undifferentiated)); - System.out.print(", Demes: "); - int sum=m_Undifferentiated.size() + (reinit==null ? 0 : reinit.size()); - if (m_Species.size()>0) { - sum+=m_Species.get(0).size(); - System.out.print(specTag(m_Species.get(0))); - for (int i=1; i 0) { + sum += m_Species.get(0).size(); + System.out.print(specTag(m_Species.get(0))); + for (int i = 1; i < m_Species.size(); i++) { + System.out.print(", " + specTag(m_Species.get(i))); + sum += m_Species.get(i).size(); + } + } + System.out.println(", reinit: " + (reinit == null ? 0 : reinit.size()) + ", sum: " + sum); + } + + private String specTag(Population spec) { + return spec.size() + "(" + spec.getGeneration() + ((spec.hasData("MAPSOModelInformation")) ? "/" + (BeanInspector.callIfAvailable(spec.getData("MAPSOModelInformation"), "getStringRepresentation", null)) : "") + ")"; + } /** - * Merge two species by adding the second to the first. Keep the longer history. The second - * species should be deactivated after merging. - * + * Merge two species by adding the second to the first. Keep the longer + * history. The second species should be deactivated after merging. + * * @param pop1 * @param pop2 */ protected void mergeToFirst(Population spec1, Population spec2, boolean plot) { // System.out.println("Merging " + spec2.size() + " to " + spec1.size()); - if (plot && (m_Topology!=null)) { + if (plot && (m_Topology != null)) { plotLine(m_Topology, spec1.getBestEAIndividual(), spec2.getBestEAIndividual()); } - spec1.addPopulation(spec2); - // keep longer history + spec1.addPopulation(spec2); + // keep longer history if (spec2.getHistoryLength() > spec1.getHistoryLength()) { spec1.SetHistory(spec2.getHistory()); } @@ -992,32 +992,33 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis } // possibly notify the optimizer of the merging event to merge population based information if (m_Optimizer instanceof InterfaceSpeciesAware) { - ((InterfaceSpeciesAware)m_Optimizer).mergeToFirstPopulationEvent(spec1, spec2); + ((InterfaceSpeciesAware) m_Optimizer).mergeToFirstPopulationEvent(spec1, spec2); } } /** - * A split event will reset the new species model so as to have a fresh start. - * + * A split event will reset the new species model so as to have a fresh + * start. + * * @param parentSp * @param newSp * @param startAtP1Gen */ protected void splitFromFirst(Population parentSp, Population newSp, boolean startAtP1Gen) { - newSp.setTargetSize(newSp.size()); - newSp.setUseHistory(true); - if (startAtP1Gen) { // start explicitely as a child population of p1 - newSp.setGenerationTo(parentSp.getGeneration()); - newSp.SetHistory((LinkedList) parentSp.getHistory().clone()); - } else { // start anew (from undiff) - newSp.setGenerationTo(0); + newSp.setTargetSize(newSp.size()); + newSp.setUseHistory(true); + if (startAtP1Gen) { // start explicitely as a child population of p1 + newSp.setGenerationTo(parentSp.getGeneration()); + newSp.SetHistory((LinkedList) parentSp.getHistory().clone()); + } else { // start anew (from undiff) + newSp.setGenerationTo(0); newSp.SetHistory(new LinkedList()); - } - - if (m_Optimizer instanceof InterfaceSpeciesAware) { - ((InterfaceSpeciesAware)m_Optimizer).splitFromFirst(parentSp, newSp); } - } + + if (m_Optimizer instanceof InterfaceSpeciesAware) { + ((InterfaceSpeciesAware) m_Optimizer).splitFromFirst(parentSp, newSp); + } + } // /** // * Return true if the given population is considered active. @@ -1028,7 +1029,6 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis // protected boolean isActive(Population pop) { // return (pop.size() >= m_actSpecSize); // } - // /** // * Deactivate a given species by removing all individuals and inserting // * only the given survivor, sets the population size to one. @@ -1042,7 +1042,6 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis // spec.add(survivor); // spec.setPopulationSize(1); // } - // public int countActiveSpec() { // int k = 0; // for (int i=0; i0) { + for (Population sp : m_Species) { + sols.add(sp.getBestIndividual()); + } + if (m_Undifferentiated.size() > 0) { sols.add(m_Undifferentiated.getBestIndividual()); } // if (!sols.checkNoNullIndy()) { // System.err.println("error in CBN..."); // } - sols.synchSize(); - return new SolutionSet(getPopulation(), sols); + sols.synchSize(); + return new SolutionSet(getPopulation(), sols); } // /** Clearing removes all but the best individuals from an identified species. @@ -1209,61 +1217,76 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis // public String applyClearingTipText() { // return "Clearing removes all but the best individuals from an identified species."; // } - - /** This method allows you to set/get the switch that toggles the use - * of species convergence. + /** + * This method allows you to set/get the switch that toggles the use of + * species convergence. + * * @return The current status of this flag */ public boolean isUseMerging() { return this.m_mergeSpecies; } - public void setUseMerging(boolean b){ + + public void setUseMerging(boolean b) { this.m_mergeSpecies = b; GenericObjectEditor.setHideProperty(this.getClass(), "mergingCA", !m_mergeSpecies); } + public String useMergingTipText() { return "Toggle the use of species merging."; } - - /** Choose a population based optimizing technique to use + + /** + * Choose a population based optimizing technique to use + * * @return The current optimizing method */ public InterfaceOptimizer getOptimizer() { return this.m_Optimizer; } - public void setOptimizer(InterfaceOptimizer b){ + + public void setOptimizer(InterfaceOptimizer b) { this.m_Optimizer = b; - if (b instanceof EvolutionStrategies) { - EvolutionStrategies es = (EvolutionStrategies)b; - setMuLambdaRatio(es.getMu()/(double)es.getLambda()); - } + if (b instanceof EvolutionStrategies) { + EvolutionStrategies es = (EvolutionStrategies) b; + setMuLambdaRatio(es.getMu() / (double) es.getLambda()); + } } + public String optimizerTipText() { return "Choose a population based optimizing technique to use."; } - /** The cluster algorithm on which the species differentiation is based + /** + * The cluster algorithm on which the species differentiation is based + * * @return The current clustering method */ public InterfaceClustering getDifferentiationCA() { return this.m_CAForSpeciesDifferentation; } - public void setDifferentiationCA(InterfaceClustering b){ + + public void setDifferentiationCA(InterfaceClustering b) { this.m_CAForSpeciesDifferentation = b; } + public String differentiationCATipText() { return "The cluster algorithm on which the species differentation is based."; } - /** The Cluster Algorithm on which the species convergence is based. + /** + * The Cluster Algorithm on which the species convergence is based. + * * @return The current clustering method */ public InterfaceClustering getMergingCA() { return this.m_CAForSpeciesMerging; } - public void setMergingCA(InterfaceClustering b){ + + public void setMergingCA(InterfaceClustering b) { this.m_CAForSpeciesMerging = b; } + public String mergingCATipText() { return "The cluster algorithm on which the species merging is based."; } @@ -1277,84 +1300,98 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis // public String useArchiveTipText() { // return "Toggle usage of an archive where converged species are saved and the individuals reinitialized."; // } - - /** Determines how often species differentation/convergence is performed. - * @return This number gives the generations when specification is performed. + /** + * Determines how often species differentation/convergence is performed. + * + * @return This number gives the generations when specification is + * performed. */ public int getSpeciesCycle() { return this.m_SpeciesCycle; } - public void setSpeciesCycle(int b){ + + public void setSpeciesCycle(int b) { this.m_SpeciesCycle = b; } + public String speciesCycleTipText() { return "Determines how often species differentation/convergence is performed."; } - /** TDetermines how often show is performed. - * @return This number gives the generations when specification is performed. + /** + * TDetermines how often show is performed. + * + * @return This number gives the generations when specification is + * performed. */ public int getShowCycle() { return this.m_ShowCycle; } - public void setShowCycle(int b){ + + public void setShowCycle(int b) { this.m_ShowCycle = b; - if (b<=0) { - m_Topology=null; + if (b <= 0) { + m_Topology = null; } } + public String showCycleTipText() { return "Determines how often show is performed (generations); set to zero to deactivate."; } - /** Determines the size of the initial population. + + /** + * Determines the size of the initial population. + * * @return This number gives initial population size. */ public int getPopulationSize() { return this.m_PopulationSize; } - public void setPopulationSize(int b){ + + public void setPopulationSize(int b) { this.m_PopulationSize = b; } + public String populationSizeTipText() { return "Determines the size of the initial population."; } public String[] getGOEPropertyUpdateLinks() { - return new String[] {"population", "populationSize", "populationSize", "population"}; + return new String[]{"population", "populationSize", "populationSize", "population"}; } - + // /** // * @return the muLambdaRatio // */ // public double getMuLambdaRatio() { // return muLambdaRatio; // } + /** + * This is now set if an ES is set as optimizer. + * + * @param muLambdaRatio the muLambdaRatio to set + */ + public void setMuLambdaRatio(double muLambdaRatio) { + this.muLambdaRatio = muLambdaRatio; + } - /** - * This is now set if an ES is set as optimizer. - * @param muLambdaRatio the muLambdaRatio to set - */ - public void setMuLambdaRatio(double muLambdaRatio) { - this.muLambdaRatio = muLambdaRatio; - } + /** + * @return the haltingWindow + */ + public int getHaltingWindow() { + return haltingWindow; + } - /** - * @return the haltingWindow - */ - public int getHaltingWindow() { - return haltingWindow; - } + /** + * @param haltingWindow the haltingWindow to set + */ + public void setHaltingWindow(int haltingWindow) { + this.haltingWindow = haltingWindow; + } - /** - * @param haltingWindow the haltingWindow to set - */ - public void setHaltingWindow(int haltingWindow) { - this.haltingWindow = haltingWindow; - } - - public String haltingWindowTipText() { - return "Number of generations after which a cluster without improvement is seen as converged and deactivated; set to zero to disable."; - } + public String haltingWindowTipText() { + return "Number of generations after which a cluster without improvement is seen as converged and deactivated; set to zero to disable."; + } // /** // * @return the useDistraction @@ -1369,7 +1406,6 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis // public void setDistractionActive(boolean useDistraction) { // this.useDistraction = useDistraction; // } - // /** // * @return the distrDefaultStrength // */ @@ -1384,184 +1420,193 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis // this.distrDefaultStrength = distrDefaultStrength; // distraction.setDefaultStrength(distrDefaultStrength); // } + /** + * @return the sleepTime + */ + public int getSleepTime() { + return sleepTime; + } - /** - * @return the sleepTime - */ - public int getSleepTime() { - return sleepTime; - } - /** - * @param sleepTime the sleepTime to set - */ - public void setSleepTime(int sleepTime) { - this.sleepTime = sleepTime; - } - public String sleepTimeTipText() { - return "Let the thread sleep between iterations (nice when visualizing)"; - } + /** + * @param sleepTime the sleepTime to set + */ + public void setSleepTime(int sleepTime) { + this.sleepTime = sleepTime; + } - /** - * @return the epsilonBound - */ - public double getEpsilonBound() { - return epsilonBound; - } - /** - * @param epsilonBound the epsilonBound to set - */ - public void setEpsilonBound(double epsilonBound) { - this.epsilonBound = epsilonBound; - } - public String epsilonBoundTipText() { - return "If fitness improves less than this value within the halting window, convergence is assumed. May be set to zero."; - } + public String sleepTimeTipText() { + return "Let the thread sleep between iterations (nice when visualizing)"; + } + + /** + * @return the epsilonBound + */ + public double getEpsilonBound() { + return epsilonBound; + } + + /** + * @param epsilonBound the epsilonBound to set + */ + public void setEpsilonBound(double epsilonBound) { + this.epsilonBound = epsilonBound; + } + + public String epsilonBoundTipText() { + return "If fitness improves less than this value within the halting window, convergence is assumed. May be set to zero."; + } @Override - public String[] getAdditionalDataHeader() { - return new String[]{"numUndiff","numActSpec","avgSpecMeas","numArchived", - "archivedMedCorr", "archivedMeanDist", "numCollisions", "clustSig"}; - } - + public String[] getAdditionalDataHeader() { + return new String[]{"numUndiff", "numActSpec", "avgSpecMeas", "numArchived", + "archivedMedCorr", "archivedMeanDist", "numCollisions", "clustSig"}; + } + @Override - public String[] getAdditionalDataInfo() { - return new String[] { - "The number of exploring individuals in the main population", - "The number of active species (sub-populations)", - "The average of the mean distance of individuals within a species", - "The number of stored potential local optima", - "The median correlation of archived solutions", - "The mean distance of archived solutions", - "The number of collisions events that happened so far", - "The clustering distance" - }; - } - + public String[] getAdditionalDataInfo() { + return new String[]{ + "The number of exploring individuals in the main population", + "The number of active species (sub-populations)", + "The average of the mean distance of individuals within a species", + "The number of stored potential local optima", + "The median correlation of archived solutions", + "The mean distance of archived solutions", + "The number of collisions events that happened so far", + "The clustering distance" + }; + } + @Override - public Object[] getAdditionalDataValue(PopulationInterface pop) { + public Object[] getAdditionalDataValue(PopulationInterface pop) { // int actives = countActiveSpec(); - return new Object[] { - m_Undifferentiated.size(), - m_Species.size(), - getAvgSpeciesMeasures()[0], - m_Archive.size(), - m_Archive.getCorrelations()[3], - m_Archive.getPopulationMeasures()[0], - collisions, - getClusterDiffDist()}; + return new Object[]{ + m_Undifferentiated.size(), + m_Species.size(), + getAvgSpeciesMeasures()[0], + m_Archive.size(), + m_Archive.getCorrelations()[3], + m_Archive.getPopulationMeasures()[0], + collisions, + getClusterDiffDist()}; // return m_Undifferentiated.size() + " \t " + m_Species.size() + " \t " + BeanInspector.toString(getAvgSpeciesMeasures()[0]) + " \t " + (m_Archive.size()); - } + } - /** - * Calculate average of Population measures (mean, minimal and maximal distance within a species) - * @return average population measures - */ + /** + * Calculate average of Population measures (mean, minimal and maximal + * distance within a species) + * + * @return average population measures + */ protected double[] getAvgSpeciesMeasures() { - if (m_Species==null || (m_Species.size()==0)) { + if (m_Species == null || (m_Species.size() == 0)) { return new double[]{0}; + } else { + double[] measures = m_Species.get(0).getPopulationMeasures(); + for (int i = 1; i < m_Species.size(); i++) { + Mathematics.vvAdd(measures, m_Species.get(i).getPopulationMeasures(), measures); + } + if (m_Species.size() > 1) { + Mathematics.svDiv((double) m_Species.size(), measures, measures); + } + return measures; } - else { - double[] measures = m_Species.get(0).getPopulationMeasures(); - for (int i=1; i1) { - Mathematics.svDiv((double)m_Species.size(), measures, measures); - } - return measures; - } - } + } + + public int getMaxSpeciesSize() { + return m_maxSpeciesSize; + } - public int getMaxSpeciesSize() { - return m_maxSpeciesSize; - } public void setMaxSpeciesSize(int mMaxSpeciesSize) { - m_maxSpeciesSize = mMaxSpeciesSize; - GenericObjectEditor.setShowProperty(this.getClass(), "reduceSizeComparator", (m_maxSpeciesSize >= m_minGroupSize)); - } + m_maxSpeciesSize = mMaxSpeciesSize; + GenericObjectEditor.setShowProperty(this.getClass(), "reduceSizeComparator", (m_maxSpeciesSize >= m_minGroupSize)); + } + public String maxSpeciesSizeTipText() { - return "If >= " + m_minGroupSize + ", larger species are reduced to the given size by reinitializing the worst individuals."; + return "If >= " + m_minGroupSize + ", larger species are reduced to the given size by reinitializing the worst individuals."; } public String reduceSizeComparatorTipText() { - return "Set the comparator used to define the 'worst' individuals when reducing species size."; + return "Set the comparator used to define the 'worst' individuals when reducing species size."; } - public AbstractEAIndividualComparator getReduceSizeComparator() { - return reduceSizeComparator; - } - public void setReduceSizeComparator( - AbstractEAIndividualComparator reduceSizeComparator) { - this.reduceSizeComparator = reduceSizeComparator; - } - + + public AbstractEAIndividualComparator getReduceSizeComparator() { + return reduceSizeComparator; + } + + public void setReduceSizeComparator( + AbstractEAIndividualComparator reduceSizeComparator) { + this.reduceSizeComparator = reduceSizeComparator; + } + public String[] customPropertyOrder() { - return new String[]{"mergingCA", "differentiationCA"}; + return new String[]{"mergingCA", "differentiationCA"}; } // public void setHistComparator(AbstractEAIndividualComparator histComparator) { // this.histComparator = histComparator; // } - public AbstractEAIndividualComparator getHistComparator() { - return histComparator; - } + public AbstractEAIndividualComparator getHistComparator() { + return histComparator; + } // public String histComparatorTipText() { // return "The comparator to keep track of old optima. Should correspond to the clustering metric."; // } - public void setClusterDiffDist(double clusterDiffDist) { - this.clusterDiffDist = clusterDiffDist; - if (clusterDiffDist<0) { - if ((m_Problem instanceof InterfaceProblemDouble) && (m_CAForSpeciesDifferentation instanceof ClusteringDensityBased)) { + public void setClusterDiffDist(double clusterDiffDist) { + this.clusterDiffDist = clusterDiffDist; + if (clusterDiffDist < 0) { + if ((m_Problem instanceof InterfaceProblemDouble) && (m_CAForSpeciesDifferentation instanceof ClusteringDensityBased)) { // int numExpectedOptima = (int)((((double)getPopulationSize())*0.9)/((ClusteringDensityBased)m_CAForSpeciesDifferentation).getMinimumGroupSize()); // this.clusterDiffDist = EsDpiNiching.calcEstimatedNicheRadius(((AbstractProblemDouble)m_Problem).makeRange(), numExpectedOptima, new EuclideanMetric()); - setUpperBoundClustDiff((InterfaceProblemDouble) m_Problem); - } else { - System.err.println("Warning, unable to calculate standard niche radius in CBN-EA"); - } - } - } + setUpperBoundClustDiff((InterfaceProblemDouble) m_Problem); + } else { + System.err.println("Warning, unable to calculate standard niche radius in CBN-EA"); + } + } + } - /** - * Calculate the clustering parameter in such a way that about one q-th part - * of the range of the given problem is within one hyper sphere of the clustering parameter. - * - * For certain types of parameter adaption schemes, this automatically sets the upper limit - * if the clustering parameter is controlled. - * - * @param prob - * @param q - */ - public void setUpperBoundClustDiff(InterfaceProblemDouble prob) { - if (m_CAForSpeciesDifferentation instanceof ClusteringDensityBased) { - double meanSubSwarmSize=0.5*(((ClusteringDensityBased)m_CAForSpeciesDifferentation).getMinimumGroupSize()+getMaxSpeciesSize()); - int numExpectedOptima = (int)((((double)getPopulationSize()))/meanSubSwarmSize); - double[][] range = ((InterfaceProblemDouble)m_Problem).makeRange(); - int dim = range.length; - double nRad = EsDpiNiching.calcEstimatedNicheRadius(range, numExpectedOptima, ((ClusteringDensityBased) m_CAForSpeciesDifferentation).getMetric()); - nRad *= Math.pow(0.5, 1/dim); + /** + * Calculate the clustering parameter in such a way that about one q-th part + * of the range of the given problem is within one hyper sphere of the + * clustering parameter. + * + * For certain types of parameter adaption schemes, this automatically sets + * the upper limit if the clustering parameter is controlled. + * + * @param prob + * @param q + */ + public void setUpperBoundClustDiff(InterfaceProblemDouble prob) { + if (m_CAForSpeciesDifferentation instanceof ClusteringDensityBased) { + double meanSubSwarmSize = 0.5 * (((ClusteringDensityBased) m_CAForSpeciesDifferentation).getMinimumGroupSize() + getMaxSpeciesSize()); + int numExpectedOptima = (int) ((((double) getPopulationSize())) / meanSubSwarmSize); + double[][] range = ((InterfaceProblemDouble) m_Problem).makeRange(); + int dim = range.length; + double nRad = EsDpiNiching.calcEstimatedNicheRadius(range, numExpectedOptima, ((ClusteringDensityBased) m_CAForSpeciesDifferentation).getMetric()); + nRad *= Math.pow(0.5, 1 / dim); // System.out.println("Alternative clust diff from niche radius... " + nRad); - this.clusterDiffDist = nRad; + this.clusterDiffDist = nRad; // System.out.println("Setting the clusterDiffDist to "+ clusterDiffDist); - ParamAdaption[] adaptors = getParameterControl(); - if (adaptors.length>0) { - for (ParamAdaption adpt : adaptors) { - if (adpt.getControlledParam().equals("clusterDiffDist")) { - if (adpt instanceof InterfaceHasUpperDoubleBound) { - ((InterfaceHasUpperDoubleBound)adpt).SetUpperBnd(clusterDiffDist); - } else { - System.err.println("Warning, unknown parameter adaption type for automatic setting of upper bound of the clustering sigma (CBN-EA)"); - } - } - } - } + ParamAdaption[] adaptors = getParameterControl(); + if (adaptors.length > 0) { + for (ParamAdaption adpt : adaptors) { + if (adpt.getControlledParam().equals("clusterDiffDist")) { + if (adpt instanceof InterfaceHasUpperDoubleBound) { + ((InterfaceHasUpperDoubleBound) adpt).SetUpperBnd(clusterDiffDist); + } else { + System.err.println("Warning, unknown parameter adaption type for automatic setting of upper bound of the clustering sigma (CBN-EA)"); + } + } + } + } // double estRad = EsDpiNiching.calcEstimatedNicheRadius(prob.makeRange(), expectedPeaks, metric); // setClusterDiffDist(estRad); - } else { - System.err.println("Warning, unable to calculate standard niche radius in CBN-EA"); - } - } + } else { + System.err.println("Warning, unable to calculate standard niche radius in CBN-EA"); + } + } - public double getClusterDiffDist() { - return clusterDiffDist; - } + public double getClusterDiffDist() { + return clusterDiffDist; + } } diff --git a/src/eva2/server/go/strategies/ClusteringHillClimbing.java b/src/eva2/server/go/strategies/ClusteringHillClimbing.java index a106f5ef..981e7f28 100644 --- a/src/eva2/server/go/strategies/ClusteringHillClimbing.java +++ b/src/eva2/server/go/strategies/ClusteringHillClimbing.java @@ -16,287 +16,303 @@ import eva2.server.go.problems.InterfaceOptimizationProblem; import eva2.tools.Pair; import java.io.Serializable; - /** - * The clustering hill climber is similar to a multi-start hill climber. In addition so optimizing - * a set of individuals in parallel using a (1+1) strategy, the population is clustered in regular - * intervals. If several individuals have gathered together in the sense that they are interpreted - * as a cluster, only a subset of representatives of the cluster is taken over to the next HC step - * while the rest is discarded. This means that the population size may be reduced. - * - * As soon as the improvement by HC lies below a threshold, the mutation step size is decreased. - * If the step size is decreased below a certain threshold, the current population is stored to - * an archive and reinitialized. Thus, the number of optima that may be found and returned by - * getAllSolutions is higher than the population size. - * + * The clustering hill climber is similar to a multi-start hill climber. In + * addition so optimizing a set of individuals in parallel using a (1+1) + * strategy, the population is clustered in regular intervals. If several + * individuals have gathered together in the sense that they are interpreted as + * a cluster, only a subset of representatives of the cluster is taken over to + * the next HC step while the rest is discarded. This means that the population + * size may be reduced. + * + * As soon as the improvement by HC lies below a threshold, the mutation step + * size is decreased. If the step size is decreased below a certain threshold, + * the current population is stored to an archive and reinitialized. Thus, the + * number of optima that may be found and returned by getAllSolutions is higher + * than the population size. + * * @author mkron * */ -public class ClusteringHillClimbing implements InterfacePopulationChangedEventListener, -InterfaceOptimizer, Serializable, InterfaceAdditionalPopulationInformer { - transient private InterfacePopulationChangedEventListener m_Listener; - public static final boolean TRACE = false; - - transient private String m_Identifier = ""; - private Population m_Population = new Population(); - private transient Population archive = new Population(); - private InterfaceOptimizationProblem m_Problem = new F1Problem(); - private int hcEvalCycle = 1000; - private int initialPopSize = 100; - private int loopCnt = 0; -// private int baseEvalCnt = 0; - private int notifyGuiEvery = 50; - private double sigmaClust = 0.01; - private double minImprovement = 0.000001; - private double stepSizeThreshold = 0.000001; - private double initialStepSize = 0.1; - // reduce the step size when there is hardy improvement. - private double reduceFactor = 0.2; - private MutateESFixedStepSize mutator = new MutateESFixedStepSize(0.1); - private PostProcessMethod localSearchMethod = PostProcessMethod.nelderMead; - private boolean doReinitialization = true; +public class ClusteringHillClimbing implements InterfacePopulationChangedEventListener, + InterfaceOptimizer, Serializable, InterfaceAdditionalPopulationInformer { + + transient private InterfacePopulationChangedEventListener m_Listener; + public static final boolean TRACE = false; + transient private String m_Identifier = ""; + private Population m_Population = new Population(); + private transient Population archive = new Population(); + private InterfaceOptimizationProblem m_Problem = new F1Problem(); + private int hcEvalCycle = 1000; + private int initialPopSize = 100; + private int loopCnt = 0; +// private int baseEvalCnt = 0; + private int notifyGuiEvery = 50; + private double sigmaClust = 0.01; + private double minImprovement = 0.000001; + private double stepSizeThreshold = 0.000001; + private double initialStepSize = 0.1; + // reduce the step size when there is hardy improvement. + private double reduceFactor = 0.2; + private MutateESFixedStepSize mutator = new MutateESFixedStepSize(0.1); + private PostProcessMethod localSearchMethod = PostProcessMethod.nelderMead; + private boolean doReinitialization = true; + + public ClusteringHillClimbing() { + hideHideable(); + } + + public ClusteringHillClimbing(int initialPopSize, PostProcessMethod lsMethod) { + this(); + setInitialPopSize(initialPopSize); + setLocalSearchMethod(lsMethod); + } + + public ClusteringHillClimbing(ClusteringHillClimbing other) { + hideHideable(); + m_Population = (Population) other.m_Population.clone(); + m_Problem = (InterfaceOptimizationProblem) other.m_Problem.clone(); + + hcEvalCycle = other.hcEvalCycle; + initialPopSize = other.initialPopSize; + notifyGuiEvery = other.notifyGuiEvery; + sigmaClust = other.sigmaClust; + minImprovement = other.minImprovement; + stepSizeThreshold = other.stepSizeThreshold; + initialStepSize = other.initialStepSize; + reduceFactor = other.reduceFactor; + mutator = (MutateESFixedStepSize) other.mutator.clone(); + loopCnt = 0; + } - public ClusteringHillClimbing() { - hideHideable(); - } - - public ClusteringHillClimbing(int initialPopSize, PostProcessMethod lsMethod) { - this(); - setInitialPopSize(initialPopSize); - setLocalSearchMethod(lsMethod); - } - - public ClusteringHillClimbing(ClusteringHillClimbing other) { - hideHideable(); - m_Population = (Population)other.m_Population.clone(); - m_Problem = (InterfaceOptimizationProblem)other.m_Problem.clone(); - - hcEvalCycle = other.hcEvalCycle; - initialPopSize = other.initialPopSize; - notifyGuiEvery = other.notifyGuiEvery; - sigmaClust = other.sigmaClust; - minImprovement = other.minImprovement; - stepSizeThreshold = other.stepSizeThreshold; - initialStepSize = other.initialStepSize; - reduceFactor = other.reduceFactor; - mutator = (MutateESFixedStepSize)other.mutator.clone(); - loopCnt = 0; - } - @Override public Object clone() { return (Object) new ClusteringHillClimbing(this); } - - /** - * Hide the population. - */ - public void hideHideable() { - GenericObjectEditor.setHideProperty(getClass(), "population", true); - setDoReinitialization(isDoReinitialization()); - setLocalSearchMethod(getLocalSearchMethod()); - } - + + /** + * Hide the population. + */ + public void hideHideable() { + GenericObjectEditor.setHideProperty(getClass(), "population", true); + setDoReinitialization(isDoReinitialization()); + setLocalSearchMethod(getLocalSearchMethod()); + } + @Override - public void setIdentifier(String name) { + public void setIdentifier(String name) { this.m_Identifier = name; } + @Override - public String getIdentifier() { - return this.m_Identifier; - } - - /** This method will set the problem that is to be optimized - * @param problem - */ + public String getIdentifier() { + return this.m_Identifier; + } + + /** + * This method will set the problem that is to be optimized + * + * @param problem + */ @Override - public void setProblem (InterfaceOptimizationProblem problem) { - this.m_Problem = problem; - } + public void setProblem(InterfaceOptimizationProblem problem) { + this.m_Problem = problem; + } + @Override - public InterfaceOptimizationProblem getProblem () { - return this.m_Problem; - } + public InterfaceOptimizationProblem getProblem() { + return this.m_Problem; + } @Override public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { this.m_Listener = ea; } + @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } + @Override public void init() { - loopCnt = 0; - mutator = new MutateESFixedStepSize(initialStepSize); - archive = new Population(); - hideHideable(); - m_Population.setTargetSize(initialPopSize); + loopCnt = 0; + mutator = new MutateESFixedStepSize(initialStepSize); + archive = new Population(); + hideHideable(); + m_Population.setTargetSize(initialPopSize); this.m_Problem.initPopulation(this.m_Population); m_Population.addPopulationChangedEventListener(null); // noone will be notified directly on pop changes this.m_Problem.evaluate(this.m_Population); this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** This method will init the optimizer with a given population - * @param pop The initial population - * @param reset If true the population is reset. + /** + * This method will init the optimizer with a given population + * + * @param pop The initial population + * @param reset If true the population is reset. */ @Override public void initByPopulation(Population pop, boolean reset) { - loopCnt = 0; - this.m_Population = (Population)pop.clone(); + loopCnt = 0; + this.m_Population = (Population) pop.clone(); m_Population.addPopulationChangedEventListener(null); if (reset) { - this.m_Population.init(); + this.m_Population.init(); this.m_Problem.evaluate(this.m_Population); this.firePropertyChangedEvent(Population.nextGenerationPerformed); } } - /** Something has changed + /** + * Something has changed */ - protected void firePropertyChangedEvent (String name) { + protected void firePropertyChangedEvent(String name) { if (this.m_Listener != null) { this.m_Listener.registerPopulationStateChanged(this, name); } } - - @Override - public void optimize() { - double improvement; - - loopCnt++; - m_Population.addPopulationChangedEventListener(this); - m_Population.setNotifyEvalInterval(notifyGuiEvery); - Pair popD; - int funCallsBefore=m_Population.getFunctionCalls(); - int evalsNow, lastOverhead = (m_Population.getFunctionCalls() % hcEvalCycle); - if (lastOverhead>0) { - evalsNow = (2*hcEvalCycle - (m_Population.getFunctionCalls() % hcEvalCycle)); - } - else { - evalsNow = hcEvalCycle; - } - do { - if (TRACE) { - System.out.println("evalCycle: " + hcEvalCycle + ", evals now: " + evalsNow); - } - popD = PostProcess.clusterLocalSearch(localSearchMethod, m_Population, (AbstractOptimizationProblem)m_Problem, sigmaClust, evalsNow, 0.5, mutator); - // (m_Population, (AbstractOptimizationProblem)m_Problem, sigmaClust, hcEvalCycle - (m_Population.getFunctionCalls() % hcEvalCycle), 0.5); - if (popD.head().getFunctionCalls()==funCallsBefore) { - System.err.println("Bad case, increasing allowed evaluations!"); - evalsNow=Math.max(evalsNow++, (int)(evalsNow*1.2)); - } - } while (popD.head().getFunctionCalls()==funCallsBefore); - improvement = popD.tail(); - m_Population = popD.head(); - if (TRACE) { - System.out.println("num inds after clusterLS: " + m_Population.size()); - } - popD.head().setGenerationTo(m_Population.getGeneration()+1); - - if (doReinitialization && (improvement < minImprovement)) { - if (TRACE) { - System.out.println("improvement below " + minImprovement); - } - if ((localSearchMethod != PostProcessMethod.hillClimber) || (mutator.getSigma() < stepSizeThreshold)) { // reinit! - // is performed for nm and cma, and if hc has too low sigma - if (TRACE) { - System.out.println("REINIT!!"); - } - - if (localSearchMethod == PostProcessMethod.hillClimber) { - mutator.setSigma(initialStepSize); - } - - // store results - archive.SetFunctionCalls(m_Population.getFunctionCalls()); - archive.addPopulation(m_Population); - - Population tmpPop = new Population(); - tmpPop.addPopulationChangedEventListener(null); - tmpPop.setTargetSize(initialPopSize); - this.m_Problem.initPopulation(tmpPop); - tmpPop.setSameParams(m_Population); - tmpPop.setTargetSize(initialPopSize); - this.m_Problem.evaluate(tmpPop); - - // reset population while keeping function calls etc. - m_Population.clear(); - m_Population.addPopulation(tmpPop); - m_Population.incrFunctionCallsBy(tmpPop.size()); - - } else { // decrease step size for hc - if (localSearchMethod != PostProcessMethod.hillClimber) { - System.err.println("Invalid case in ClusteringHillClimbing!"); - } - mutator.setSigma(mutator.getSigma()*reduceFactor); - if (TRACE) { - System.out.println("mutation stepsize reduced to " + mutator.getSigma()); - } - } - } + @Override + public void optimize() { + double improvement; + + loopCnt++; + m_Population.addPopulationChangedEventListener(this); + m_Population.setNotifyEvalInterval(notifyGuiEvery); + Pair popD; + int funCallsBefore = m_Population.getFunctionCalls(); + int evalsNow, lastOverhead = (m_Population.getFunctionCalls() % hcEvalCycle); + if (lastOverhead > 0) { + evalsNow = (2 * hcEvalCycle - (m_Population.getFunctionCalls() % hcEvalCycle)); + } else { + evalsNow = hcEvalCycle; + } + do { + if (TRACE) { + System.out.println("evalCycle: " + hcEvalCycle + ", evals now: " + evalsNow); + } + popD = PostProcess.clusterLocalSearch(localSearchMethod, m_Population, (AbstractOptimizationProblem) m_Problem, sigmaClust, evalsNow, 0.5, mutator); + // (m_Population, (AbstractOptimizationProblem)m_Problem, sigmaClust, hcEvalCycle - (m_Population.getFunctionCalls() % hcEvalCycle), 0.5); + if (popD.head().getFunctionCalls() == funCallsBefore) { + System.err.println("Bad case, increasing allowed evaluations!"); + evalsNow = Math.max(evalsNow++, (int) (evalsNow * 1.2)); + } + } while (popD.head().getFunctionCalls() == funCallsBefore); + improvement = popD.tail(); + m_Population = popD.head(); + if (TRACE) { + System.out.println("num inds after clusterLS: " + m_Population.size()); + } + + popD.head().setGenerationTo(m_Population.getGeneration() + 1); + + if (doReinitialization && (improvement < minImprovement)) { + if (TRACE) { + System.out.println("improvement below " + minImprovement); + } + if ((localSearchMethod != PostProcessMethod.hillClimber) || (mutator.getSigma() < stepSizeThreshold)) { // reinit! + // is performed for nm and cma, and if hc has too low sigma + if (TRACE) { + System.out.println("REINIT!!"); + } + + if (localSearchMethod == PostProcessMethod.hillClimber) { + mutator.setSigma(initialStepSize); + } + + // store results + archive.SetFunctionCalls(m_Population.getFunctionCalls()); + archive.addPopulation(m_Population); + + Population tmpPop = new Population(); + tmpPop.addPopulationChangedEventListener(null); + tmpPop.setTargetSize(initialPopSize); + this.m_Problem.initPopulation(tmpPop); + tmpPop.setSameParams(m_Population); + tmpPop.setTargetSize(initialPopSize); + this.m_Problem.evaluate(tmpPop); + + // reset population while keeping function calls etc. + m_Population.clear(); + m_Population.addPopulation(tmpPop); + m_Population.incrFunctionCallsBy(tmpPop.size()); + + } else { // decrease step size for hc + if (localSearchMethod != PostProcessMethod.hillClimber) { + System.err.println("Invalid case in ClusteringHillClimbing!"); + } + mutator.setSigma(mutator.getSigma() * reduceFactor); + if (TRACE) { + System.out.println("mutation stepsize reduced to " + mutator.getSigma()); + } + } + } // System.out.println("funcalls: " + evalCnt); this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } + } @Override - public void registerPopulationStateChanged(Object source, String name) { - // The events of the interim hill climbing population will be caught here - if (name.compareTo(Population.funCallIntervalReached) == 0) { + public void registerPopulationStateChanged(Object source, String name) { + // The events of the interim hill climbing population will be caught here + if (name.compareTo(Population.funCallIntervalReached) == 0) { // if ((((Population)source).size() % 50) > 0) { // System.out.println("bla"); // } - // set funcalls to real value - m_Population.SetFunctionCalls(((Population)source).getFunctionCalls()); + // set funcalls to real value + m_Population.SetFunctionCalls(((Population) source).getFunctionCalls()); // System.out.println("FunCallIntervalReached at " + (((Population)source).getFunctionCalls())); - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } - // do not react to NextGenerationPerformed - //else System.err.println("ERROR, event was " + name); - - } + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + } + // do not react to NextGenerationPerformed + //else System.err.println("ERROR, event was " + name); - /** Assuming that all optimizer will store thier data in a population - * we will allow acess to this population to query to current state - * of the optimizer. + } + + /** + * Assuming that all optimizer will store thier data in a population we will + * allow acess to this population to query to current state of the + * optimizer. + * * @return The population of current solutions to a given problem. */ @Override public Population getPopulation() { return this.m_Population; } + @Override - public void setPopulation(Population pop){ + public void setPopulation(Population pop) { this.m_Population = pop; } + public String populationTipText() { return "Change the number of starting individuals stored (Cluster-HC)."; } @Override public InterfaceSolutionSet getAllSolutions() { - Population tmp = new Population(); - tmp.addPopulation(archive); - tmp.addPopulation(m_Population); - tmp.SetFunctionCalls(m_Population.getFunctionCalls()); - tmp.setGenerationTo(m_Population.getGeneration()); + Population tmp = new Population(); + tmp.addPopulation(archive); + tmp.addPopulation(m_Population); + tmp.SetFunctionCalls(m_Population.getFunctionCalls()); + tmp.setGenerationTo(m_Population.getGeneration()); // tmp = PostProcessInterim.clusterBest(tmp, sigma, 0, PostProcessInterim.KEEP_LONERS, PostProcessInterim.BEST_ONLY); - return new SolutionSet(m_Population, tmp); + return new SolutionSet(m_Population, tmp); } - - /** This method will return a string describing all properties of the optimizer - * and the applied methods. + + /** + * This method will return a string describing all properties of the + * optimizer and the applied methods. + * * @return A descriptive string */ @Override @@ -309,185 +325,182 @@ InterfaceOptimizer, Serializable, InterfaceAdditionalPopulationInformer { sbuf.append(this.m_Population.getStringRepresentation()); return sbuf.toString(); } - - @Override - public void freeWilly() {} @Override - public String getName() { - return "ClustHC-"+initialPopSize+"-"+localSearchMethod; - } + public String getName() { + return "ClustHC-" + initialPopSize + "-" + localSearchMethod; + } - public static String globalInfo() { - return "Similar to multi-start HC, but clusters the population during optimization to remove redundant individuals for efficiency." + - "If the local search step does not achieve a minimum improvement, the population may be reinitialized."; - } - - /** - * @return the hcEvalCycle - */ - public int getEvalCycle() { - return hcEvalCycle; - } + public static String globalInfo() { + return "Similar to multi-start HC, but clusters the population during optimization to remove redundant individuals for efficiency." + + "If the local search step does not achieve a minimum improvement, the population may be reinitialized."; + } - /** - * @param hcEvalCycle the hcEvalCycle to set - */ - public void setEvalCycle(int hcEvalCycle) { - this.hcEvalCycle = hcEvalCycle; - } - - public String evalCycleTipText() { - return "The number of evaluations between two clustering/adaption steps."; - } + /** + * @return the hcEvalCycle + */ + public int getEvalCycle() { + return hcEvalCycle; + } - /** - * @return the initialPopSize - */ - public int getInitialPopSize() { - return initialPopSize; - } + /** + * @param hcEvalCycle the hcEvalCycle to set + */ + public void setEvalCycle(int hcEvalCycle) { + this.hcEvalCycle = hcEvalCycle; + } - /** - * @param initialPopSize the initialPopSize to set - */ - public void setInitialPopSize(int initialPopSize) { - this.initialPopSize = initialPopSize; - } + public String evalCycleTipText() { + return "The number of evaluations between two clustering/adaption steps."; + } - public String initialPopSizeTipText() { - return "Population size at the start and at reinitialization times."; - } - - /** - * @return the sigma - */ - public double getSigmaClust() { - return sigmaClust; - } + /** + * @return the initialPopSize + */ + public int getInitialPopSize() { + return initialPopSize; + } - /** - * @param sigma the sigma to set - */ - public void setSigmaClust(double sigma) { - this.sigmaClust = sigma; - } - - public String sigmaClustTipText() { - return "Defines the sigma distance parameter for density based clustering."; - } + /** + * @param initialPopSize the initialPopSize to set + */ + public void setInitialPopSize(int initialPopSize) { + this.initialPopSize = initialPopSize; + } - /** - * @return the notifyGuiEvery - */ - public int getNotifyGuiEvery() { - return notifyGuiEvery; - } + public String initialPopSizeTipText() { + return "Population size at the start and at reinitialization times."; + } - /** - * @param notifyGuiEvery the notifyGuiEvery to set - */ - public void setNotifyGuiEvery(int notifyGuiEvery) { - this.notifyGuiEvery = notifyGuiEvery; - } + /** + * @return the sigma + */ + public double getSigmaClust() { + return sigmaClust; + } - public String notifyGuiEveryTipText() { - return "How often to notify the GUI to plot the fitness etc."; - } - - /** - * @return the minImprovement - */ - public double getMinImprovement() { - return minImprovement; - } + /** + * @param sigma the sigma to set + */ + public void setSigmaClust(double sigma) { + this.sigmaClust = sigma; + } - /** - * @param minImprovement the minImprovement to set - */ - public void setMinImprovement(double minImprovement) { - this.minImprovement = minImprovement; - } + public String sigmaClustTipText() { + return "Defines the sigma distance parameter for density based clustering."; + } - public String minImprovementTipText() { - return "Improvement threshold below which the mutation step size is reduced or the population reinitialized."; - } - - /** - * @return the reinitForStepSize - */ - public double getStepSizeThreshold() { - return stepSizeThreshold; - } + /** + * @return the notifyGuiEvery + */ + public int getNotifyGuiEvery() { + return notifyGuiEvery; + } - /** - * @param reinitForStepSize the reinitForStepSize to set - */ - public void setStepSizeThreshold(double reinitForStepSize) { - this.stepSizeThreshold = reinitForStepSize; - } + /** + * @param notifyGuiEvery the notifyGuiEvery to set + */ + public void setNotifyGuiEvery(int notifyGuiEvery) { + this.notifyGuiEvery = notifyGuiEvery; + } - public String stepSizeThresholdTipText() { - return "Threshold for the mutation step size below which the population is seen as converged and reinitialized."; - } - - /** - * @return the initialStepSize - */ - public double getStepSizeInitial() { - return initialStepSize; - } + public String notifyGuiEveryTipText() { + return "How often to notify the GUI to plot the fitness etc."; + } - /** - * @param initialStepSize the initialStepSize to set - */ - public void setStepSizeInitial(double initialStepSize) { - this.initialStepSize = initialStepSize; - } - - public String stepSizeInitialTipText() { - return "Initial mutation step size for hill climbing, relative to the problem range."; - } + /** + * @return the minImprovement + */ + public double getMinImprovement() { + return minImprovement; + } - public PostProcessMethod getLocalSearchMethod() { - return localSearchMethod; - } + /** + * @param minImprovement the minImprovement to set + */ + public void setMinImprovement(double minImprovement) { + this.minImprovement = minImprovement; + } - public void setLocalSearchMethod(PostProcessMethod localSearchMethod) { - this.localSearchMethod = localSearchMethod; - GenericObjectEditor.setShowProperty(this.getClass(), "stepSizeInitial", localSearchMethod==PostProcessMethod.hillClimber); - GenericObjectEditor.setShowProperty(this.getClass(), "stepSizeThreshold", localSearchMethod==PostProcessMethod.hillClimber); - } - - public String localSearchMethodTipText() { - return "Set the method to be used for the hill climbing as local search"; - } + public String minImprovementTipText() { + return "Improvement threshold below which the mutation step size is reduced or the population reinitialized."; + } + + /** + * @return the reinitForStepSize + */ + public double getStepSizeThreshold() { + return stepSizeThreshold; + } + + /** + * @param reinitForStepSize the reinitForStepSize to set + */ + public void setStepSizeThreshold(double reinitForStepSize) { + this.stepSizeThreshold = reinitForStepSize; + } + + public String stepSizeThresholdTipText() { + return "Threshold for the mutation step size below which the population is seen as converged and reinitialized."; + } + + /** + * @return the initialStepSize + */ + public double getStepSizeInitial() { + return initialStepSize; + } + + /** + * @param initialStepSize the initialStepSize to set + */ + public void setStepSizeInitial(double initialStepSize) { + this.initialStepSize = initialStepSize; + } + + public String stepSizeInitialTipText() { + return "Initial mutation step size for hill climbing, relative to the problem range."; + } + + public PostProcessMethod getLocalSearchMethod() { + return localSearchMethod; + } + + public void setLocalSearchMethod(PostProcessMethod localSearchMethod) { + this.localSearchMethod = localSearchMethod; + GenericObjectEditor.setShowProperty(this.getClass(), "stepSizeInitial", localSearchMethod == PostProcessMethod.hillClimber); + GenericObjectEditor.setShowProperty(this.getClass(), "stepSizeThreshold", localSearchMethod == PostProcessMethod.hillClimber); + } + + public String localSearchMethodTipText() { + return "Set the method to be used for the hill climbing as local search"; + } @Override - public String[] getAdditionalDataHeader() { - return new String[]{"numIndies", "sigma", "numArchived", "archivedMeanDist"}; - } - + public String[] getAdditionalDataHeader() { + return new String[]{"numIndies", "sigma", "numArchived", "archivedMeanDist"}; + } + @Override - public String[] getAdditionalDataInfo() { - return new String[]{"The current population size", "Current step size in case of stochastic HC", "Number of archived solutions", "Mean distance of archived solutions"}; - } - + public String[] getAdditionalDataInfo() { + return new String[]{"The current population size", "Current step size in case of stochastic HC", "Number of archived solutions", "Mean distance of archived solutions"}; + } + @Override - public Object[] getAdditionalDataValue(PopulationInterface pop) { - return new Object[]{m_Population.size(), mutator.getSigma(), archive.size(), archive.getPopulationMeasures()[0]}; - } + public Object[] getAdditionalDataValue(PopulationInterface pop) { + return new Object[]{m_Population.size(), mutator.getSigma(), archive.size(), archive.getPopulationMeasures()[0]}; + } - public boolean isDoReinitialization() { - return doReinitialization; - } + public boolean isDoReinitialization() { + return doReinitialization; + } - public void setDoReinitialization(boolean doReinitialization) { - this.doReinitialization = doReinitialization; - GenericObjectEditor.setShowProperty(this.getClass(), "minImprovement", doReinitialization); - } + public void setDoReinitialization(boolean doReinitialization) { + this.doReinitialization = doReinitialization; + GenericObjectEditor.setShowProperty(this.getClass(), "minImprovement", doReinitialization); + } - public String doReinitializationTipText() { - return "Activate reinitialization if no improvement was achieved."; - } + public String doReinitializationTipText() { + return "Activate reinitialization if no improvement was achieved."; + } } diff --git a/src/eva2/server/go/strategies/DifferentialEvolution.java b/src/eva2/server/go/strategies/DifferentialEvolution.java index 805f92af..ba78e154 100644 --- a/src/eva2/server/go/strategies/DifferentialEvolution.java +++ b/src/eva2/server/go/strategies/DifferentialEvolution.java @@ -20,50 +20,49 @@ import eva2.tools.math.Mathematics; import eva2.tools.math.RNG; import java.util.Vector; -/** - * Differential evolution implementing DE1 and DE2 following the paper of Storm and - * Price and the Trigonometric DE published recently. - * Please note that DE will only work on real-valued genotypes and will ignore - * all mutation and crossover operators selected. - * Added aging mechanism to provide for dynamically changing problems. If an individual - * reaches the age limit, it is doomed and replaced by the next challenge vector, even if its worse. +/** + * Differential evolution implementing DE1 and DE2 following the paper of Storm + * and Price and the Trigonometric DE published recently. Please note that DE + * will only work on real-valued genotypes and will ignore all mutation and + * crossover operators selected. Added aging mechanism to provide for + * dynamically changing problems. If an individual reaches the age limit, it is + * doomed and replaced by the next challenge vector, even if its worse. * */ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serializable { - protected Population m_Population = new Population(); - protected transient Population children = null; - protected AbstractOptimizationProblem m_Problem = new F1Problem(); - private DETypeEnum m_DEType; - private double m_F = 0.8; - private double m_k = 0.6; // AKA CR - private double m_Lambda = 0.6; - private double m_Mt = 0.05; - private int maximumAge = -1; - private boolean reEvaluate = false; + protected Population m_Population = new Population(); + protected transient Population children = null; + protected AbstractOptimizationProblem m_Problem = new F1Problem(); + private DETypeEnum m_DEType; + private double m_F = 0.8; + private double m_k = 0.6; // AKA CR + private double m_Lambda = 0.6; + private double m_Mt = 0.05; + private int maximumAge = -1; + private boolean reEvaluate = false; // to log the parents of a newly created indy. - public boolean doLogParents = false; // deactivate for better performance - private transient Vector parents = null; - - private boolean randomizeFKLambda = false; - private boolean generational = true; - private String m_Identifier = ""; - transient private Vector m_Listener=new Vector(); - private boolean forceRange = true; - private boolean cyclePop = false; // if true, individuals are used as parents in a cyclic sequence - otherwise randomly - private boolean compareToParent = true; // if true, the challenge indy is compared to its parent, otherwise to a random individual + public boolean doLogParents = false; // deactivate for better performance + private transient Vector parents = null; + private boolean randomizeFKLambda = false; + private boolean generational = true; + private String m_Identifier = ""; + transient private Vector m_Listener = new Vector(); + private boolean forceRange = true; + private boolean cyclePop = false; // if true, individuals are used as parents in a cyclic sequence - otherwise randomly + private boolean compareToParent = true; // if true, the challenge indy is compared to its parent, otherwise to a random individual /** * A constructor. * */ public DifferentialEvolution() { - // sets DE2 as default + // sets DE2 as default m_DEType = DETypeEnum.DE2_CurrentToBest; } - + public DifferentialEvolution(int popSize, DETypeEnum type, double f, double k, double lambda, double mt) { - m_Population=new Population(popSize); + m_Population = new Population(popSize); m_DEType = type; m_F = f; m_k = k; @@ -73,24 +72,24 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial /** * The copy constructor. - * + * * @param a */ public DifferentialEvolution(DifferentialEvolution a) { - this.m_DEType = a.m_DEType; - this.m_Population = (Population)a.m_Population.clone(); - this.m_Problem = (AbstractOptimizationProblem)a.m_Problem.clone(); - this.m_Identifier = a.m_Identifier; - this.m_F = a.m_F; - this.m_k = a.m_k; - this.m_Lambda = a.m_Lambda; - this.m_Mt = a.m_Mt; - - this.maximumAge = a.maximumAge; - this.randomizeFKLambda = a.randomizeFKLambda; - this.forceRange = a.forceRange; - this.cyclePop = a.cyclePop; - this.compareToParent = a.compareToParent; + this.m_DEType = a.m_DEType; + this.m_Population = (Population) a.m_Population.clone(); + this.m_Problem = (AbstractOptimizationProblem) a.m_Problem.clone(); + this.m_Identifier = a.m_Identifier; + this.m_F = a.m_F; + this.m_k = a.m_k; + this.m_Lambda = a.m_Lambda; + this.m_Mt = a.m_Mt; + + this.maximumAge = a.maximumAge; + this.randomizeFKLambda = a.randomizeFKLambda; + this.forceRange = a.forceRange; + this.cyclePop = a.cyclePop; + this.compareToParent = a.compareToParent; } @Override @@ -107,18 +106,20 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial } public void hideHideable() { - setDEType(getDEType()); + setDEType(getDEType()); } - - /** This method will init the optimizer with a given population - * @param pop The initial population - * @param reset If true the population is reset. + + /** + * This method will init the optimizer with a given population + * + * @param pop The initial population + * @param reset If true the population is reset. */ @Override public void initByPopulation(Population pop, boolean reset) { - this.m_Population = (Population)pop.clone(); + this.m_Population = (Population) pop.clone(); if (reset) { - this.m_Population.init(); + this.m_Population.init(); this.evaluatePopulation(this.m_Population); this.firePropertyChangedEvent(Population.nextGenerationPerformed); } @@ -126,8 +127,9 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial // else children = new Population(m_Population.size()); } - /** This method will evaluate the current population using the - * given problem. + /** + * This method will evaluate the current population using the given problem. + * * @param population The population that is to be evaluated */ private void evaluatePopulation(Population population) { @@ -135,110 +137,108 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial population.incrGeneration(); } - /** - * This method returns a difference vector between two random individuals from the population. - * This method should make sure that delta is not zero. - * - * @param pop The population to choose from + /** + * This method returns a difference vector between two random individuals + * from the population. This method should make sure that delta is not zero. + * + * @param pop The population to choose from * @return The delta vector */ private double[] fetchDeltaRandom(Population pop) { - double[] x1, x2; - double[] result; - boolean isEmpty; - int iterations = 0; + double[] x1, x2; + double[] result; + boolean isEmpty; + int iterations = 0; AbstractEAIndividual x1Indy = getRandomIndy(pop); x1 = getGenotype(x1Indy); - + if (parents != null) { parents.add(x1Indy); } - + result = new double[x1.length]; isEmpty = true; AbstractEAIndividual x2Indy = null; while (isEmpty && (iterations < pop.size())) { - x2Indy = getRandomIndy(pop); - x2 = getGenotype(x2Indy); - + x2Indy = getRandomIndy(pop); + x2 = getGenotype(x2Indy); + for (int i = 0; i < x1.length; i++) { result[i] = x1[i] - x2[i]; - isEmpty = (isEmpty && (result[i]==0)); + isEmpty = (isEmpty && (result[i] == 0)); } iterations++; } if (!isEmpty && (parents != null)) { parents.add(x2Indy); - } - + } + while (isEmpty) { - // for n (popSize) iterations there were only zero vectors found - // so now the hard way: construct a random vector + // for n (popSize) iterations there were only zero vectors found + // so now the hard way: construct a random vector for (int i = 0; i < x1.length; i++) { - if (RNG.flipCoin(1/(double)x1.length)) { - result[i] = 0.01*RNG.gaussianDouble(0.1); - } - else { + if (RNG.flipCoin(1 / (double) x1.length)) { + result[i] = 0.01 * RNG.gaussianDouble(0.1); + } else { result[i] = 0; } - isEmpty = (isEmpty && (result[i]==0)); + isEmpty = (isEmpty && (result[i] == 0)); } // single parent! dont add another one } return result; } - - /** - * This method returns a difference vector between two random individuals from the population. - * This method should make sure that delta is not zero. - * - * @param pop The population to choose from + + /** + * This method returns a difference vector between two random individuals + * from the population. This method should make sure that delta is not zero. + * + * @param pop The population to choose from * @return The delta vector */ - private double[] fetchDeltaCurrentRandom(Population pop,InterfaceDataTypeDouble indy) { - double[] x1, x2; - double[] result; - boolean isEmpty; - int iterations = 0; + private double[] fetchDeltaCurrentRandom(Population pop, InterfaceDataTypeDouble indy) { + double[] x1, x2; + double[] result; + boolean isEmpty; + int iterations = 0; x1 = indy.getDoubleData(); - - + + if (parents != null) { - parents.add((AbstractEAIndividual)indy); + parents.add((AbstractEAIndividual) indy); } - + result = new double[x1.length]; isEmpty = true; AbstractEAIndividual x2Indy = null; while (isEmpty && (iterations < pop.size())) { - x2Indy = getRandomIndy(pop); - x2 = getGenotype(x2Indy); - + x2Indy = getRandomIndy(pop); + x2 = getGenotype(x2Indy); + for (int i = 0; i < x1.length; i++) { result[i] = x1[i] - x2[i]; - isEmpty = (isEmpty && (result[i]==0)); + isEmpty = (isEmpty && (result[i] == 0)); } iterations++; } if (!isEmpty && (parents != null)) { parents.add(x2Indy); - } - + } + while (isEmpty) { - // for n (popSize) iterations there were only zero vectors found - // so now the hard way: construct a random vector + // for n (popSize) iterations there were only zero vectors found + // so now the hard way: construct a random vector for (int i = 0; i < x1.length; i++) { - if (RNG.flipCoin(1/(double)x1.length)) { - result[i] = 0.01*RNG.gaussianDouble(0.1); - } - else { + if (RNG.flipCoin(1 / (double) x1.length)) { + result[i] = 0.01 * RNG.gaussianDouble(0.1); + } else { result[i] = 0; } - isEmpty = (isEmpty && (result[i]==0)); + isEmpty = (isEmpty && (result[i] == 0)); } // single parent! dont add another one } @@ -246,45 +246,47 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial return result; } - /** + /** * This method will return the delta vector to the best individual - * - * @param pop The population to choose the best from - * @param indy The current individual + * + * @param pop The population to choose the best from + * @param indy The current individual * @return the delta vector */ private double[] fetchDeltaBest(Population pop, InterfaceDataTypeDouble indy) { - double[] x1, result; - AbstractEAIndividual xbIndy; - + double[] x1, result; + AbstractEAIndividual xbIndy; + x1 = indy.getDoubleData(); - result = new double[x1.length]; + result = new double[x1.length]; if (m_Problem instanceof AbstractMultiObjectiveOptimizationProblem) { - // implements MODE for the multi-objective case: a dominating individual is selected for difference building - Population domSet = pop.getDominatingSet((AbstractEAIndividual)indy); - if (domSet.size() > 0) { - xbIndy = getRandomIndy(domSet); - } else { - return result; // just return a zero vector. this will happen automatically if domSet contains only the individual itself - } + // implements MODE for the multi-objective case: a dominating individual is selected for difference building + Population domSet = pop.getDominatingSet((AbstractEAIndividual) indy); + if (domSet.size() > 0) { + xbIndy = getRandomIndy(domSet); + } else { + return result; // just return a zero vector. this will happen automatically if domSet contains only the individual itself + } } else { - xbIndy = getBestIndy(pop); + xbIndy = getBestIndy(pop); } double[] xb = getGenotype(xbIndy); if (parents != null) { parents.add(xbIndy); } // given indy argument is already listed - + for (int i = 0; i < x1.length; i++) { result[i] = xb[i] - x1[i]; } - + return result; } - /** This method returns two parents to the original individual - * @param pop The population to choose from + /** + * This method returns two parents to the original individual + * + * @param pop The population to choose from * @return the delta vector */ // private double[][] chooseRandomParents(Population pop) { @@ -301,29 +303,29 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial // result[1] = indy2.getDGenotype(); // return result; // } - - /** This method will generate one new individual from the given population - * @param pop The current population + /** + * This method will generate one new individual from the given population + * + * @param pop The current population * @return AbstractEAIndividual */ public AbstractEAIndividual generateNewIndividual(Population pop, int parentIndex) { // int firstParentIndex; - AbstractEAIndividual indy; - InterfaceDataTypeDouble esIndy; - + AbstractEAIndividual indy; + InterfaceDataTypeDouble esIndy; + if (doLogParents) { parents = new Vector(); - } - else { + } else { parents = null; } try { - // select one random indy as starting individual. its a parent in any case. - if (parentIndex<0) { - parentIndex = RNG.randomInt(0, pop.size()-1); + // select one random indy as starting individual. its a parent in any case. + if (parentIndex < 0) { + parentIndex = RNG.randomInt(0, pop.size() - 1); } - indy = (AbstractEAIndividual)(pop.getEAIndividual(parentIndex)).getClone(); - esIndy = (InterfaceDataTypeDouble)indy; + indy = (AbstractEAIndividual) (pop.getEAIndividual(parentIndex)).getClone(); + esIndy = (InterfaceDataTypeDouble) indy; } catch (java.lang.ClassCastException e) { throw new RuntimeException("Differential Evolution currently requires InterfaceESIndividual as basic data type!"); // return (AbstractEAIndividual)((AbstractEAIndividual)pop.get(RNG.randomInt(0, pop.size()-1))).getClone(); @@ -340,11 +342,11 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial parents.add(pop.getEAIndividual(parentIndex)); } // Add wherever oX is used directly for (int i = 0; i < oX.length; i++) { - vX[i] = oX[i] + this.getCurrentF()*delta[i]; + vX[i] = oX[i] + this.getCurrentF() * delta[i]; } break; } - case DE_CurrentToRand : { + case DE_CurrentToRand: { // this is DE/current-to-rand/1 double[] rndDelta = this.fetchDeltaRandom(pop); double[] bestDelta = this.fetchDeltaCurrentRandom(pop, esIndy); @@ -356,7 +358,7 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial } break; } - case DE2_CurrentToBest : { + case DE2_CurrentToBest: { // this is DE2 or DE/current-to-best/1 double[] rndDelta = this.fetchDeltaRandom(pop); double[] bestDelta = this.fetchDeltaBest(pop, esIndy); @@ -369,47 +371,47 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial break; } case DE_Best_2: { - // DE/best/2 - AbstractEAIndividual bestIndy = getBestIndy(pop); - oX = getGenotype(bestIndy); + // DE/best/2 + AbstractEAIndividual bestIndy = getBestIndy(pop); + oX = getGenotype(bestIndy); if (parents != null) { parents.add(bestIndy); } // Add best instead of preselected double[] delta1 = this.fetchDeltaRandom(pop); - double[] delta2 = this.fetchDeltaRandom(pop); + double[] delta2 = this.fetchDeltaRandom(pop); for (int i = 0; i < oX.length; i++) { vX[i] = oX[i] + this.getCurrentF() * (delta1[i] + delta2[i]); - } - break; + } + break; } - case TrigonometricDE : { + case TrigonometricDE: { // this is trigonometric mutation - if (parents != null) { + if (parents != null) { parents.add(pop.getEAIndividual(parentIndex)); } // Add wherever oX is used directly if (RNG.flipCoin(this.m_Mt)) { - double[] xk, xl; - double p, pj, pk, pl; + double[] xk, xl; + double p, pj, pk, pl; InterfaceDataTypeDouble indy1 = null, indy2 = null; try { // and i got indy! - indy1 = (InterfaceDataTypeDouble)pop.get(RNG.randomInt(0, pop.size()-1)); - indy2 = (InterfaceDataTypeDouble)pop.get(RNG.randomInt(0, pop.size()-1)); + indy1 = (InterfaceDataTypeDouble) pop.get(RNG.randomInt(0, pop.size() - 1)); + indy2 = (InterfaceDataTypeDouble) pop.get(RNG.randomInt(0, pop.size() - 1)); if (parents != null) { - parents.add((AbstractEAIndividual)indy1); - parents.add((AbstractEAIndividual)indy2); + parents.add((AbstractEAIndividual) indy1); + parents.add((AbstractEAIndividual) indy2); } } catch (java.lang.ClassCastException e) { - EVAERROR.errorMsgOnce("Differential Evolution currently requires InterfaceESIndividual as basic data type!"); + EVAERROR.errorMsgOnce("Differential Evolution currently requires InterfaceESIndividual as basic data type!"); } xk = indy1.getDoubleData(); xl = indy2.getDoubleData(); - p = Math.abs(((AbstractEAIndividual)esIndy).getFitness(0)) + Math.abs(((AbstractEAIndividual)indy1).getFitness(0)) + Math.abs(((AbstractEAIndividual)indy2).getFitness(0)); - pj = Math.abs(((AbstractEAIndividual)esIndy).getFitness(0))/p; - pk = Math.abs(((AbstractEAIndividual)indy1).getFitness(0))/p; - pl = Math.abs(((AbstractEAIndividual)indy2).getFitness(0))/p; + p = Math.abs(((AbstractEAIndividual) esIndy).getFitness(0)) + Math.abs(((AbstractEAIndividual) indy1).getFitness(0)) + Math.abs(((AbstractEAIndividual) indy2).getFitness(0)); + pj = Math.abs(((AbstractEAIndividual) esIndy).getFitness(0)) / p; + pk = Math.abs(((AbstractEAIndividual) indy1).getFitness(0)) / p; + pl = Math.abs(((AbstractEAIndividual) indy2).getFitness(0)) / p; for (int i = 0; i < oX.length; i++) { - vX[i] = (oX[i] + xk[i] + xl[i])/3.0 + ((pk-pj)*(oX[i]-xk[i])) + ((pl-pk)*(xk[i]-xl[i])) + ((pj-pl)*(xl[i]-oX[i])); + vX[i] = (oX[i] + xk[i] + xl[i]) / 3.0 + ((pk - pj) * (oX[i] - xk[i])) + ((pl - pk) * (xk[i] - xl[i])) + ((pj - pl) * (xl[i] - oX[i])); } } else { // this is DE1 @@ -418,15 +420,15 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial parents.add(pop.getEAIndividual(parentIndex)); } // Add wherever oX is used directly for (int i = 0; i < oX.length; i++) { - vX[i] = oX[i] + this.getCurrentF()*delta[i]; + vX[i] = oX[i] + this.getCurrentF() * delta[i]; } } break; } } - int k=RNG.randomInt(oX.length); // at least one position is changed - for (int i =0; i < oX.length; i++) { - if ((i==k) || RNG.flipCoin(this.getCurrentK())) { + int k = RNG.randomInt(oX.length); // at least one position is changed + for (int i = 0; i < oX.length; i++) { + if ((i == k) || RNG.flipCoin(this.getCurrentK())) { // it is altered nX[i] = vX[i]; } else { @@ -451,211 +453,206 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial } private double getCurrentK() { - if (randomizeFKLambda) { - return RNG.randomDouble(m_k*0.8, m_k * 1.2); - } - else { + if (randomizeFKLambda) { + return RNG.randomDouble(m_k * 0.8, m_k * 1.2); + } else { return m_k; } - } - - private double getCurrentLambda() { - if (randomizeFKLambda) { - return RNG.randomDouble(m_Lambda*0.8, m_Lambda * 1.2); - } - else { - return m_Lambda; - } - } - - private double getCurrentF() { - if (randomizeFKLambda) { - return RNG.randomDouble(m_F*0.8, m_F * 1.2); - } - else { - return m_F; - } - } - - private AbstractEAIndividual getBestIndy(Population pop) { - return (AbstractEAIndividual)pop.getBestIndividual(); - } - - private AbstractEAIndividual getRandomIndy(Population pop) { - if (pop.size()<1) { - System.err.println("Error: invalid pop size in DE!"); - System.err.println("DE: \n"+ BeanInspector.toString(this) + "\nPop: \n" + BeanInspector.toString(pop)); - } - - int randIndex = RNG.randomInt(0, pop.size()-1); - return pop.getEAIndividual(randIndex); } - + + private double getCurrentLambda() { + if (randomizeFKLambda) { + return RNG.randomDouble(m_Lambda * 0.8, m_Lambda * 1.2); + } else { + return m_Lambda; + } + } + + private double getCurrentF() { + if (randomizeFKLambda) { + return RNG.randomDouble(m_F * 0.8, m_F * 1.2); + } else { + return m_F; + } + } + + private AbstractEAIndividual getBestIndy(Population pop) { + return (AbstractEAIndividual) pop.getBestIndividual(); + } + + private AbstractEAIndividual getRandomIndy(Population pop) { + if (pop.size() < 1) { + System.err.println("Error: invalid pop size in DE!"); + System.err.println("DE: \n" + BeanInspector.toString(this) + "\nPop: \n" + BeanInspector.toString(pop)); + } + + int randIndex = RNG.randomInt(0, pop.size() - 1); + return pop.getEAIndividual(randIndex); + } + private double[] getGenotype(AbstractEAIndividual indy) { - try { - return ((InterfaceDataTypeDouble)indy).getDoubleData(); - } catch (java.lang.ClassCastException e) { - EVAERROR.errorMsgOnce("Differential Evolution currently requires InterfaceESIndividual as basic data type!"); - return null; - } + try { + return ((InterfaceDataTypeDouble) indy).getDoubleData(); + } catch (java.lang.ClassCastException e) { + EVAERROR.errorMsgOnce("Differential Evolution currently requires InterfaceESIndividual as basic data type!"); + return null; + } } @Override public void optimize() { - if (generational) { + if (generational) { optimizeGenerational(); - } - else { + } else { optimizeSteadyState(); } } - + /** - * This generational DE variant calls the method AbstractOptimizationProblem.evaluate(Population). - * Its performance may be slightly worse for schemes that rely on current best individuals, - * because improvements are not immediately incorporated as in the steady state DE. + * This generational DE variant calls the method + * AbstractOptimizationProblem.evaluate(Population). Its performance may be + * slightly worse for schemes that rely on current best individuals, because + * improvements are not immediately incorporated as in the steady state DE. * However it may be easier to parallelize. - * + * */ - public void optimizeGenerational() { + public void optimizeGenerational() { // AbstractEAIndividual indy = null, orig; - int parentIndex; + int parentIndex; // required for dynamic problems especially // m_Problem.evaluatePopulationStart(m_Population); - if (children==null) { - children = new Population(m_Population.size()); - } - else { - children.clear(); - } - for (int i = 0; i < this.m_Population.size(); i++) { - if (cyclePop) { - parentIndex=i; - } - else { - parentIndex=RNG.randomInt(0, this.m_Population.size()-1); - } - AbstractEAIndividual indy = generateNewIndividual(m_Population, parentIndex); - children.add(indy); + if (children == null) { + children = new Population(m_Population.size()); + } else { + children.clear(); } - + for (int i = 0; i < this.m_Population.size(); i++) { + if (cyclePop) { + parentIndex = i; + } else { + parentIndex = RNG.randomInt(0, this.m_Population.size() - 1); + } + AbstractEAIndividual indy = generateNewIndividual(m_Population, parentIndex); + children.add(indy); + } + children.setGenerationTo(m_Population.getGeneration()); m_Problem.evaluate(children); - + /** - * MdP: added a reevalutation mechanism for dynamically changing problems + * MdP: added a reevalutation mechanism for dynamically changing + * problems */ - if(isReEvaluate()){ - for(int i=0;i= maximumAge) { - this.m_Problem.evaluate(((AbstractEAIndividual)m_Population.get(i))); - ((AbstractEAIndividual)m_Population.get(i)).SetAge(0); - m_Population.incrFunctionCalls(); - } - } + if (isReEvaluate()) { + for (int i = 0; i < this.m_Population.size(); i++) { + + if (((AbstractEAIndividual) m_Population.get(i)).getAge() >= maximumAge) { + this.m_Problem.evaluate(((AbstractEAIndividual) m_Population.get(i))); + ((AbstractEAIndividual) m_Population.get(i)).SetAge(0); + m_Population.incrFunctionCalls(); + } + } } - + int nextDoomed = getNextDoomed(m_Population, 0); for (int i = 0; i < this.m_Population.size(); i++) { - AbstractEAIndividual indy = children.getEAIndividual(i); - if (cyclePop) { - parentIndex=i; + AbstractEAIndividual indy = children.getEAIndividual(i); + if (cyclePop) { + parentIndex = i; + } else { + parentIndex = RNG.randomInt(0, this.m_Population.size() - 1); } - else { - parentIndex=RNG.randomInt(0, this.m_Population.size()-1); - } - if (nextDoomed >= 0) { // this one is lucky, may replace an 'old' one - m_Population.replaceIndividualAt(nextDoomed, indy); - nextDoomed = getNextDoomed(m_Population, nextDoomed+1); - } else { - if (m_Problem instanceof AbstractMultiObjectiveOptimizationProblem&indy.getFitness().length>1) { - ReplacementCrowding repl = new ReplacementCrowding(); - repl.insertIndividual(indy, m_Population, null); - } else { + if (nextDoomed >= 0) { // this one is lucky, may replace an 'old' one + m_Population.replaceIndividualAt(nextDoomed, indy); + nextDoomed = getNextDoomed(m_Population, nextDoomed + 1); + } else { + if (m_Problem instanceof AbstractMultiObjectiveOptimizationProblem & indy.getFitness().length > 1) { + ReplacementCrowding repl = new ReplacementCrowding(); + repl.insertIndividual(indy, m_Population, null); + } else { // index = RNG.randomInt(0, this.m_Population.size()-1); - if (!compareToParent) { - parentIndex = RNG.randomInt(0, this.m_Population.size()-1); - } - AbstractEAIndividual orig = (AbstractEAIndividual)this.m_Population.get(parentIndex); - if (indy.isDominatingDebConstraints(orig)) { - this.m_Population.replaceIndividualAt(parentIndex, indy); - } - } - } + if (!compareToParent) { + parentIndex = RNG.randomInt(0, this.m_Population.size() - 1); + } + AbstractEAIndividual orig = (AbstractEAIndividual) this.m_Population.get(parentIndex); + if (indy.isDominatingDebConstraints(orig)) { + this.m_Population.replaceIndividualAt(parentIndex, indy); + } + } + } } this.m_Population.incrFunctionCallsBy(children.size()); this.m_Population.incrGeneration(); this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } - + } + public void optimizeSteadyState() { - AbstractEAIndividual indy = null, orig; + AbstractEAIndividual indy = null, orig; int index; int nextDoomed = getNextDoomed(m_Population, 0); - + // required for dynamic problems especially m_Problem.evaluatePopulationStart(m_Population); - - + + /** - * MdP: added a reevalutation mechanism for dynamically changing problems + * MdP: added a reevalutation mechanism for dynamically changing + * problems */ - if(isReEvaluate()){ - nextDoomed=-1; - for(int i=0;i= maximumAge) { - this.m_Problem.evaluate(((AbstractEAIndividual)m_Population.get(i))); - ((AbstractEAIndividual)m_Population.get(i)).SetAge(0); - m_Population.incrFunctionCalls(); - } - } + if (isReEvaluate()) { + nextDoomed = -1; + for (int i = 0; i < this.m_Population.size(); i++) { + + if (((AbstractEAIndividual) m_Population.get(i)).getAge() >= maximumAge) { + this.m_Problem.evaluate(((AbstractEAIndividual) m_Population.get(i))); + ((AbstractEAIndividual) m_Population.get(i)).SetAge(0); + m_Population.incrFunctionCalls(); + } + } } - - + + for (int i = 0; i < this.m_Population.size(); i++) { - if (cyclePop) { - index=i; + if (cyclePop) { + index = i; + } else { + index = RNG.randomInt(0, this.m_Population.size() - 1); } - else { - index=RNG.randomInt(0, this.m_Population.size()-1); - } - indy = generateNewIndividual(m_Population, index); + indy = generateNewIndividual(m_Population, index); // if (cyclePop) indy = this.generateNewIndividual(this.m_Population, i); // else indy = this.generateNewIndividual(this.m_Population, -1); - this.m_Problem.evaluate(indy); - this.m_Population.incrFunctionCalls(); - if (nextDoomed >= 0) { // this one is lucky, may replace an 'old' one - m_Population.replaceIndividualAt(nextDoomed, indy); - nextDoomed = getNextDoomed(m_Population, nextDoomed+1); - } else { - if (m_Problem instanceof AbstractMultiObjectiveOptimizationProblem) { - - if(indy.isDominatingDebConstraints(m_Population.getEAIndividual(index))){ //child dominates the parent replace the parent - m_Population.replaceIndividualAt(index, indy); - }else if(!(m_Population.getEAIndividual(index).isDominatingDebConstraints(indy))){ //do nothing if parent dominates the child use crowding if neither one dominates the other one - ReplacementNondominatedSortingDistanceCrowding repl =new ReplacementNondominatedSortingDistanceCrowding(); - repl.insertIndividual(indy, m_Population, null); - } - // ReplacementCrowding repl = new ReplacementCrowding(); - // repl.insertIndividual(indy, m_Population, null); - - - } else { -// index = RNG.randomInt(0, this.m_Population.size()-1); - if (!compareToParent) { - index = RNG.randomInt(0, this.m_Population.size()-1); + this.m_Problem.evaluate(indy); + this.m_Population.incrFunctionCalls(); + if (nextDoomed >= 0) { // this one is lucky, may replace an 'old' one + m_Population.replaceIndividualAt(nextDoomed, indy); + nextDoomed = getNextDoomed(m_Population, nextDoomed + 1); + } else { + if (m_Problem instanceof AbstractMultiObjectiveOptimizationProblem) { + + if (indy.isDominatingDebConstraints(m_Population.getEAIndividual(index))) { //child dominates the parent replace the parent + m_Population.replaceIndividualAt(index, indy); + } else if (!(m_Population.getEAIndividual(index).isDominatingDebConstraints(indy))) { //do nothing if parent dominates the child use crowding if neither one dominates the other one + ReplacementNondominatedSortingDistanceCrowding repl = new ReplacementNondominatedSortingDistanceCrowding(); + repl.insertIndividual(indy, m_Population, null); } - orig = (AbstractEAIndividual)this.m_Population.get(index); - if (indy.isDominatingDebConstraints(orig)) { + // ReplacementCrowding repl = new ReplacementCrowding(); + // repl.insertIndividual(indy, m_Population, null); + + + } else { +// index = RNG.randomInt(0, this.m_Population.size()-1); + if (!compareToParent) { + index = RNG.randomInt(0, this.m_Population.size() - 1); + } + orig = (AbstractEAIndividual) this.m_Population.get(index); + if (indy.isDominatingDebConstraints(orig)) { this.m_Population.replaceIndividualAt(index, indy); } - } - } + } + } } - + //////// this was a non-steady-state-version // if (children==null) children = new Population(m_Population.size()); // for (int i = 0; i < this.m_Population.size(); i++) { @@ -699,70 +696,82 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial } /** - * Search for the first individual which is older than the age limit and return its index. - * If there is no age limit or all individuals are younger, -1 is returned. The start index - * of the search may be provided to make iterative search efficient. + * Search for the first individual which is older than the age limit and + * return its index. If there is no age limit or all individuals are + * younger, -1 is returned. The start index of the search may be provided to + * make iterative search efficient. * * @param pop Population to search * @param startIndex index to start the search from * @return index of an overaged individual or -1 */ protected int getNextDoomed(Population pop, int startIndex) { - if (maximumAge > 0) { - for (int i=startIndex; i= maximumAge) { - return i; - } - } - } - return -1; + if (maximumAge > 0) { + for (int i = startIndex; i < pop.size(); i++) { + if (((AbstractEAIndividual) pop.get(i)).getAge() >= maximumAge) { + return i; + } + } + } + return -1; } - - /** This method allows you to add the LectureGUI as listener to the Optimizer + + /** + * This method allows you to add the LectureGUI as listener to the Optimizer + * * @param ea */ @Override public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { - if(this.m_Listener ==null){ - this.m_Listener=new Vector(); - } + if (this.m_Listener == null) { + this.m_Listener = new Vector(); + } this.m_Listener.add(ea); } + @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener!=null&&m_Listener.removeElement(ea)) { - - return true; - } else { - return false; - } - } - /** Something has changed - * @param name - */ - protected void firePropertyChangedEvent (String name) { - if (this.m_Listener != null){ - for(int i=0;i 1) { k = 1; - } + } this.m_k = k; } + public double getK() { return this.m_k; } + public String kTipText() { return "Probability of alteration through DE (a.k.a. CR, similar to discrete uniform crossover)."; } - /** Enhance greediness through amplification of the differential vector to the best individual for DE2 + /** + * Enhance greediness through amplification of the differential vector to + * the best individual for DE2 + * * @param l */ - public void setLambda (double l) { + public void setLambda(double l) { this.m_Lambda = l; } + public double getLambda() { return this.m_Lambda; } + public String lambdaTipText() { return "Enhance greediness through amplification of the differential vector to the best individual for DE2."; } - /** In case of trig. mutation DE, the TMO is applied wit probability Mt + /** + * In case of trig. mutation DE, the TMO is applied wit probability Mt + * * @param l */ - public void setMt (double l) { + public void setMt(double l) { this.m_Mt = l; if (this.m_Mt < 0) { this.m_Mt = 0; @@ -890,78 +923,87 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial this.m_Mt = 1; } } + public double getMt() { return this.m_Mt; } + public String mtTipText() { return "In case of trigonometric mutation DE, the TMO is applied with probability Mt."; } - /** This method allows you to choose the type of Differential Evolution. - * @param s The type. + /** + * This method allows you to choose the type of Differential Evolution. + * + * @param s The type. */ public void setDEType(DETypeEnum s) { this.m_DEType = s; // show mt for trig. DE only - GenericObjectEditor.setShowProperty(this.getClass(), "lambda", s==DETypeEnum.DE2_CurrentToBest); - GenericObjectEditor.setShowProperty(this.getClass(), "mt", s==DETypeEnum.TrigonometricDE); + GenericObjectEditor.setShowProperty(this.getClass(), "lambda", s == DETypeEnum.DE2_CurrentToBest); + GenericObjectEditor.setShowProperty(this.getClass(), "mt", s == DETypeEnum.TrigonometricDE); } + public DETypeEnum getDEType() { return this.m_DEType; } + public String dETypeTipText() { return "Choose the type of Differential Evolution."; } - /** - * @return the maximumAge - **/ - public int getMaximumAge() { - return maximumAge; - } + /** + * @return the maximumAge + * + */ + public int getMaximumAge() { + return maximumAge; + } - /** - * @param maximumAge the maximumAge to set - **/ - public void setMaximumAge(int maximumAge) { - this.maximumAge = maximumAge; - } - - public String maximumAgeTipText() { - return "The maximum age of individuals, older ones are discarded. Set to -1 (or 0) to deactivate"; - } + /** + * @param maximumAge the maximumAge to set + * + */ + public void setMaximumAge(int maximumAge) { + this.maximumAge = maximumAge; + } - /** - * Check whether the problem range will be enforced. - * @return the forceRange - */ - public boolean isCheckRange() { - return forceRange; - } + public String maximumAgeTipText() { + return "The maximum age of individuals, older ones are discarded. Set to -1 (or 0) to deactivate"; + } - /** - * @param forceRange the forceRange to set - */ - public void setCheckRange(boolean forceRange) { - this.forceRange = forceRange; - } - - public String checkRangeTipText() { - return "Set whether to enforce the problem range."; - } + /** + * Check whether the problem range will be enforced. + * + * @return the forceRange + */ + public boolean isCheckRange() { + return forceRange; + } - public boolean isRandomizeFKLambda() { - return randomizeFKLambda; - } + /** + * @param forceRange the forceRange to set + */ + public void setCheckRange(boolean forceRange) { + this.forceRange = forceRange; + } - public void setRandomizeFKLambda(boolean randomizeFK) { - this.randomizeFKLambda = randomizeFK; - } + public String checkRangeTipText() { + return "Set whether to enforce the problem range."; + } + + public boolean isRandomizeFKLambda() { + return randomizeFKLambda; + } + + public void setRandomizeFKLambda(boolean randomizeFK) { + this.randomizeFKLambda = randomizeFK; + } + + public String randomizeFKLambdaTipText() { + return "If true, values for k, f, lambda are randomly sampled around +/- 20% of the given values."; + } - public String randomizeFKLambdaTipText() { - return "If true, values for k, f, lambda are randomly sampled around +/- 20% of the given values."; - } - // public boolean isCyclePop() { // return cyclePop; // } @@ -973,59 +1015,59 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial // public String cyclePopTipText() { // return "Use all individuals as parents in cyclic sequence instead of randomly."; // } + public boolean isCompareToParent() { + return compareToParent; + } - public boolean isCompareToParent() { - return compareToParent; - } + public void setCompareToParent(boolean compareToParent) { + this.compareToParent = compareToParent; + } - public void setCompareToParent(boolean compareToParent) { - this.compareToParent = compareToParent; - } - - public String compareToParentTipText() { - return "Compare a challenge individual to its original parent instead of a random one."; - } + public String compareToParentTipText() { + return "Compare a challenge individual to its original parent instead of a random one."; + } - public boolean isGenerational() { - return generational; - } + public boolean isGenerational() { + return generational; + } - public void setGenerational(boolean generational) { - this.generational = generational; - } - - public String generationalTipText() { - return "Switch to generational DE as opposed to standard steady-state DE"; - } - - public boolean isCyclePop() { - return cyclePop; - } + public void setGenerational(boolean generational) { + this.generational = generational; + } - public void setCyclePop(boolean cycle) { - this.cyclePop = cycle; - } - - public String cyclePopTipText() { - return "if true, individuals are used as parents in a cyclic sequence - otherwise randomly "; - } - - /** - * @return the maximumAge - **/ - public boolean isReEvaluate() { - return reEvaluate; - } + public String generationalTipText() { + return "Switch to generational DE as opposed to standard steady-state DE"; + } - /** - * @param maximumAge the maximumAge to set - **/ - public void setReEvaluate(boolean reEvaluate) { - this.reEvaluate = reEvaluate; - } - - public String reEvaluateTipText() { - return "Reeavulates individuals which are older than maximum age instead of discarding them"; - } + public boolean isCyclePop() { + return cyclePop; + } + public void setCyclePop(boolean cycle) { + this.cyclePop = cycle; + } + + public String cyclePopTipText() { + return "if true, individuals are used as parents in a cyclic sequence - otherwise randomly "; + } + + /** + * @return the maximumAge + * + */ + public boolean isReEvaluate() { + return reEvaluate; + } + + /** + * @param maximumAge the maximumAge to set + * + */ + public void setReEvaluate(boolean reEvaluate) { + this.reEvaluate = reEvaluate; + } + + public String reEvaluateTipText() { + return "Reeavulates individuals which are older than maximum age instead of discarding them"; + } } \ No newline at end of file diff --git a/src/eva2/server/go/strategies/EsDpiNiching.java b/src/eva2/server/go/strategies/EsDpiNiching.java index 778dcbd1..cdaff572 100644 --- a/src/eva2/server/go/strategies/EsDpiNiching.java +++ b/src/eva2/server/go/strategies/EsDpiNiching.java @@ -284,6 +284,8 @@ public class EsDpiNiching implements InterfaceOptimizer, Serializable, Interface * with the given parameters. If windowLen <= 0, the deactivation mechanism * is disabled. This provides for semi-sequential niching with DPI-ES * + * + * * * @param threshold @@ -948,7 +950,8 @@ public class EsDpiNiching implements InterfaceOptimizer, Serializable, Interface /** * Calculate the dynamic population size, which is the number of individuals * that are currently "alive" in the peak set. This must be implemented in - * analogy to {@link #collectPopulationIncGen(Population, EvolutionStrategies[], Population)} + * analogy to + * {@link #collectPopulationIncGen(Population, EvolutionStrategies[], Population)} * * @return */ @@ -1048,10 +1051,6 @@ public class EsDpiNiching implements InterfaceOptimizer, Serializable, Interface } } - @Override - public void freeWilly() { - } - @Override public InterfaceSolutionSet getAllSolutions() { Population peaks = new Population(peakOpts.length); diff --git a/src/eva2/server/go/strategies/EvolutionStrategies.java b/src/eva2/server/go/strategies/EvolutionStrategies.java index 2de15c22..d2528daf 100644 --- a/src/eva2/server/go/strategies/EvolutionStrategies.java +++ b/src/eva2/server/go/strategies/EvolutionStrategies.java @@ -12,20 +12,20 @@ import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; -/** Evolution strategies by Rechenberg and Schwefel, but please remember that +/** + * Evolution strategies by Rechenberg and Schwefel, but please remember that * this only gives the generation strategy and not the coding. But this is the - * only stategy that is able to utilize the 1/5 success rule mutation. Unfortunately, - * there is a minor problem with the interpretation of the population size in constrast - * to the parameters mu and lambda used by Rechenberg and Schwefel. Therefore, i'm - * afraid that the interpretation of the population size may be subject to future - * changes. - * This is a implementation of Evolution Strategies. - * Copyright: Copyright (c) 2003 - * Company: University of Tuebingen, Computer Architecture - * @author Felix Streichert - * @version: $Revision: 307 $ - * $Date: 2007-12-04 14:31:47 +0100 (Tue, 04 Dec 2007) $ - * $Author: mkron $ + * only stategy that is able to utilize the 1/5 success rule mutation. + * Unfortunately, there is a minor problem with the interpretation of the + * population size in constrast to the parameters mu and lambda used by + * Rechenberg and Schwefel. Therefore, i'm afraid that the interpretation of the + * population size may be subject to future changes. This is a implementation of + * Evolution Strategies. Copyright: Copyright (c) 2003 Company: University of + * Tuebingen, Computer Architecture + * + * @author Felix Streichert + * @version: $Revision: 307 $ $Date: 2007-12-04 14:31:47 +0100 (Tue, 04 Dec + * 2007) $ $Author: mkron $ */ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializable { @@ -210,9 +210,9 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ } setPop(getReplacePop(nextGeneration)); - + // necessary here because evalPop was not called on population - this.firePropertyChangedEvent(Population.nextGenerationPerformed); + this.firePropertyChangedEvent(Population.nextGenerationPerformed); } /** @@ -339,18 +339,9 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ return this.identifier; } - /** - * This method is required to free the memory on a RMIServer, but there is - * nothing to implement. - */ - @Override - public void freeWilly() { - } - /** * These are for GUI */ - /** * This method returns a global info string * diff --git a/src/eva2/server/go/strategies/EvolutionaryProgramming.java b/src/eva2/server/go/strategies/EvolutionaryProgramming.java index 295f56ef..67989e8f 100644 --- a/src/eva2/server/go/strategies/EvolutionaryProgramming.java +++ b/src/eva2/server/go/strategies/EvolutionaryProgramming.java @@ -10,37 +10,36 @@ import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.F1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; -/** Evolutionary programming by Fogel. Works fine but is actually a quite greedy local search - * strategy solely based on mutation. To prevent any confusion, the mutation rate is temporaily - * set to 1.0. - * Potential citation: the PhD thesis of David B. Fogel (1992). - * - * Copyright: Copyright (c) 2003 - * Company: University of Tuebingen, Computer Architecture - * @author Felix Streichert - * @version: $Revision: 307 $ - * $Date: 2007-12-04 14:31:47 +0100 (Tue, 04 Dec 2007) $ - * $Author: mkron $ +/** + * Evolutionary programming by Fogel. Works fine but is actually a quite greedy + * local search strategy solely based on mutation. To prevent any confusion, the + * mutation rate is temporaily set to 1.0. Potential citation: the PhD thesis of + * David B. Fogel (1992). + * + * Copyright: Copyright (c) 2003 Company: University of Tuebingen, Computer + * Architecture + * + * @author Felix Streichert + * @version: $Revision: 307 $ $Date: 2007-12-04 14:31:47 +0100 (Tue, 04 Dec + * 2007) $ $Author: mkron $ */ - public class EvolutionaryProgramming implements InterfaceOptimizer, java.io.Serializable { - private int m_PopulationSize = 0; - private Population m_Population = new Population(); - private InterfaceOptimizationProblem m_Problem = new F1Problem(); - private InterfaceSelection m_EnvironmentSelection = new SelectEPTournaments(); - - private String m_Identifier = ""; + private int m_PopulationSize = 0; + private Population m_Population = new Population(); + private InterfaceOptimizationProblem m_Problem = new F1Problem(); + private InterfaceSelection m_EnvironmentSelection = new SelectEPTournaments(); + private String m_Identifier = ""; transient private InterfacePopulationChangedEventListener m_Listener; public EvolutionaryProgramming() { } public EvolutionaryProgramming(EvolutionaryProgramming a) { - this.m_Population = (Population)a.m_Population.clone(); - this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone(); - this.m_Identifier = a.m_Identifier; - this.m_EnvironmentSelection = (InterfaceSelection)a.m_EnvironmentSelection.clone(); + this.m_Population = (Population) a.m_Population.clone(); + this.m_Problem = (InterfaceOptimizationProblem) a.m_Problem.clone(); + this.m_Identifier = a.m_Identifier; + this.m_EnvironmentSelection = (InterfaceSelection) a.m_EnvironmentSelection.clone(); } @Override @@ -49,109 +48,123 @@ public class EvolutionaryProgramming implements InterfaceOptimizer, java.io.Seri } @Override - public void init() { - this.m_Problem.initPopulation(this.m_Population); + public void init() { + this.m_Problem.initPopulation(this.m_Population); + this.evaluatePopulation(this.m_Population); + this.m_PopulationSize = this.m_Population.size(); + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + } + + /** + * This method will init the optimizer with a given population + * + * @param reset If true the population is reset. + */ + @Override + public void initByPopulation(Population pop, boolean reset) { + this.m_Population = (Population) pop.clone(); + if (reset) { + this.m_Population.init(); this.evaluatePopulation(this.m_Population); - this.m_PopulationSize = this.m_Population.size(); this.firePropertyChangedEvent(Population.nextGenerationPerformed); } + } - /** This method will init the optimizer with a given population - * @param reset If true the population is reset. - */ - @Override - public void initByPopulation(Population pop, boolean reset) { - this.m_Population = (Population)pop.clone(); - if (reset) { - this.m_Population.init(); - this.evaluatePopulation(this.m_Population); - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } - } - - /** This method will evaluate the current population using the - * given problem. - * @param population The population that is to be evaluated - */ - private void evaluatePopulation(Population population) { - this.m_Problem.evaluate(population); - population.incrGeneration(); - } - - /** This method will generate the offspring population from the - * given population of evaluated individuals. - */ - private Population generateChildren() { - Population result = (Population)this.m_Population.cloneWithoutInds(); - AbstractEAIndividual mutant; - - result.clear(); - for (int i = 0; i < this.m_Population.size(); i++) { - mutant = (AbstractEAIndividual)((AbstractEAIndividual)this.m_Population.get(i)).clone(); - double tmpD = mutant.getMutationProbability(); - mutant.setMutationProbability(1.0); - mutant.mutate(); - mutant.setMutationProbability(tmpD); - result.add(mutant); - } - return result; + /** + * This method will evaluate the current population using the given problem. + * + * @param population The population that is to be evaluated + */ + private void evaluatePopulation(Population population) { + this.m_Problem.evaluate(population); + population.incrGeneration(); + } + + /** + * This method will generate the offspring population from the given + * population of evaluated individuals. + */ + private Population generateChildren() { + Population result = (Population) this.m_Population.cloneWithoutInds(); + AbstractEAIndividual mutant; + + result.clear(); + for (int i = 0; i < this.m_Population.size(); i++) { + mutant = (AbstractEAIndividual) ((AbstractEAIndividual) this.m_Population.get(i)).clone(); + double tmpD = mutant.getMutationProbability(); + mutant.setMutationProbability(1.0); + mutant.mutate(); + mutant.setMutationProbability(tmpD); + result.add(mutant); } + return result; + } @Override - public void optimize() { - Population nextGeneration, parents; + public void optimize() { + Population nextGeneration, parents; - this.m_EnvironmentSelection.prepareSelection(this.m_Population); - parents = this.m_EnvironmentSelection.selectFrom(this.m_Population, this.m_PopulationSize); - this.m_Population.clear(); - this.m_Population.addPopulation(parents); - nextGeneration = this.generateChildren(); - this.evaluatePopulation(nextGeneration); - nextGeneration.addPopulation(this.m_Population); - this.m_Population = nextGeneration; + this.m_EnvironmentSelection.prepareSelection(this.m_Population); + parents = this.m_EnvironmentSelection.selectFrom(this.m_Population, this.m_PopulationSize); + this.m_Population.clear(); + this.m_Population.addPopulation(parents); + nextGeneration = this.generateChildren(); + this.evaluatePopulation(nextGeneration); + nextGeneration.addPopulation(this.m_Population); + this.m_Population = nextGeneration; - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + } - /** This method allows you to add the LectureGUI as listener to the Optimizer + /** + * This method allows you to add the LectureGUI as listener to the Optimizer + * * @param ea */ @Override public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { this.m_Listener = ea; } + @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - /** Something has changed + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } + + /** + * Something has changed */ - protected void firePropertyChangedEvent (String name) { + protected void firePropertyChangedEvent(String name) { if (this.m_Listener != null) { this.m_Listener.registerPopulationStateChanged(this, name); } } - /** This method will set the problem that is to be optimized + /** + * This method will set the problem that is to be optimized + * * @param problem */ @Override - public void setProblem (InterfaceOptimizationProblem problem) { + public void setProblem(InterfaceOptimizationProblem problem) { this.m_Problem = problem; } + @Override - public InterfaceOptimizationProblem getProblem () { + public InterfaceOptimizationProblem getProblem() { return this.m_Problem; } - /** This method will return a string describing all properties of the optimizer - * and the applied methods. + /** + * This method will return a string describing all properties of the + * optimizer and the applied methods. + * * @return A descriptive string */ @Override @@ -159,39 +172,42 @@ public class EvolutionaryProgramming implements InterfaceOptimizer, java.io.Seri String result = ""; result += "Evolutionary Programming:\n"; result += "Optimization Problem: "; - result += this.m_Problem.getStringRepresentationForProblem(this) +"\n"; + result += this.m_Problem.getStringRepresentationForProblem(this) + "\n"; result += this.m_Population.getStringRepresentation(); return result; } - /** This method allows you to set an identifier for the algorithm - * @param name The indenifier + + /** + * This method allows you to set an identifier for the algorithm + * + * @param name The indenifier */ @Override public void setIdentifier(String name) { this.m_Identifier = name; } + @Override public String getIdentifier() { return this.m_Identifier; } - /** This method is required to free the memory on a RMIServer, - * but there is nothing to implement. - */ - @Override - public void freeWilly() { - - } - /********************************************************************************************************************** + /** + * ******************************************************************************************************************** * These are for GUI */ - /** This method returns a global info string + /** + * This method returns a global info string + * * @return description */ public static String globalInfo() { return "This is a basic Evolutionary Programming scheme."; } - /** This method will return a naming String + + /** + * This method will return a naming String + * * @return The name of the algorithm */ @Override @@ -199,36 +215,45 @@ public class EvolutionaryProgramming implements InterfaceOptimizer, java.io.Seri return "EP"; } - /** Assuming that all optimizer will store thier data in a population - * we will allow acess to this population to query to current state - * of the optimizer. + /** + * Assuming that all optimizer will store thier data in a population we will + * allow acess to this population to query to current state of the + * optimizer. + * * @return The population of current solutions to a given problem. */ @Override public Population getPopulation() { return this.m_Population; } + @Override - public void setPopulation(Population pop){ + public void setPopulation(Population pop) { this.m_Population = pop; } + public String populationTipText() { return "Edit the properties of the population used."; } - + @Override public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(getPopulation()); + return new SolutionSet(getPopulation()); } - /** Choose a method for selecting the reduced population. + + /** + * Choose a method for selecting the reduced population. + * * @param selection */ public void setEnvironmentSelection(InterfaceSelection selection) { this.m_EnvironmentSelection = selection; } + public InterfaceSelection getEnvironmentSelection() { return this.m_EnvironmentSelection; } + public String environmentSelectionTipText() { return "Choose a method for selecting the reduced population."; } diff --git a/src/eva2/server/go/strategies/FloodAlgorithm.java b/src/eva2/server/go/strategies/FloodAlgorithm.java index f633c1ea..637399db 100644 --- a/src/eva2/server/go/strategies/FloodAlgorithm.java +++ b/src/eva2/server/go/strategies/FloodAlgorithm.java @@ -9,33 +9,31 @@ import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; -/** The flood algorithm, and alternative to the threshold algorithms. No really - * good but commonly known and sometimes even used. Here the problem is to choose - * the initial flood peak and the drain rate such that it fits the current optimization - * problem. But again this is a greedy local search strategy. Similar to the - * evolutionary programming strategy this strategy sets the mutation rate temporarily - * to 1.0. - * The algorithm regards only one-dimensional fitness. - * Created by IntelliJ IDEA. - * User: streiche - * Date: 01.10.2004 - * Time: 13:46:02 - * To change this template use File | Settings | File Templates. +/** + * The flood algorithm, and alternative to the threshold algorithms. No really + * good but commonly known and sometimes even used. Here the problem is to + * choose the initial flood peak and the drain rate such that it fits the + * current optimization problem. But again this is a greedy local search + * strategy. Similar to the evolutionary programming strategy this strategy sets + * the mutation rate temporarily to 1.0. The algorithm regards only + * one-dimensional fitness. Created by IntelliJ IDEA. User: streiche Date: + * 01.10.2004 Time: 13:46:02 To change this template use File | Settings | File + * Templates. */ public class FloodAlgorithm implements InterfaceOptimizer, java.io.Serializable { // These variables are necessary for the simple testcase - private InterfaceOptimizationProblem m_Problem = new B1Problem(); - private int m_MultiRuns = 100; - private int m_FitnessCalls = 100; - private int m_FitnessCallsNeeded = 0; - GAIndividualBinaryData m_Best, m_Test; - public double m_InitialFloodPeak = 2000.0, m_CurrentFloodPeak; - public double m_DrainRate = 1.0; + private InterfaceOptimizationProblem m_Problem = new B1Problem(); + private int m_MultiRuns = 100; + private int m_FitnessCalls = 100; + private int m_FitnessCallsNeeded = 0; + GAIndividualBinaryData m_Best, m_Test; + public double m_InitialFloodPeak = 2000.0, m_CurrentFloodPeak; + public double m_DrainRate = 1.0; // These variables are necessary for the more complex LectureGUI enviroment - transient private String m_Identifier = ""; + transient private String m_Identifier = ""; transient private InterfacePopulationChangedEventListener m_Listener; - private Population m_Population; + private Population m_Population; public FloodAlgorithm() { this.m_Population = new Population(); @@ -43,10 +41,10 @@ public class FloodAlgorithm implements InterfaceOptimizer, java.io.Serializable } public FloodAlgorithm(FloodAlgorithm a) { - this.m_Population = (Population)a.m_Population.clone(); - this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone(); - this.m_InitialFloodPeak = a.m_InitialFloodPeak; - this.m_DrainRate = a.m_DrainRate; + this.m_Population = (Population) a.m_Population.clone(); + this.m_Problem = (InterfaceOptimizationProblem) a.m_Problem.clone(); + this.m_InitialFloodPeak = a.m_InitialFloodPeak; + this.m_DrainRate = a.m_DrainRate; } @Override @@ -54,7 +52,8 @@ public class FloodAlgorithm implements InterfaceOptimizer, java.io.Serializable return (Object) new FloodAlgorithm(this); } - /** This method will init the HillClimber + /** + * This method will init the HillClimber */ @Override public void init() { @@ -64,27 +63,30 @@ public class FloodAlgorithm implements InterfaceOptimizer, java.io.Serializable this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** This method will init the optimizer with a given population - * @param reset If true the population is reset. + /** + * This method will init the optimizer with a given population + * + * @param reset If true the population is reset. */ @Override public void initByPopulation(Population pop, boolean reset) { - this.m_Population = (Population)pop.clone(); + this.m_Population = (Population) pop.clone(); if (reset) { - this.m_Population.init(); + this.m_Population.init(); this.m_Problem.evaluate(this.m_Population); this.firePropertyChangedEvent(Population.nextGenerationPerformed); } this.m_CurrentFloodPeak = this.m_InitialFloodPeak; } - /** This method will optimize + /** + * This method will optimize */ @Override public void optimize() { - AbstractEAIndividual indy; - Population original = (Population)this.m_Population.clone(); - double[] fitness; + AbstractEAIndividual indy; + Population original = (Population) this.m_Population.clone(); + double[] fitness; for (int i = 0; i < this.m_Population.size(); i++) { indy = ((AbstractEAIndividual) this.m_Population.get(i)); @@ -95,7 +97,7 @@ public class FloodAlgorithm implements InterfaceOptimizer, java.io.Serializable } this.m_Problem.evaluate(this.m_Population); for (int i = 0; i < this.m_Population.size(); i++) { - fitness = ((AbstractEAIndividual)this.m_Population.get(i)).getFitness(); + fitness = ((AbstractEAIndividual) this.m_Population.get(i)).getFitness(); if (fitness[0] > this.m_CurrentFloodPeak) { this.m_Population.remove(i); this.m_Population.add(i, original.get(i)); @@ -106,13 +108,15 @@ public class FloodAlgorithm implements InterfaceOptimizer, java.io.Serializable this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** This method calculates the difference between the fitness values - * @param org The original - * @param mut The mutant + /** + * This method calculates the difference between the fitness values + * + * @param org The original + * @param mut The mutant */ private double calculateDelta(AbstractEAIndividual org, AbstractEAIndividual mut) { - double result = 0; - double[] fitOrg, fitMut; + double result = 0; + double[] fitOrg, fitMut; fitOrg = org.getFitness(); fitMut = mut.getFitness(); for (int i = 0; i < fitOrg.length; i++) { @@ -121,19 +125,23 @@ public class FloodAlgorithm implements InterfaceOptimizer, java.io.Serializable return result; } - /** This method will set the problem that is to be optimized + /** + * This method will set the problem that is to be optimized + * * @param problem */ @Override - public void setProblem (InterfaceOptimizationProblem problem) { + public void setProblem(InterfaceOptimizationProblem problem) { this.m_Problem = problem; } + @Override - public InterfaceOptimizationProblem getProblem () { + public InterfaceOptimizationProblem getProblem() { return this.m_Problem; } - /** This method will init the HillClimber + /** + * This method will init the HillClimber */ public void defaultInit() { this.m_FitnessCallsNeeded = 0; @@ -141,24 +149,26 @@ public class FloodAlgorithm implements InterfaceOptimizer, java.io.Serializable this.m_Best.defaultInit(m_Problem); } - /** This method will optimize + /** + * This method will optimize */ public void defaultOptimize() { for (int i = 0; i < m_FitnessCalls; i++) { - this.m_Test = (GAIndividualBinaryData)((this.m_Best).clone()); + this.m_Test = (GAIndividualBinaryData) ((this.m_Best).clone()); this.m_Test.defaultMutate(); if (this.m_Test.defaultEvaulateAsMiniBits() < this.m_Best.defaultEvaulateAsMiniBits()) { this.m_Best = this.m_Test; } this.m_FitnessCallsNeeded = i; if (this.m_Best.defaultEvaulateAsMiniBits() == 0) { - i = this.m_FitnessCalls +1; + i = this.m_FitnessCalls + 1; } } } - /** This main method will start a simple hillclimber. - * No arguments necessary. + /** + * This main method will start a simple hillclimber. No arguments necessary. + * * @param args */ public static void main(String[] args) { @@ -172,36 +182,43 @@ public class FloodAlgorithm implements InterfaceOptimizer, java.io.Serializable } TmpMeanCalls /= program.m_MultiRuns; TmpMeanFitness /= program.m_MultiRuns; - System.out.println("("+program.m_MultiRuns+"/"+program.m_FitnessCalls+") Mean Fitness : " + TmpMeanFitness + " Mean Calls needed: " + TmpMeanCalls); + System.out.println("(" + program.m_MultiRuns + "/" + program.m_FitnessCalls + ") Mean Fitness : " + TmpMeanFitness + " Mean Calls needed: " + TmpMeanCalls); } - /** This method allows you to add the LectureGUI as listener to the Optimizer + /** + * This method allows you to add the LectureGUI as listener to the Optimizer + * * @param ea */ @Override public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { this.m_Listener = ea; } + @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - /** Something has changed + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } + + /** + * Something has changed */ - protected void firePropertyChangedEvent (String name) { + protected void firePropertyChangedEvent(String name) { if (this.m_Listener != null) { this.m_Listener.registerPopulationStateChanged(this, name); } } - /** This method will return a string describing all properties of the optimizer - * and the applied methods. + /** + * This method will return a string describing all properties of the + * optimizer and the applied methods. + * * @return A descriptive string */ @Override @@ -209,44 +226,46 @@ public class FloodAlgorithm implements InterfaceOptimizer, java.io.Serializable String result = ""; if (this.m_Population.size() > 1) { result += "Multi(" + this.m_Population.size() + ")-Start Hill Climbing:\n"; - } - else { + } else { result += "Simulated Annealing:\n"; } result += "Optimization Problem: "; - result += this.m_Problem.getStringRepresentationForProblem(this) +"\n"; + result += this.m_Problem.getStringRepresentationForProblem(this) + "\n"; result += this.m_Population.getStringRepresentation(); return result; } - /** This method allows you to set an identifier for the algorithm - * @param name The indenifier + + /** + * This method allows you to set an identifier for the algorithm + * + * @param name The indenifier */ @Override - public void setIdentifier(String name) { + public void setIdentifier(String name) { this.m_Identifier = name; } - @Override - public String getIdentifier() { - return this.m_Identifier; - } - /** This method is required to free the memory on a RMIServer, - * but there is nothing to implement. - */ @Override - public void freeWilly() { - + public String getIdentifier() { + return this.m_Identifier; } -/********************************************************************************************************************** - * These are for GUI - */ - /** This method returns a global info string + + /** + * ******************************************************************************************************************** + * These are for GUI + */ + /** + * This method returns a global info string + * * @return description */ public static String globalInfo() { return "The flood algorithm uses an declining flood peak to accpect new solutions (*shudder* check inital flood peak and drain very carefully!)."; } - /** This method will return a naming String + + /** + * This method will return a naming String + * * @return The name of the algorithm */ @Override @@ -254,55 +273,67 @@ public class FloodAlgorithm implements InterfaceOptimizer, java.io.Serializable return "MS-FA"; } - /** Assuming that all optimizer will store thier data in a population - * we will allow acess to this population to query to current state - * of the optimizer. + /** + * Assuming that all optimizer will store thier data in a population we will + * allow acess to this population to query to current state of the + * optimizer. + * * @return The population of current solutions to a given problem. */ @Override public Population getPopulation() { return this.m_Population; } + @Override - public void setPopulation(Population pop){ + public void setPopulation(Population pop) { this.m_Population = pop; } + public String populationTipText() { return "Change the number of best individuals stored (MS-FA)."; } - @Override public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(getPopulation()); + return new SolutionSet(getPopulation()); } - /** This methods allow you to set/get the temperatur of the flood - * algorithm procedure + + /** + * This methods allow you to set/get the temperatur of the flood algorithm + * procedure + * * @return The initial flood level. */ public double getInitialFloodPeak() { return this.m_InitialFloodPeak; } - public void setInitialFloodPeak(double pop){ + + public void setInitialFloodPeak(double pop) { this.m_InitialFloodPeak = pop; } + public String initialFloodPeakTipText() { return "Set the initial flood peak."; } - /** This methods allow you to set/get the drain rate of the flood - * algorithm procedure + /** + * This methods allow you to set/get the drain rate of the flood algorithm + * procedure + * * @return The drain rate. */ public double getDrainRate() { return this.m_DrainRate; } - public void setDrainRate(double a){ + + public void setDrainRate(double a) { this.m_DrainRate = a; if (this.m_DrainRate < 0) { this.m_DrainRate = 0.0; } } + public String drainRateTipText() { return "Set the drain rate that reduces the current flood level each generation."; } diff --git a/src/eva2/server/go/strategies/GeneticAlgorithm.java b/src/eva2/server/go/strategies/GeneticAlgorithm.java index 84ccb88b..789e3e97 100644 --- a/src/eva2/server/go/strategies/GeneticAlgorithm.java +++ b/src/eva2/server/go/strategies/GeneticAlgorithm.java @@ -241,14 +241,6 @@ public class GeneticAlgorithm implements InterfaceOptimizer, java.io.Serializabl return this.identifier; } - /** - * This method is required to free the memory on a RMIServer, but there is - * nothing to implement. - */ - @Override - public void freeWilly() { - } - /** * ******************************************************************************************************************** * These are for GUI diff --git a/src/eva2/server/go/strategies/GradientDescentAlgorithm.java b/src/eva2/server/go/strategies/GradientDescentAlgorithm.java index 209d9b19..841ab870 100644 --- a/src/eva2/server/go/strategies/GradientDescentAlgorithm.java +++ b/src/eva2/server/go/strategies/GradientDescentAlgorithm.java @@ -13,554 +13,577 @@ import eva2.server.go.problems.InterfaceOptimizationProblem; import eva2.tools.EVAERROR; import eva2.tools.ReflectPackage; -/** +/** * A gradient descent algorithm by hannes planatscher don't expect any * descriptions here... *big sigh* - * + * * mkron added some! - * + * * @author not attributable * @version 1.0 */ - public class GradientDescentAlgorithm implements InterfaceOptimizer, java.io.Serializable { - private InterfaceOptimizationProblem m_Problem; - - InterfaceDataTypeDouble m_Best, m_Test; - private int iterations = 1; - private double wDecreaseStepSize = 0.5; - private double wIncreaseStepSize = 1.1; - boolean recovery = false; - private int recoverylocksteps = 5; - private double recoverythreshold = 100000; - boolean localStepSizeAdaption = true; - boolean globalStepSizeAdaption = false; - private double globalinitstepsize = 1; - double globalmaxstepsize = 3.0; - double globalminstepsize = 1e-10; - boolean manhattan = false; - double localmaxstepsize = 10; - double localminstepsize = 1e-10; - private boolean momentumterm = false; - transient private InterfacePopulationChangedEventListener m_Listener; - public double maximumabsolutechange = 0.2; - // Hashtable indyhash; - - // These variables are necessary for the more complex LectureGUI enviroment - transient private String m_Identifier = ""; - private Population m_Population; - - private static boolean TRACE=false; - - private static final String lockKey = "gdaLockDataKey"; - private static final String lastFitnessKey = "gdaLastFitDataKey"; - private static final String stepSizeKey = "gdaStepSizeDataKey"; - private static final String wStepSizeKey = "gdaWStepSizeDataKey"; - private static final String gradientKey = "gdaGradientDataKey"; - private static final String changesKey = "gdaChangesDataKey"; - private static final String oldParamsKey = "gdaOldParamsDataKey"; + private InterfaceOptimizationProblem m_Problem; + InterfaceDataTypeDouble m_Best, m_Test; + private int iterations = 1; + private double wDecreaseStepSize = 0.5; + private double wIncreaseStepSize = 1.1; + boolean recovery = false; + private int recoverylocksteps = 5; + private double recoverythreshold = 100000; + boolean localStepSizeAdaption = true; + boolean globalStepSizeAdaption = false; + private double globalinitstepsize = 1; + double globalmaxstepsize = 3.0; + double globalminstepsize = 1e-10; + boolean manhattan = false; + double localmaxstepsize = 10; + double localminstepsize = 1e-10; + private boolean momentumterm = false; + transient private InterfacePopulationChangedEventListener m_Listener; + public double maximumabsolutechange = 0.2; + // Hashtable indyhash; + // These variables are necessary for the more complex LectureGUI enviroment + transient private String m_Identifier = ""; + private Population m_Population; + private static boolean TRACE = false; + private static final String lockKey = "gdaLockDataKey"; + private static final String lastFitnessKey = "gdaLastFitDataKey"; + private static final String stepSizeKey = "gdaStepSizeDataKey"; + private static final String wStepSizeKey = "gdaWStepSizeDataKey"; + private static final String gradientKey = "gdaGradientDataKey"; + private static final String changesKey = "gdaChangesDataKey"; + private static final String oldParamsKey = "gdaOldParamsDataKey"; @Override - public void initByPopulation(Population pop, boolean reset) { - this.setPopulation((Population) pop.clone()); - if (reset) { - this.getPopulation().init(); - this.m_Problem.evaluate(this.getPopulation()); - this.firePropertyChangedEvent(Population.nextGenerationPerformed); + public void initByPopulation(Population pop, boolean reset) { + this.setPopulation((Population) pop.clone()); + if (reset) { + this.getPopulation().init(); + this.m_Problem.evaluate(this.getPopulation()); + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + } + //System.out.println("initByPopulation() called"); +// indyhash = new Hashtable(); } - //System.out.println("initByPopulation() called"); + + public GradientDescentAlgorithm() { // indyhash = new Hashtable(); - } + this.m_Population = new Population(); + this.m_Population.setTargetSize(1); + } - public GradientDescentAlgorithm() { + /** + * GDA with locally adapted step size. + * + * @param minStepSize + * @param maxStepSize + * @param maxAbsoluteChange + */ + public GradientDescentAlgorithm(double minStepSize, double maxStepSize, double maxAbsoluteChange) { + globalStepSizeAdaption = false; + localStepSizeAdaption = true; + localminstepsize = minStepSize; + globalminstepsize = minStepSize; + localmaxstepsize = maxStepSize; + globalmaxstepsize = maxStepSize; + maximumabsolutechange = maxAbsoluteChange; + } + + @Override + public Object clone() { + /** + * @todo Implement InterfaceOptimizer method + */ + throw new java.lang.UnsupportedOperationException("Method clone() not yet implemented."); + } + + @Override + public String getName() { + return "GradientDescentAlgorithm"; + } + + @Override + public void init() { + //System.out.println("init() called "); // indyhash = new Hashtable(); - this.m_Population = new Population(); - this.m_Population.setTargetSize(1); - } - - /** - * GDA with locally adapted step size. - * - * @param minStepSize - * @param maxStepSize - * @param maxAbsoluteChange - */ - public GradientDescentAlgorithm(double minStepSize, double maxStepSize, double maxAbsoluteChange) { - globalStepSizeAdaption=false; - localStepSizeAdaption=true; - localminstepsize = minStepSize; - globalminstepsize = minStepSize; - localmaxstepsize = maxStepSize; - globalmaxstepsize = maxStepSize; - maximumabsolutechange = maxAbsoluteChange; - } + this.m_Problem.initPopulation(this.m_Population); + this.m_Problem.evaluate(this.m_Population); + } + + public double signum(double val) { + return (val < 0) ? -1 : 1; + } @Override - public Object clone() { - /**@todo Implement InterfaceOptimizer method*/ - throw new java.lang.UnsupportedOperationException("Method clone() not yet implemented."); - } - - @Override - public String getName() { - return "GradientDescentAlgorithm"; - } - - @Override - public void init() { - //System.out.println("init() called "); -// indyhash = new Hashtable(); - this.m_Problem.initPopulation(this.m_Population); - this.m_Problem.evaluate(this.m_Population); - } - - public double signum(double val) { - return (val < 0) ? -1 : 1; - } - - @Override - public void optimize() { - // System.out.println("opt. called"); - AbstractEAIndividual indy; + public void optimize() { + // System.out.println("opt. called"); + AbstractEAIndividual indy; // if ((this.indyhash == null) || (this.indyhash.size() <1)) init(); - for (int i = 0; i < this.m_Population.size(); i++) { - indy = ((AbstractEAIndividual)this.m_Population.get(i)); - if (!indy.hasData(gradientKey)) { - //System.out.println("new indy to hash"); + for (int i = 0; i < this.m_Population.size(); i++) { + indy = ((AbstractEAIndividual) this.m_Population.get(i)); + if (!indy.hasData(gradientKey)) { + //System.out.println("new indy to hash"); // Hashtable history = new Hashtable(); - int[] lock = new int[((InterfaceDataTypeDouble) indy).getDoubleData().length]; - double[] wstepsize = new double[((InterfaceDataTypeDouble) indy).getDoubleData().length]; - for (int li = 0; li < lock.length; li++) { - lock[li] = 0; - } - for (int li = 0; li < lock.length; li++) { - wstepsize[li] = 1.0; - } - double fitness = 0; - indy.putData(lockKey, lock); - indy.putData(lastFitnessKey, new Double(fitness)); - indy.putData(stepSizeKey, new Double(globalinitstepsize)); - indy.putData(wStepSizeKey, wstepsize); + int[] lock = new int[((InterfaceDataTypeDouble) indy).getDoubleData().length]; + double[] wstepsize = new double[((InterfaceDataTypeDouble) indy).getDoubleData().length]; + for (int li = 0; li < lock.length; li++) { + lock[li] = 0; + } + for (int li = 0; li < lock.length; li++) { + wstepsize[li] = 1.0; + } + double fitness = 0; + indy.putData(lockKey, lock); + indy.putData(lastFitnessKey, new Double(fitness)); + indy.putData(stepSizeKey, new Double(globalinitstepsize)); + indy.putData(wStepSizeKey, wstepsize); // indyhash.put(indy, history); - } else { - //System.out.println("indy already in hash"); - } - } - // System.out.println("hashtable built"); - for (int i = 0; i < this.m_Population.size(); i++) { - - indy = ((AbstractEAIndividual)this.m_Population.get(i)); - double[][] range = ((InterfaceDataTypeDouble) indy).getDoubleRange(); - double[] params = ((InterfaceDataTypeDouble) indy).getDoubleData(); - indy.putData(oldParamsKey , params); - - int[] lock = (int[]) indy.getData(lockKey); - double indystepsize = ((Double) indy.getData(stepSizeKey)).doubleValue(); - // System.out.println("indystepsize" + indystepsize); - - if ((this.m_Problem instanceof InterfaceFirstOrderDerivableProblem) && (indy instanceof InterfaceDataTypeDouble)) { -// Hashtable history = (Hashtable) indyhash.get(indy); - for (int iterations = 0; iterations < this.iterations; iterations++) { - - double[] oldgradient = indy.hasData(gradientKey) ? (double[]) indy.getData(gradientKey) : null; - double[] wstepsize = (double[]) indy.getData(wStepSizeKey); - double[] oldchange = null; - - double[] gradient = ((InterfaceFirstOrderDerivableProblem) m_Problem).getFirstOrderGradients(params); - if (TRACE) { - System.out.println("GDA: " + BeanInspector.toString(params) + ", grad: " + BeanInspector.toString(gradient)); + } else { + //System.out.println("indy already in hash"); } - if ((oldgradient != null) && (wstepsize != null)) { // LOCAL adaption - for (int li = 0; li < wstepsize.length; li++) { - double prod = gradient[li] * oldgradient[li]; - if (prod < 0) { - wstepsize[li] = wDecreaseStepSize * wstepsize[li]; - } else if (prod > 0) { - wstepsize[li] = wIncreaseStepSize * wstepsize[li]; - } - wstepsize[li] = (wstepsize[li] < localminstepsize) ? localminstepsize : wstepsize[li]; - wstepsize[li] = (wstepsize[li] > localmaxstepsize) ? localmaxstepsize : wstepsize[li]; + } + // System.out.println("hashtable built"); + for (int i = 0; i < this.m_Population.size(); i++) { + + indy = ((AbstractEAIndividual) this.m_Population.get(i)); + double[][] range = ((InterfaceDataTypeDouble) indy).getDoubleRange(); + double[] params = ((InterfaceDataTypeDouble) indy).getDoubleData(); + indy.putData(oldParamsKey, params); + + int[] lock = (int[]) indy.getData(lockKey); + double indystepsize = ((Double) indy.getData(stepSizeKey)).doubleValue(); + // System.out.println("indystepsize" + indystepsize); + + if ((this.m_Problem instanceof InterfaceFirstOrderDerivableProblem) && (indy instanceof InterfaceDataTypeDouble)) { +// Hashtable history = (Hashtable) indyhash.get(indy); + for (int iterations = 0; iterations < this.iterations; iterations++) { + + double[] oldgradient = indy.hasData(gradientKey) ? (double[]) indy.getData(gradientKey) : null; + double[] wstepsize = (double[]) indy.getData(wStepSizeKey); + double[] oldchange = null; + + double[] gradient = ((InterfaceFirstOrderDerivableProblem) m_Problem).getFirstOrderGradients(params); + if (TRACE) { + System.out.println("GDA: " + BeanInspector.toString(params) + ", grad: " + BeanInspector.toString(gradient)); + } + if ((oldgradient != null) && (wstepsize != null)) { // LOCAL adaption + for (int li = 0; li < wstepsize.length; li++) { + double prod = gradient[li] * oldgradient[li]; + if (prod < 0) { + wstepsize[li] = wDecreaseStepSize * wstepsize[li]; + } else if (prod > 0) { + wstepsize[li] = wIncreaseStepSize * wstepsize[li]; + } + wstepsize[li] = (wstepsize[li] < localminstepsize) ? localminstepsize : wstepsize[li]; + wstepsize[li] = (wstepsize[li] > localmaxstepsize) ? localmaxstepsize : wstepsize[li]; // System.out.println("wstepsize "+ li + " " + wstepsize[li]); - } + } - } - double[] newparams = new double[params.length]; - indy.putData(gradientKey, gradient); - double[] change = new double[params.length]; - if (indy.hasData(changesKey)) { - oldchange =(double[]) indy.getData(changesKey); - } - boolean dograddesc = (this.momentumterm) && (oldchange != null); + } + double[] newparams = new double[params.length]; + indy.putData(gradientKey, gradient); + double[] change = new double[params.length]; + if (indy.hasData(changesKey)) { + oldchange = (double[]) indy.getData(changesKey); + } + boolean dograddesc = (this.momentumterm) && (oldchange != null); - for (int j = 0; j < newparams.length; j++) { - if (lock[j] == 0) { - double tempstepsize = 1; - if (this.localStepSizeAdaption) { - tempstepsize *= wstepsize[j]; - } - if (this.globalStepSizeAdaption) { - tempstepsize *= indystepsize; - } - double wchange = signum(tempstepsize * gradient[j]) * Math.min(maximumabsolutechange,Math.abs(tempstepsize * gradient[j])); //indystepsize * gradient[j]; - if (this.manhattan) { - wchange = this.signum(wchange) * tempstepsize; - } - if (dograddesc) { - wchange += this.momentumweigth * oldchange[j]; - } - newparams[j] = params[j] - wchange; - if (newparams[j] < range[j][0]) { - newparams[j] = range[j][0]; - } - if (newparams[j] > range[j][1]) { - newparams[j] = range[j][1]; - } + for (int j = 0; j < newparams.length; j++) { + if (lock[j] == 0) { + double tempstepsize = 1; + if (this.localStepSizeAdaption) { + tempstepsize *= wstepsize[j]; + } + if (this.globalStepSizeAdaption) { + tempstepsize *= indystepsize; + } + double wchange = signum(tempstepsize * gradient[j]) * Math.min(maximumabsolutechange, Math.abs(tempstepsize * gradient[j])); //indystepsize * gradient[j]; + if (this.manhattan) { + wchange = this.signum(wchange) * tempstepsize; + } + if (dograddesc) { + wchange += this.momentumweigth * oldchange[j]; + } + newparams[j] = params[j] - wchange; + if (newparams[j] < range[j][0]) { + newparams[j] = range[j][0]; + } + if (newparams[j] > range[j][1]) { + newparams[j] = range[j][1]; + } // for (int g = 0; g < newparams.length; g++) { // System.out.println("Param " + g +": " + newparams[g]); // } - change[j] += wchange; - } else { - lock[j]--; + change[j] += wchange; + } else { + lock[j]--; + } + } + params = newparams; + + indy.putData(changesKey, change); + + } // end loop iterations + + ((InterfaceDataTypeDouble) indy).SetDoubleGenotype(params); + + } // end if ((this.m_Problem instanceof InterfaceFirstOrderDerivableProblem) && (indy instanceof InterfaceDataTypeDouble)) { + else { + String msg = "Warning, problem of type InterfaceFirstOrderDerivableProblem and template of type InterfaceDataTypeDouble is required for " + this.getClass(); + EVAERROR.errorMsgOnce(msg); + Class[] clsArr = ReflectPackage.getAssignableClasses(InterfaceFirstOrderDerivableProblem.class.getName(), true, true); + msg += " (available: "; + for (Class cls : clsArr) { + msg = msg + " " + cls.getSimpleName(); + } + msg += ")"; + throw new RuntimeException(msg); } - } - params = newparams; + } // for loop population size - indy.putData(changesKey, change); + this.m_Problem.evaluate(this.m_Population); + m_Population.incrGeneration(); - } // end loop iterations - - ((InterfaceDataTypeDouble) indy).SetDoubleGenotype(params); - - } // end if ((this.m_Problem instanceof InterfaceFirstOrderDerivableProblem) && (indy instanceof InterfaceDataTypeDouble)) { - else { - String msg="Warning, problem of type InterfaceFirstOrderDerivableProblem and template of type InterfaceDataTypeDouble is required for " + this.getClass(); - EVAERROR.errorMsgOnce(msg); - Class[] clsArr = ReflectPackage.getAssignableClasses(InterfaceFirstOrderDerivableProblem.class.getName(), true, true); - msg += " (available: "; - for (Class cls: clsArr) { - msg=msg+" "+cls.getSimpleName(); - } - msg += ")"; - throw new RuntimeException(msg); - } - } // for loop population size - - this.m_Problem.evaluate(this.m_Population); - m_Population.incrGeneration(); - - if (this.recovery) { - for (int i = 0; i < this.m_Population.size(); i++) { - indy = ((AbstractEAIndividual)this.m_Population.get(i)); + if (this.recovery) { + for (int i = 0; i < this.m_Population.size(); i++) { + indy = ((AbstractEAIndividual) this.m_Population.get(i)); // Hashtable history = (Hashtable) indyhash.get(indy); - if (indy.getFitness()[0] > recoverythreshold) { - if (TRACE) { - System.out.println("Gradient Descent: Fitness critical:" + indy.getFitness()[0]); - } - ((InterfaceDataTypeDouble) indy).SetDoublePhenotype((double[]) indy.getData(oldParamsKey)); - double[] changes = (double[]) indy.getData(changesKey); - int[] lock = (int[]) indy.getData(lockKey); + if (indy.getFitness()[0] > recoverythreshold) { + if (TRACE) { + System.out.println("Gradient Descent: Fitness critical:" + indy.getFitness()[0]); + } + ((InterfaceDataTypeDouble) indy).SetDoublePhenotype((double[]) indy.getData(oldParamsKey)); + double[] changes = (double[]) indy.getData(changesKey); + int[] lock = (int[]) indy.getData(lockKey); - int indexmaxchange = 0; - double maxchangeval = Double.NEGATIVE_INFINITY; - for (int j = 0; j < changes.length; j++) { - if ((changes[j] > maxchangeval) && (lock[j] == 0)) { - indexmaxchange = j; - maxchangeval = changes[j]; + int indexmaxchange = 0; + double maxchangeval = Double.NEGATIVE_INFINITY; + for (int j = 0; j < changes.length; j++) { + if ((changes[j] > maxchangeval) && (lock[j] == 0)) { + indexmaxchange = j; + maxchangeval = changes[j]; + } + } + lock[indexmaxchange] = recoverylocksteps; + indy.putData(lockKey, lock); + } else { + } } - } - lock[indexmaxchange] = recoverylocksteps; - indy.putData(lockKey, lock); - } else { + this.m_Problem.evaluate(this.m_Population); + m_Population.incrGeneration(); } - } - this.m_Problem.evaluate(this.m_Population); - m_Population.incrGeneration(); - } - if (this.globalStepSizeAdaption) { + if (this.globalStepSizeAdaption) { - //System.out.println("gsa main"); - for (int i = 0; i < this.m_Population.size(); i++) { - indy = ((AbstractEAIndividual)this.m_Population.get(i)); + //System.out.println("gsa main"); + for (int i = 0; i < this.m_Population.size(); i++) { + indy = ((AbstractEAIndividual) this.m_Population.get(i)); // Hashtable history = (Hashtable) indyhash.get(indy); // if (history == null) break; - if (indy.getData(lastFitnessKey) != null) { - double lastfit = ((Double) indy.getData(lastFitnessKey)).doubleValue(); - double indystepsize = ((Double) indy.getData(stepSizeKey)).doubleValue(); + if (indy.getData(lastFitnessKey) != null) { + double lastfit = ((Double) indy.getData(lastFitnessKey)).doubleValue(); + double indystepsize = ((Double) indy.getData(stepSizeKey)).doubleValue(); - if (lastfit < indy.getFitness()[0]) { // GLOBAL adaption - indystepsize *= wDecreaseStepSize; - } else { - indystepsize *= wIncreaseStepSize; - } + if (lastfit < indy.getFitness()[0]) { // GLOBAL adaption + indystepsize *= wDecreaseStepSize; + } else { + indystepsize *= wIncreaseStepSize; + } //System.out.println("newstepsize" + indystepsize); - indystepsize = (indystepsize > globalmaxstepsize) ? globalmaxstepsize : indystepsize; - indystepsize = (indystepsize < globalminstepsize) ? globalminstepsize : indystepsize; - indy.putData(stepSizeKey, new Double(indystepsize)); - } + indystepsize = (indystepsize > globalmaxstepsize) ? globalmaxstepsize : indystepsize; + indystepsize = (indystepsize < globalminstepsize) ? globalminstepsize : indystepsize; + indy.putData(stepSizeKey, new Double(indystepsize)); + } //System.out.println("newstepsize in bounds" + indystepsize); - indy.putData(lastFitnessKey, new Double(indy.getFitness()[0])); - } + indy.putData(lastFitnessKey, new Double(indy.getFitness()[0])); + } + } + + + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + } + private double momentumweigth = 0.1; + + protected void firePropertyChangedEvent(String name) { + if (this.m_Listener != null) { + this.m_Listener.registerPopulationStateChanged(this, name); + } } - - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } - - private double momentumweigth = 0.1; - - protected void firePropertyChangedEvent(String name) { - if (this.m_Listener != null) { - this.m_Listener.registerPopulationStateChanged(this, name); - } - } + @Override + public Population getPopulation() { + return this.m_Population; + } @Override - public Population getPopulation() { - return this.m_Population; - } - - @Override - public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(getPopulation()); - } + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(getPopulation()); + } @Override - public void setPopulation(Population pop) { + public void setPopulation(Population pop) { // Hashtable newindyhash = new Hashtable(); // for (int i = 0; i < pop.size(); i++) { // if (indyhash.contains(pop.get(i))) newindyhash.put(pop.get(i), indyhash.get(pop.get(i))); // } // indyhash = newindyhash; - this.m_Population = pop; - } - - - /** This method allows you to set an identifier for the algorithm - * @param name The indenifier - */ - @Override - public void setIdentifier(String name) { - this.m_Identifier = name; - } - - @Override - public String getIdentifier() { - return this.m_Identifier; - } - - @Override - public void setProblem(InterfaceOptimizationProblem problem) { - - m_Problem = problem; - } - - @Override - public InterfaceOptimizationProblem getProblem() { - return m_Problem; - } - - @Override - public String getStringRepresentation() { - return "GradientDescentAlgorithm"; - } - - @Override - public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { - this.m_Listener = ea; - } - @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - public static void main(String[] args) { - GradientDescentAlgorithm program = new GradientDescentAlgorithm(); - InterfaceOptimizationProblem problem = new F1Problem(); - program.setProblem(problem); - program.init(); - for (int i = 0; i < 100; i++) { - program.optimize(); - System.out.println(program.getPopulation().getBestFitness()[0]); + this.m_Population = pop; } - double[] res = ((InterfaceDataTypeDouble) program.getPopulation().getBestIndividual()).getDoubleData(); - for (int i = 0; i < res.length; i++) { - System.out.print(res[i] + " "); + + /** + * This method allows you to set an identifier for the algorithm + * + * @param name The indenifier + */ + @Override + public void setIdentifier(String name) { + this.m_Identifier = name; } - } @Override - public void freeWilly() { } + public String getIdentifier() { + return this.m_Identifier; + } - public static String globalInfo() { - return "Gradient Descent can be applied to derivable functions ("+InterfaceFirstOrderDerivableProblem.class.getSimpleName()+")."; - } + @Override + public void setProblem(InterfaceOptimizationProblem problem) { + + m_Problem = problem; + } + + @Override + public InterfaceOptimizationProblem getProblem() { + return m_Problem; + } + + @Override + public String getStringRepresentation() { + return "GradientDescentAlgorithm"; + } + + @Override + public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { + this.m_Listener = ea; + } + + @Override + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } + + public static void main(String[] args) { + GradientDescentAlgorithm program = new GradientDescentAlgorithm(); + InterfaceOptimizationProblem problem = new F1Problem(); + program.setProblem(problem); + program.init(); + for (int i = 0; i < 100; i++) { + program.optimize(); + System.out.println(program.getPopulation().getBestFitness()[0]); + } + double[] res = ((InterfaceDataTypeDouble) program.getPopulation().getBestIndividual()).getDoubleData(); + for (int i = 0; i < res.length; i++) { + System.out.print(res[i] + " "); + } + } + + public static String globalInfo() { + return "Gradient Descent can be applied to derivable functions (" + InterfaceFirstOrderDerivableProblem.class.getSimpleName() + ")."; + } //////////////// for global adaption - public boolean isAdaptStepSizeGlobally() { - return globalStepSizeAdaption; - } - public void setAdaptStepSizeGlobally(boolean globalstepsizeadaption) { - this.globalStepSizeAdaption = globalstepsizeadaption; - if (globalstepsizeadaption && localStepSizeAdaption) { - setAdaptStepSizeLocally(false); - } - } - public String adaptStepSizeGloballyTipText() { - return "Use a single step size per individual - (priority over local step size)."; - } - - public double getGlobalMaxStepSize() { - return globalmaxstepsize; - } - public void setGlobalMaxStepSize(double p) { - globalmaxstepsize = p; - } - public String globalMaxStepSizeTipText() { - return "Maximum step size for global adaption."; - } - public double getGlobalMinStepSize() { - return globalminstepsize; - } - public void setGlobalMinStepSize(double p) { - globalminstepsize = p; - } - public String globalMindStepSizeTipText() { - return "Minimum step size for global adaption."; - } - - public double getGlobalInitStepSize() { - return globalinitstepsize; - } - public void setGlobalInitStepSize(double initstepsize) { - this.globalinitstepsize = initstepsize; - } - public String globalInitStepSizeTipText() { - return "Initial step size for global adaption."; - } + public boolean isAdaptStepSizeGlobally() { + return globalStepSizeAdaption; + } - //////////////// for local adaption - public boolean isAdaptStepSizeLocally() { - return localStepSizeAdaption; - } - public void setAdaptStepSizeLocally(boolean stepsizeadaption) { - this.localStepSizeAdaption = stepsizeadaption; - if (globalStepSizeAdaption && localStepSizeAdaption) { - setAdaptStepSizeGlobally(false); - } - } - public String adaptStepSizeLocallyTipText() { - return "Use a step size parameter in any dimension."; - } + public void setAdaptStepSizeGlobally(boolean globalstepsizeadaption) { + this.globalStepSizeAdaption = globalstepsizeadaption; + if (globalstepsizeadaption && localStepSizeAdaption) { + setAdaptStepSizeLocally(false); + } + } + + public String adaptStepSizeGloballyTipText() { + return "Use a single step size per individual - (priority over local step size)."; + } + + public double getGlobalMaxStepSize() { + return globalmaxstepsize; + } + + public void setGlobalMaxStepSize(double p) { + globalmaxstepsize = p; + } + + public String globalMaxStepSizeTipText() { + return "Maximum step size for global adaption."; + } + + public double getGlobalMinStepSize() { + return globalminstepsize; + } + + public void setGlobalMinStepSize(double p) { + globalminstepsize = p; + } + + public String globalMindStepSizeTipText() { + return "Minimum step size for global adaption."; + } + + public double getGlobalInitStepSize() { + return globalinitstepsize; + } + + public void setGlobalInitStepSize(double initstepsize) { + this.globalinitstepsize = initstepsize; + } + + public String globalInitStepSizeTipText() { + return "Initial step size for global adaption."; + } + + //////////////// for local adaption + public boolean isAdaptStepSizeLocally() { + return localStepSizeAdaption; + } + + public void setAdaptStepSizeLocally(boolean stepsizeadaption) { + this.localStepSizeAdaption = stepsizeadaption; + if (globalStepSizeAdaption && localStepSizeAdaption) { + setAdaptStepSizeGlobally(false); + } + } + + public String adaptStepSizeLocallyTipText() { + return "Use a step size parameter in any dimension."; + } + + public double getLocalMinStepSize() { + return localminstepsize; + } + + public void setLocalMinStepSize(double localminstepsize) { + this.localminstepsize = localminstepsize; + } + + public double getLocalMaxStepSize() { + return localmaxstepsize; + } + + public void setLocalMaxStepSize(double localmaxstepsize) { + this.localmaxstepsize = localmaxstepsize; + } + + public void setStepSizeIncreaseFact(double nplus) { + this.wIncreaseStepSize = nplus; + } + + public double getStepSizeIncreaseFact() { + return wIncreaseStepSize; + } + + public String stepSizeIncreaseFactTipText() { + return "Factor for increasing the step size in adaption."; + } + + public void setStepSizeDecreaseFact(double nminus) { + this.wDecreaseStepSize = nminus; + } + + public double getStepSizeDecreaseFact() { + return wDecreaseStepSize; + } + + public String stepSizeDecreaseFactTipText() { + return "Factor for decreasing the step size in adaption."; + } - public double getLocalMinStepSize() { - return localminstepsize; - } - public void setLocalMinStepSize(double localminstepsize) { - this.localminstepsize = localminstepsize; - } - - public double getLocalMaxStepSize() { - return localmaxstepsize; - } - public void setLocalMaxStepSize(double localmaxstepsize) { - this.localmaxstepsize = localmaxstepsize; - } - - public void setStepSizeIncreaseFact(double nplus) { - this.wIncreaseStepSize = nplus; - } - public double getStepSizeIncreaseFact() { - return wIncreaseStepSize; - } - public String stepSizeIncreaseFactTipText() { - return "Factor for increasing the step size in adaption."; - } - - public void setStepSizeDecreaseFact(double nminus) { - this.wDecreaseStepSize = nminus; - } - public double getStepSizeDecreaseFact() { - return wDecreaseStepSize; - } - public String stepSizeDecreaseFactTipText() { - return "Factor for decreasing the step size in adaption."; - } - //////////////// concerning recovery - public boolean isRecovery() { - return recovery; - } - public void setRecovery(boolean recovery) { - this.recovery = recovery; - } - public int getRecoveryLocksteps() { - return recoverylocksteps; - } - public void setRecoveryLocksteps(int locksteps) { - this.recoverylocksteps = locksteps; - } - public double getRecoveryThreshold() { - return recoverythreshold; - } - public void setRecoveryThreshold(double recoverythreshold) { - this.recoverythreshold = recoverythreshold; - } - public String recoveryThresholdTipText() { - return "If the fitness exceeds this threshold, an unstable area is assumed and one step recovered."; - } + public boolean isRecovery() { + return recovery; + } - - public int getIterations() { - return iterations; - } - public void setIterations(int iterations) { - this.iterations = iterations; - } - public String iterationsTipText() { - return "The number of GD-iterations per generation."; - } + public void setRecovery(boolean recovery) { + this.recovery = recovery; + } - - public boolean isManhattan() { - return manhattan; - } - public void setManhattan(boolean manhattan) { - this.manhattan = manhattan; - } + public int getRecoveryLocksteps() { + return recoverylocksteps; + } - public boolean isMomentumTerm() { - return momentumterm; - } - public void setMomentumTerm(boolean momentum) { - this.momentumterm = momentum; - } - - public double getMomentumWeigth() { - return momentumweigth; - } - public void setMomentumWeigth(double momentumweigth) { - this.momentumweigth = momentumweigth; - } + public void setRecoveryLocksteps(int locksteps) { + this.recoverylocksteps = locksteps; + } - public double getMaximumAbsoluteChange() { - return maximumabsolutechange; - } - public void setMaximumAbsoluteChange(double maximumabsolutechange) { - this.maximumabsolutechange = maximumabsolutechange; - } - public String maximumAbsoluteChangeTipText() { - return "The maximum change along a coordinate in one step."; - } + public double getRecoveryThreshold() { + return recoverythreshold; + } + public void setRecoveryThreshold(double recoverythreshold) { + this.recoverythreshold = recoverythreshold; + } + + public String recoveryThresholdTipText() { + return "If the fitness exceeds this threshold, an unstable area is assumed and one step recovered."; + } + + public int getIterations() { + return iterations; + } + + public void setIterations(int iterations) { + this.iterations = iterations; + } + + public String iterationsTipText() { + return "The number of GD-iterations per generation."; + } + + public boolean isManhattan() { + return manhattan; + } + + public void setManhattan(boolean manhattan) { + this.manhattan = manhattan; + } + + public boolean isMomentumTerm() { + return momentumterm; + } + + public void setMomentumTerm(boolean momentum) { + this.momentumterm = momentum; + } + + public double getMomentumWeigth() { + return momentumweigth; + } + + public void setMomentumWeigth(double momentumweigth) { + this.momentumweigth = momentumweigth; + } + + public double getMaximumAbsoluteChange() { + return maximumabsolutechange; + } + + public void setMaximumAbsoluteChange(double maximumabsolutechange) { + this.maximumabsolutechange = maximumabsolutechange; + } + + public String maximumAbsoluteChangeTipText() { + return "The maximum change along a coordinate in one step."; + } } diff --git a/src/eva2/server/go/strategies/HillClimbing.java b/src/eva2/server/go/strategies/HillClimbing.java index 69d5cef4..4d9253be 100644 --- a/src/eva2/server/go/strategies/HillClimbing.java +++ b/src/eva2/server/go/strategies/HillClimbing.java @@ -9,40 +9,38 @@ import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; - -/** This is a Multi-Start Hill-Climber, here the population size gives the number of - * multi-starts. Similar to the evolutionary programming strategy this strategy sets the - * mutation rate temporarily to 1.0. - * Copyright: Copyright (c) 2003 - * Company: University of Tuebingen, Computer Architecture - * @author Felix Streichert - * @version: $Revision: 307 $ - * $Date: 2007-12-04 14:31:47 +0100 (Tue, 04 Dec 2007) $ - * $Author: mkron $ +/** + * This is a Multi-Start Hill-Climber, here the population size gives the number + * of multi-starts. Similar to the evolutionary programming strategy this + * strategy sets the mutation rate temporarily to 1.0. Copyright: Copyright (c) + * 2003 Company: University of Tuebingen, Computer Architecture + * + * @author Felix Streichert + * @version: $Revision: 307 $ $Date: 2007-12-04 14:31:47 +0100 (Tue, 04 Dec + * 2007) $ $Author: mkron $ */ - public class HillClimbing implements InterfaceOptimizer, java.io.Serializable { // These variables are necessary for the simple testcase - private InterfaceOptimizationProblem m_Problem = new B1Problem(); - private InterfaceMutation mutator = null; + + private InterfaceOptimizationProblem m_Problem = new B1Problem(); + private InterfaceMutation mutator = null; // private int m_MultiRuns = 100; // private int m_FitnessCalls = 100; // private int m_FitnessCallsNeeded = 0; // GAIndividualBinaryData m_Best, m_Test; - // These variables are necessary for the more complex LectureGUI enviroment - transient private String m_Identifier = ""; - transient private InterfacePopulationChangedEventListener m_Listener; - private Population m_Population; + transient private String m_Identifier = ""; + transient private InterfacePopulationChangedEventListener m_Listener; + private Population m_Population; public HillClimbing() { this.m_Population = new Population(); this.m_Population.setTargetSize(10); } - + public HillClimbing(HillClimbing a) { - this.m_Population = (Population)a.m_Population.clone(); - this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone(); + this.m_Population = (Population) a.m_Population.clone(); + this.m_Problem = (InterfaceOptimizationProblem) a.m_Problem.clone(); } @Override @@ -50,7 +48,8 @@ public class HillClimbing implements InterfaceOptimizer, java.io.Serializable { return (Object) new HillClimbing(this); } - /** This method will init the HillClimber + /** + * This method will init the HillClimber */ @Override public void init() { @@ -61,43 +60,43 @@ public class HillClimbing implements InterfaceOptimizer, java.io.Serializable { @Override public void initByPopulation(Population pop, boolean reset) { - this.m_Population = (Population)pop.clone(); + this.m_Population = (Population) pop.clone(); if (reset) { - this.m_Population.init(); + this.m_Population.init(); this.m_Problem.evaluate(this.m_Population); this.firePropertyChangedEvent(Population.nextGenerationPerformed); } } - /** This method will optimize + /** + * This method will optimize */ @Override public void optimize() { - AbstractEAIndividual indy; - Population original = (Population)this.m_Population.clone(); + AbstractEAIndividual indy; + Population original = (Population) this.m_Population.clone(); double tmpD; InterfaceMutation tmpMut; - + for (int i = 0; i < this.m_Population.size(); i++) { indy = ((AbstractEAIndividual) this.m_Population.get(i)); tmpD = indy.getMutationProbability(); indy.setMutationProbability(1.0); if (mutator == null) { indy.mutate(); - } - else { + } else { mutator.mutate(indy); } - indy.setMutationProbability(tmpD); + indy.setMutationProbability(tmpD); } this.m_Problem.evaluate(this.m_Population); for (int i = 0; i < this.m_Population.size(); i++) { - if (((AbstractEAIndividual)original.get(i)).isDominatingDebConstraints(((AbstractEAIndividual)this.m_Population.get(i)))) { + if (((AbstractEAIndividual) original.get(i)).isDominatingDebConstraints(((AbstractEAIndividual) this.m_Population.get(i)))) { // this.m_Population.remove(i); // throw away mutated one and replace by old one this.m_Population.set(i, original.get(i)); } else { - // else: mutation improved the individual, so leave the new one + // else: mutation improved the individual, so leave the new one } } this.m_Population.incrGeneration(); @@ -119,28 +118,32 @@ public class HillClimbing implements InterfaceOptimizer, java.io.Serializable { } public InterfaceMutation getMutationOperator() { - return mutator; + return mutator; } - + /** - * Allows to set a desired mutator by hand, which is used instead of the one in the individuals. - * Set it to null to use the one in the individuals, which is the default. - * + * Allows to set a desired mutator by hand, which is used instead of the one + * in the individuals. Set it to null to use the one in the individuals, + * which is the default. + * * @param mute */ public void SetMutationOperator(InterfaceMutation mute) { - mutator = mute; + mutator = mute; } - - /** This method will set the problem that is to be optimized + + /** + * This method will set the problem that is to be optimized + * * @param problem */ @Override - public void setProblem (InterfaceOptimizationProblem problem) { + public void setProblem(InterfaceOptimizationProblem problem) { this.m_Problem = problem; } + @Override - public InterfaceOptimizationProblem getProblem () { + public InterfaceOptimizationProblem getProblem() { return this.m_Problem; } @@ -163,7 +166,6 @@ public class HillClimbing implements InterfaceOptimizer, java.io.Serializable { // if (this.m_Best.defaultEvaulateAsMiniBits() == 0) i = this.m_FitnessCalls +1; // } // } - // /** This main method will start a simple hillclimber. // * No arguments necessary. // * @param args @@ -181,34 +183,40 @@ public class HillClimbing implements InterfaceOptimizer, java.io.Serializable { // TmpMeanFitness = TmpMeanFitness/program.m_MultiRuns; // System.out.println("("+program.m_MultiRuns+"/"+program.m_FitnessCalls+") Mean Fitness : " + TmpMeanFitness + " Mean Calls needed: " + TmpMeanCalls); // } - - /** This method allows you to add the LectureGUI as listener to the Optimizer + /** + * This method allows you to add the LectureGUI as listener to the Optimizer + * * @param ea */ @Override public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { this.m_Listener = ea; } + @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - /** Something has changed + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } + + /** + * Something has changed */ - protected void firePropertyChangedEvent (String name) { + protected void firePropertyChangedEvent(String name) { if (this.m_Listener != null) { this.m_Listener.registerPopulationStateChanged(this, name); } } - /** This method will return a string describing all properties of the optimizer - * and the applied methods. + /** + * This method will return a string describing all properties of the + * optimizer and the applied methods. + * * @return A descriptive string */ @Override @@ -216,63 +224,68 @@ public class HillClimbing implements InterfaceOptimizer, java.io.Serializable { String result = ""; if (this.m_Population.size() > 1) { result += "Multi(" + this.m_Population.size() + ")-Start Hill Climbing:\n"; - } - else { + } else { result += "Hill Climbing:\n"; } result += "Optimization Problem: "; - result += this.m_Problem.getStringRepresentationForProblem(this) +"\n"; + result += this.m_Problem.getStringRepresentationForProblem(this) + "\n"; result += this.m_Population.getStringRepresentation(); return result; } - /** This method allows you to set an identifier for the algorithm - * @param name The indenifier + + /** + * This method allows you to set an identifier for the algorithm + * + * @param name The indenifier */ @Override - public void setIdentifier(String name) { + public void setIdentifier(String name) { this.m_Identifier = name; } - @Override - public String getIdentifier() { - return this.m_Identifier; - } - /** This method is required to free the memory on a RMIServer, - * but there is nothing to implement. + @Override + public String getIdentifier() { + return this.m_Identifier; + } + + /** + * ******************************************************************************************************************** + * These are for GUI */ - @Override - public void freeWilly() { - - } -/********************************************************************************************************************** - * These are for GUI - */ - /** This method returns a global info string + /** + * This method returns a global info string + * * @return description */ public static String globalInfo() { return "The Hill Climber uses the default EA mutation and initializing operators. If the population size is bigger than one a multi-start Hill Climber is performed."; } - /** This method will return a naming String + + /** + * This method will return a naming String + * * @return The name of the algorithm */ @Override public String getName() { - return "MS-HC"+getIdentifier(); + return "MS-HC" + getIdentifier(); } + @Override public Population getPopulation() { return this.m_Population; } + @Override - public void setPopulation(Population pop){ + public void setPopulation(Population pop) { this.m_Population = pop; } - + @Override public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(getPopulation()); + return new SolutionSet(getPopulation()); } + public String populationTipText() { return "Change the number of best individuals stored (MS-HC)."; } diff --git a/src/eva2/server/go/strategies/InterfaceOptimizer.java b/src/eva2/server/go/strategies/InterfaceOptimizer.java index 1939eb23..6a33cba0 100644 --- a/src/eva2/server/go/strategies/InterfaceOptimizer.java +++ b/src/eva2/server/go/strategies/InterfaceOptimizer.java @@ -22,29 +22,29 @@ public interface InterfaceOptimizer { /** This method will return deep clone of the optimizer * @return The clone */ - public Object clone(); + Object clone(); /** This method will return a naming String * @return The name of the algorithm */ - public String getName(); + String getName(); /** * This method allows you to add a listener to the Optimizer. * @param ea */ - public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea); + void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea); /** * This method removes a listener from the Optimizer. It returns true on success, * false if the listener could not be found. * @param ea */ - public boolean removePopulationChangedEventListener(InterfacePopulationChangedEventListener ea); + boolean removePopulationChangedEventListener(InterfacePopulationChangedEventListener ea); /** This method will init the optimizer */ - public void init(); + void init(); /** * This method will init the optimizer with a given population. @@ -52,22 +52,22 @@ public interface InterfaceOptimizer { * @param pop The initial population * @param reset If true the population is reinitialized and reevaluated. */ - public void initByPopulation(Population pop, boolean reset); + void initByPopulation(Population pop, boolean reset); /** This method will optimize for a single iteration, after this step * the population should be as big as possible (ie. the size of lambda * and not mu) and all individual should be evaluated. This allows more * usefull statistics on the population. */ - public void optimize(); + void optimize(); /** Assuming that all optimizer will store their data in a population * we will allow access to this population to query to current state * of the optimizer. * @return The population of current solutions to a given problem. */ - public Population getPopulation(); - public void setPopulation(Population pop); + Population getPopulation(); + void setPopulation(Population pop); /** * Return all found solutions (local optima) if they are not contained in the current population. Be @@ -78,14 +78,14 @@ public interface InterfaceOptimizer { * * @return A solution set of the current population and possibly earlier solutions. */ - public InterfaceSolutionSet getAllSolutions(); + InterfaceSolutionSet getAllSolutions(); /** * This method allows you to set an identifier for the algorithm * @param name The identifier */ - public void setIdentifier(String name); - public String getIdentifier(); + void setIdentifier(String name); + String getIdentifier(); /** * This method will set the problem that is to be optimized. The problem @@ -93,17 +93,12 @@ public interface InterfaceOptimizer { * * @param problem */ - public void setProblem (InterfaceOptimizationProblem problem); - public InterfaceOptimizationProblem getProblem (); + void setProblem (InterfaceOptimizationProblem problem); + InterfaceOptimizationProblem getProblem (); /** This method will return a string describing all properties of the optimizer * and the applied methods. * @return A descriptive string */ - public String getStringRepresentation(); - - /** This method is required to free the memory on a RMIServer, - * but there is nothing to implement. - */ - public void freeWilly(); + String getStringRepresentation(); } diff --git a/src/eva2/server/go/strategies/IslandModelEA.java b/src/eva2/server/go/strategies/IslandModelEA.java index 35f0cbcb..d1ebbf1f 100644 --- a/src/eva2/server/go/strategies/IslandModelEA.java +++ b/src/eva2/server/go/strategies/IslandModelEA.java @@ -17,64 +17,59 @@ import eva2.server.go.problems.F8Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; import eva2.server.go.problems.TF1Problem; -/** The one and only island model for parallelization. Since parallelization based - * on the RMIProxyRemoteThread is on the one hand much slower than benchmark function - * evaluation and on the other hand the GUI based distribution scheme is rather prone - * to config errors (the correct ssh version is required, the jar needs to be in - * the working dir and possible problem data must be on the servers to) an implicit - * island-model has been implemented too to allow fast and reliable computation. - * This is still usefull, since it is less prone to premature convergence and also - * an heterogenuous island model can be used. - * - * A population of the same size is sent to all nodes and evaluated there independently - * for a cycle (more precisely: for MigrationRate generations) after which a communication - * step is performed according to the migration model. Only after migration is a main - * cycle complete, the statistics updated etc. - * - * Created by IntelliJ IDEA. - * User: streiche - * Date: 12.09.2004 - * Time: 14:48:20 - * To change this template use File | Settings | File Templates. +/** + * The one and only island model for parallelization. Since parallelization + * based on the RMIProxyRemoteThread is on the one hand much slower than + * benchmark function evaluation and on the other hand the GUI based + * distribution scheme is rather prone to config errors (the correct ssh version + * is required, the jar needs to be in the working dir and possible problem data + * must be on the servers to) an implicit island-model has been implemented too + * to allow fast and reliable computation. This is still usefull, since it is + * less prone to premature convergence and also an heterogenuous island model + * can be used. + * + * A population of the same size is sent to all nodes and evaluated there + * independently for a cycle (more precisely: for MigrationRate generations) + * after which a communication step is performed according to the migration + * model. Only after migration is a main cycle complete, the statistics updated + * etc. + * + * Created by IntelliJ IDEA. User: streiche Date: 12.09.2004 Time: 14:48:20 To + * change this template use File | Settings | File Templates. */ - public class IslandModelEA implements InterfacePopulationChangedEventListener, InterfaceOptimizer, java.io.Serializable { - private Population m_Population = new Population(); - private InterfaceOptimizer m_Optimizer = new GeneticAlgorithm(); - private InterfaceMigration m_Migration = new SOBestMigration(); - private InterfaceOptimizationProblem m_Problem = new F8Problem(); + private Population m_Population = new Population(); + private InterfaceOptimizer m_Optimizer = new GeneticAlgorithm(); + private InterfaceMigration m_Migration = new SOBestMigration(); + private InterfaceOptimizationProblem m_Problem = new F8Problem(); // private String[] m_NodesList; - private int m_MigrationRate = 10; - private boolean m_HeterogenuousProblems = false; - + private int m_MigrationRate = 10; + private boolean m_HeterogenuousProblems = false; // These are the processor to run on - private int m_numLocalCPUs = 1; - private boolean m_localOnly = false; - transient private InterfaceOptimizer[] m_Islands; - + private int m_numLocalCPUs = 1; + private boolean m_localOnly = false; + transient private InterfaceOptimizer[] m_Islands; // This is for debugging - private boolean m_LogLocalChanges = true; - private boolean m_Show = false; - transient private Plot m_Plot = null; - - transient private String m_Identifier = ""; - transient private InterfacePopulationChangedEventListener m_Listener; - transient private final boolean TRACE = false; - + private boolean m_LogLocalChanges = true; + private boolean m_Show = false; + transient private Plot m_Plot = null; + transient private String m_Identifier = ""; + transient private InterfacePopulationChangedEventListener m_Listener; + transient private final boolean TRACE = false; public IslandModelEA() { } public IslandModelEA(IslandModelEA a) { - this.m_Population = (Population)a.m_Population.clone(); - this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone(); - this.m_Optimizer = (InterfaceOptimizer)a.m_Optimizer.clone(); - this.m_Migration = (InterfaceMigration)a.m_Migration.clone(); - this.m_MigrationRate = a.m_MigrationRate; - this.m_HeterogenuousProblems = a.m_HeterogenuousProblems; - this.m_numLocalCPUs = a.m_numLocalCPUs; - this.m_localOnly = a.m_localOnly; + this.m_Population = (Population) a.m_Population.clone(); + this.m_Problem = (InterfaceOptimizationProblem) a.m_Problem.clone(); + this.m_Optimizer = (InterfaceOptimizer) a.m_Optimizer.clone(); + this.m_Migration = (InterfaceMigration) a.m_Migration.clone(); + this.m_MigrationRate = a.m_MigrationRate; + this.m_HeterogenuousProblems = a.m_HeterogenuousProblems; + this.m_numLocalCPUs = a.m_numLocalCPUs; + this.m_localOnly = a.m_localOnly; } @Override @@ -98,14 +93,14 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I this.m_Population.init(); this.m_Optimizer.init(); this.m_Optimizer.setProblem(this.m_Problem); - this.m_Optimizer.setPopulation((Population)m_Population.clone()); + this.m_Optimizer.setPopulation((Population) m_Population.clone()); InterfacePopulationChangedEventListener myLocal = null; if (this.m_localOnly) { // this is running on the local machine this.m_Islands = new InterfaceOptimizer[this.m_numLocalCPUs]; for (int i = 0; i < this.m_numLocalCPUs; i++) { this.m_Islands[i] = (InterfaceOptimizer) this.m_Optimizer.clone(); - this.m_Islands[i].setIdentifier(""+i); + this.m_Islands[i].setIdentifier("" + i); this.m_Islands[i].init(); if (this.m_LogLocalChanges) { this.m_Islands[i].addPopulationChangedEventListener(this); @@ -115,49 +110,51 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I // this is running on remote machines // ToDo: Parallelize with Threads?!? /*if (this.m_LocalServer == null) { - this.m_LocalServer = RMIServer.getInstance(); - } - try { - myLocal = (InterfacePopulationChangedEventListener) RMIProxyLocal.newInstance(this); - } catch(Exception e) { - System.err.println("Island Model EA warning on local RMIServer... but i'll start anyway!"); - } - String[] nodesList = this.m_Servers.getCheckedServerNodes(); - if ((nodesList == null) || (nodesList.length == 0)) { - throw new RuntimeException("Error, no active remote servers available! Activate servers or use localOnly mode."); - } - this.m_Islands = new InterfaceOptimizer[nodesList.length]; - for (int i = 0; i < nodesList.length; i++) { - this.m_Islands[i] = (InterfaceOptimizer) RMIProxyRemoteThread.newInstance(this.m_Optimizer, nodesList[i]); - this.m_Islands[i].setIdentifier(""+i); - this.m_Islands[i].init(); - if (this.m_LogLocalChanges) { - this.m_Islands[i].addPopulationChangedEventListener(myLocal); - } - }*/ + this.m_LocalServer = RMIServer.getInstance(); + } + try { + myLocal = (InterfacePopulationChangedEventListener) RMIProxyLocal.newInstance(this); + } catch(Exception e) { + System.err.println("Island Model EA warning on local RMIServer... but i'll start anyway!"); + } + String[] nodesList = this.m_Servers.getCheckedServerNodes(); + if ((nodesList == null) || (nodesList.length == 0)) { + throw new RuntimeException("Error, no active remote servers available! Activate servers or use localOnly mode."); + } + this.m_Islands = new InterfaceOptimizer[nodesList.length]; + for (int i = 0; i < nodesList.length; i++) { + this.m_Islands[i] = (InterfaceOptimizer) RMIProxyRemoteThread.newInstance(this.m_Optimizer, nodesList[i]); + this.m_Islands[i].setIdentifier(""+i); + this.m_Islands[i].init(); + if (this.m_LogLocalChanges) { + this.m_Islands[i].addPopulationChangedEventListener(myLocal); + } + }*/ } this.m_Migration.initMigration(this.m_Islands); Population pop; - this.m_Population.incrGeneration(); // the island-initialization has increased the island-pop generations. + this.m_Population.incrGeneration(); // the island-initialization has increased the island-pop generations. for (int i = 0; i < this.m_Islands.length; i++) { - pop = (Population)this.m_Islands[i].getPopulation().clone(); + pop = (Population) this.m_Islands[i].getPopulation().clone(); this.m_Population.addPopulation(pop); this.m_Population.incrFunctionCallsBy(pop.getFunctionCalls()); - if (m_Islands[i].getPopulation().getGeneration()!=m_Population.getGeneration()) { - System.err.println("Error, inconsistent generations!"); + if (m_Islands[i].getPopulation().getGeneration() != m_Population.getGeneration()) { + System.err.println("Error, inconsistent generations!"); } } this.firePropertyChangedEvent(Population.nextGenerationPerformed, this.m_Optimizer.getPopulation()); } - /** This method will init the optimizer with a given population - * @param reset If true the population is reset. + /** + * This method will init the optimizer with a given population + * + * @param reset If true the population is reset. */ @Override public void initByPopulation(Population tpop, boolean reset) { - // TODO this is again evil copy&paste style + // TODO this is again evil copy&paste style if (this.m_Show) { if (this.m_Plot == null) { double[] tmpD = new double[2]; @@ -167,9 +164,9 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I } } - this.m_Population = (Population)tpop.clone(); + this.m_Population = (Population) tpop.clone(); if (reset) { - this.m_Population.init(); + this.m_Population.init(); this.m_Population.incrGeneration(); } this.m_Optimizer.init(); @@ -180,7 +177,7 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I this.m_Islands = new InterfaceOptimizer[this.m_numLocalCPUs]; for (int i = 0; i < this.m_numLocalCPUs; i++) { this.m_Islands[i] = (InterfaceOptimizer) this.m_Optimizer.clone(); - this.m_Islands[i].setIdentifier(""+i); + this.m_Islands[i].setIdentifier("" + i); this.m_Islands[i].init(); if (this.m_LogLocalChanges) { this.m_Islands[i].addPopulationChangedEventListener(this); @@ -190,47 +187,48 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I // this is running on remote machines // ToDo: Parallellize with threads?!? /* - if (this.m_LocalServer == null) { - this.m_LocalServer = RMIServer.getInstance(); - } - try { - myLocal = (InterfacePopulationChangedEventListener) RMIProxyLocal.newInstance(this); - } catch(Exception e) { - System.err.println("Island Model EA warning on local RMIServer... but i'll try to start anyway!"); - } - String[] nodesList = this.m_Servers.getCheckedServerNodes(); - if ((nodesList == null) || (nodesList.length == 0)) { - return; - } - this.m_Islands = new InterfaceOptimizer[nodesList.length]; - for (int i = 0; i < nodesList.length; i++) { - this.m_Islands[i] = (InterfaceOptimizer) RMIProxyRemoteThread.newInstance(this.m_Optimizer, nodesList[i]); - this.m_Islands[i].setIdentifier(""+i); - this.m_Islands[i].init(); - if (this.m_LogLocalChanges) { - this.m_Islands[i].addPopulationChangedEventListener(myLocal); - } - }*/ + if (this.m_LocalServer == null) { + this.m_LocalServer = RMIServer.getInstance(); + } + try { + myLocal = (InterfacePopulationChangedEventListener) RMIProxyLocal.newInstance(this); + } catch(Exception e) { + System.err.println("Island Model EA warning on local RMIServer... but i'll try to start anyway!"); + } + String[] nodesList = this.m_Servers.getCheckedServerNodes(); + if ((nodesList == null) || (nodesList.length == 0)) { + return; + } + this.m_Islands = new InterfaceOptimizer[nodesList.length]; + for (int i = 0; i < nodesList.length; i++) { + this.m_Islands[i] = (InterfaceOptimizer) RMIProxyRemoteThread.newInstance(this.m_Optimizer, nodesList[i]); + this.m_Islands[i].setIdentifier(""+i); + this.m_Islands[i].init(); + if (this.m_LogLocalChanges) { + this.m_Islands[i].addPopulationChangedEventListener(myLocal); + } + }*/ } this.m_Migration.initMigration(this.m_Islands); Population pop; for (int i = 0; i < this.m_Islands.length; i++) { - pop = (Population)this.m_Islands[i].getPopulation().clone(); + pop = (Population) this.m_Islands[i].getPopulation().clone(); this.m_Population.addPopulation(pop); this.m_Population.incrFunctionCallsBy(pop.getFunctionCalls()); } this.firePropertyChangedEvent(Population.nextGenerationPerformed, this.m_Optimizer.getPopulation()); } - /** The optimize method will compute an 'improved' and evaluated population + /** + * The optimize method will compute an 'improved' and evaluated population */ @Override public void optimize() { for (int i = 0; i < this.m_Islands.length; i++) { if (this.m_Islands[i].getPopulation().size() > 0) { - this.m_Islands[i].optimize(); - if (TRACE ) { + this.m_Islands[i].optimize(); + if (TRACE) { System.out.println(BeanInspector.toString(m_Islands[i].getPopulation())); } } else { @@ -253,28 +251,28 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I System.gc(); } - /** This method will manage communication between the - * islands + /** + * This method will manage communication between the islands */ private void communicate() { // Here i'll have to wait until all islands are finished boolean allReachedG = false; - int G = this.m_Population.getGeneration(); + int G = this.m_Population.getGeneration(); while (!allReachedG) { allReachedG = true; String gen = "["; for (int i = 0; i < this.m_Islands.length; i++) { - gen += this.m_Islands[i].getPopulation().getGeneration()+"; "; + gen += this.m_Islands[i].getPopulation().getGeneration() + "; "; if (this.m_Islands[i].getPopulation().getGeneration() != G) { allReachedG = false; } } if (!allReachedG) { - System.out.println("Waiting...."+gen+"] ?= " + G); + System.out.println("Waiting...." + gen + "] ?= " + G); try { - Thread.sleep(1000); + Thread.sleep(1000); } catch (Exception e) { - System.err.println("Error in sleep of XThread"); + System.err.println("Error in sleep of XThread"); } } } @@ -282,7 +280,7 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I this.m_Population.setFunctionCalls(0); Population pop; for (int i = 0; i < this.m_Islands.length; i++) { - pop = (Population)this.m_Islands[i].getPopulation().clone(); + pop = (Population) this.m_Islands[i].getPopulation().clone(); this.m_Population.addPopulation(pop); this.m_Population.incrFunctionCallsBy(pop.getFunctionCalls()); } @@ -296,46 +294,56 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I this.m_Migration.migrate(this.m_Islands); } - /** This method allows you to add the LectureGUI as listener to the Optimizer + /** + * This method allows you to add the LectureGUI as listener to the Optimizer + * * @param ea */ @Override public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { this.m_Listener = ea; } + @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - /** Something has changed + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } + + /** + * Something has changed */ - protected void firePropertyChangedEvent (String name, Population population) { + protected void firePropertyChangedEvent(String name, Population population) { if (this.m_Listener != null) { this.m_Listener.registerPopulationStateChanged(this, name); } } - /** This method will set the problem that is to be optimized + /** + * This method will set the problem that is to be optimized + * * @param problem */ @Override - public void setProblem (InterfaceOptimizationProblem problem) { + public void setProblem(InterfaceOptimizationProblem problem) { this.m_Problem = problem; this.m_Optimizer.setProblem(problem); } + @Override - public InterfaceOptimizationProblem getProblem () { + public InterfaceOptimizationProblem getProblem() { return this.m_Problem; } - /** This method will return a string describing all properties of the optimizer - * and the applied methods. + /** + * This method will return a string describing all properties of the + * optimizer and the applied methods. + * * @return A descriptive string */ @Override @@ -350,11 +358,11 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I if (this.m_HeterogenuousProblems) { result += " Heterogenuous Optimizers: \n"; for (int i = 0; i < this.m_Islands.length; i++) { - result += this.m_Islands[i].getStringRepresentation() +"\n"; + result += this.m_Islands[i].getStringRepresentation() + "\n"; } } else { result += " Homogeneous Optimizer = " + this.m_Optimizer.getClass().toString() + "\n"; - result += this.m_Optimizer.getStringRepresentation() +"\n"; + result += this.m_Optimizer.getStringRepresentation() + "\n"; } //result += "=> The Optimization Problem: "; //result += this.m_Problem.getStringRepresentationForProblem(this) +"\n"; @@ -362,22 +370,23 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I return result; } - /** This method is to test the parallelization scheme + /** + * This method is to test the parallelization scheme * * @param args */ public static void main(String[] args) { // @todo die ServerStarter muss ich noch hin kriegen // @todo Wichtig ich brauche den eva2.tools.jproxy.RMIServer! - IslandModelEA imea = new IslandModelEA(); + IslandModelEA imea = new IslandModelEA(); imea.m_Show = true; imea.m_localOnly = false; if (false) { - imea.m_Optimizer = new MultiObjectiveEA(); - ((MultiObjectiveEA)imea.m_Optimizer).setArchiveSize(25); - ((MultiObjectiveEA)imea.m_Optimizer).getPopulation().setTargetSize(50); - imea.m_Problem = new TF1Problem(); - ((TF1Problem)imea.m_Problem).setEAIndividual(new ESIndividualDoubleData()); + imea.m_Optimizer = new MultiObjectiveEA(); + ((MultiObjectiveEA) imea.m_Optimizer).setArchiveSize(25); + ((MultiObjectiveEA) imea.m_Optimizer).getPopulation().setTargetSize(50); + imea.m_Problem = new TF1Problem(); + ((TF1Problem) imea.m_Problem).setEAIndividual(new ESIndividualDoubleData()); // ((TF1Problem)imea.m_Problem).setEAIndividual(new ESIndividualDoubleData()); // imea.m_Problem = new TFPortfolioSelectionProblem(); // ((TFPortfolioSelectionProblem)imea.m_Problem).setEAIndividual(new ESIndividualDoubleData()); @@ -386,7 +395,7 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I c.getKMeans().setUseSearchSpace(false); c.setUseConstraints(true); c.m_Debug = true; - imea.m_Migration = c; + imea.m_Migration = c; } if (false) { MOConeSeparation c = new MOConeSeparation(); @@ -395,11 +404,11 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I imea.m_Migration = c; } if (true) { - imea.m_Migration = new MOBestMigration(); + imea.m_Migration = new MOBestMigration(); } } else { - imea.m_Problem = new F8Problem(); - ((F1Problem)imea.m_Problem).setEAIndividual(new ESIndividualDoubleData()); + imea.m_Problem = new F8Problem(); + ((F1Problem) imea.m_Problem).setEAIndividual(new ESIndividualDoubleData()); } imea.m_MigrationRate = 15; imea.init(); @@ -410,75 +419,82 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I //System.exit(0); } - /** This method allows you to set an identifier for the algorithm - * @param name The indenifier + /** + * This method allows you to set an identifier for the algorithm + * + * @param name The indenifier */ @Override - public void setIdentifier(String name) { + public void setIdentifier(String name) { this.m_Identifier = name; } - @Override - public String getIdentifier() { - return this.m_Identifier; - } - /** This method will return the Optimizers + @Override + public String getIdentifier() { + return this.m_Identifier; + } + + /** + * This method will return the Optimizers + * * @return An array of optimizers */ public InterfaceOptimizer[] getOptimizers() { return this.m_Islands; } - /** This method will allow you to toggel between homogenuous and heterogenuous problems. - * In case of heterogenuous problems the individuals need to be reevaluated after migration. + /** + * This method will allow you to toggel between homogenuous and + * heterogenuous problems. In case of heterogenuous problems the individuals + * need to be reevaluated after migration. + * * @param t */ public void setHeterogenuousProblems(boolean t) { this.m_HeterogenuousProblems = t; } - /** This method is required to free the memory on a RMIServer, - * but there is nothing to implement. + /** + * ******************************************************************************************************************** + * These are for InterfacePopulationChangedEventListener */ - @Override - public void freeWilly() { - for (int i = 0; i < this.m_Islands.length; i++) { - this.m_Islands[i].freeWilly(); - } - } - -/********************************************************************************************************************** - * These are for InterfacePopulationChangedEventListener - */ - /** This method allows an optimizer to register a change in the EA-lecture - * @param source The source of the event. - * @param name Could be used to indicate the nature of the event. + /** + * This method allows an optimizer to register a change in the EA-lecture + * + * @param source The source of the event. + * @param name Could be used to indicate the nature of the event. */ @Override public void registerPopulationStateChanged(Object source, String name) { - InterfaceOptimizer opt = (InterfaceOptimizer)source; - int sourceID = new Integer(opt.getIdentifier()).intValue(); - double cFCOpt = opt.getPopulation().getFunctionCalls(); - double plotValue = (this.m_Problem.getDoublePlotValue(opt.getPopulation())).doubleValue(); + InterfaceOptimizer opt = (InterfaceOptimizer) source; + int sourceID = new Integer(opt.getIdentifier()).intValue(); + double cFCOpt = opt.getPopulation().getFunctionCalls(); + double plotValue = (this.m_Problem.getDoublePlotValue(opt.getPopulation())).doubleValue(); if (this.m_Show) { - this.m_Plot.setConnectedPoint(cFCOpt, plotValue, (sourceID+1)); + this.m_Plot.setConnectedPoint(cFCOpt, plotValue, (sourceID + 1)); } //System.out.println("Someone has finished, ("+this.m_Generation+"/"+this.m_Performed+")"); //System.out.println(sourceID + " is at generation "+ opt.getPopulation().getGeneration() +" i'm at " +this.m_Generation); } -/********************************************************************************************************************** - * These are for GUI - */ - /** This method returns a global info string + /** + * ******************************************************************************************************************** + * These are for GUI + */ + /** + * This method returns a global info string + * * @return description */ public static String globalInfo() { return "This is an island model EA distributing the individuals across several (remote) CPUs for optimization."; } - /** This method will return a naming String + + /** + * This method will return a naming String + * * @return The name of the algorithm */ @Override @@ -486,8 +502,10 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I return "IslandEA"; } - /** This method allows you to toggle between a truly parallel - * and a serial implementation. + /** + * This method allows you to toggle between a truly parallel and a serial + * implementation. + * * @return The current optimization mode */ // TODO Deactivated from GUI because the current implementation does not really parallelize on a multicore. @@ -495,62 +513,79 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I // public boolean isLocalOnly() { // return this.m_localOnly; // } - public void setLocalOnly(boolean b){ + public void setLocalOnly(boolean b) { this.m_localOnly = b; } + public String localOnlyTipText() { return "Toggle between usage of local CPUs and remote servers."; } - /** This will show the local performance + /** + * This will show the local performance + * * @return The current optimzation mode */ public boolean getShow() { return this.m_Show; } - public void setShow(boolean b){ - this.m_Show = b; - this.m_LogLocalChanges = b; + + public void setShow(boolean b) { + this.m_Show = b; + this.m_LogLocalChanges = b; } + public String showTipText() { return "This will show the local performance."; } - /** This method allows you to set/get the optimizing technique to use. + /** + * This method allows you to set/get the optimizing technique to use. + * * @return The current optimizing method */ public InterfaceOptimizer getOptimizer() { return this.m_Optimizer; } - public void setOptimizer(InterfaceOptimizer b){ + + public void setOptimizer(InterfaceOptimizer b) { this.m_Optimizer = b; } + public String optimizerTipText() { return "Choose a population based optimizing technique to use."; } - /** This method allows you to set/get the migration strategy to use. + /** + * This method allows you to set/get the migration strategy to use. + * * @return The current migration strategy */ public InterfaceMigration getMigrationStrategy() { return this.m_Migration; } - public void setMigrationStrategy(InterfaceMigration b){ + + public void setMigrationStrategy(InterfaceMigration b) { this.m_Migration = b; } + public String migrationStrategyTipText() { return "Choose a migration strategy to use."; } - /** This method allows you to set/get the migration rate to use. + /** + * This method allows you to set/get the migration rate to use. + * * @return The current migration rate */ public int getMigrationRate() { return this.m_MigrationRate; } - public void setMigrationRate(int b){ + + public void setMigrationRate(int b) { this.m_MigrationRate = b; } + public String migrationRateTipText() { return "Set the migration rate for communication between islands."; } @@ -559,36 +594,42 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I return "Choose and manage the servers (only active in parallelized mode)."; } - /** Assuming that all optimizer will store thier data in a population - * we will allow acess to this population to query to current state - * of the optimizer. + /** + * Assuming that all optimizer will store thier data in a population we will + * allow acess to this population to query to current state of the + * optimizer. + * * @return The population of current solutions to a given problem. */ @Override public Population getPopulation() { return this.m_Population; } + @Override public void setPopulation(Population pop) { // @todo Jetzt m�sste ich die pop auch auf die Rechner verteilen... this.m_Population = pop; } + public String populationTipText() { return "(Defunct)"; } - + @Override public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(getPopulation()); + return new SolutionSet(getPopulation()); } - /** This method allows you to set the number of processors in local mode - * @param n Number of processors. + + /** + * This method allows you to set the number of processors in local mode + * + * @param n Number of processors. */ public void setNumberLocalCPUs(int n) { - if (n>=1) { + if (n >= 1) { this.m_numLocalCPUs = n; - } - else { + } else { System.err.println("Number of CPUs must be at least 1!"); } } @@ -597,6 +638,7 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I // public int getNumberLocalCPUs() { // return this.m_LocalCPUs; // } + public String numberLocalCPUsTipText() { return "Set the number of local CPUS (>=1, only used in local mode)."; } diff --git a/src/eva2/server/go/strategies/LTGA.java b/src/eva2/server/go/strategies/LTGA.java index 3e1ce14f..867acc29 100644 --- a/src/eva2/server/go/strategies/LTGA.java +++ b/src/eva2/server/go/strategies/LTGA.java @@ -364,10 +364,6 @@ public class LTGA implements InterfaceOptimizer, java.io.Serializable, Interface return "Linkage Tree GA"; } - @Override - public void freeWilly() { - } - @Override public void registerPopulationStateChanged(Object source, String name) { // The events of the interim hill climbing population will be caught here diff --git a/src/eva2/server/go/strategies/MLTGA.java b/src/eva2/server/go/strategies/MLTGA.java index a0e357bf..397899d5 100644 --- a/src/eva2/server/go/strategies/MLTGA.java +++ b/src/eva2/server/go/strategies/MLTGA.java @@ -246,13 +246,13 @@ public class MLTGA implements InterfaceOptimizer, java.io.Serializable, Interfac this.problem.evaluatePopulationStart(this.population); Stack> linkageTree = buildLinkageTree(); Population newPop = new Population(this.popSize); - if(elitism){ + if (elitism) { AbstractEAIndividual firstIndy = this.population.getBestEAIndividual(); AbstractEAIndividual firstNewIndy = buildNewIndy(firstIndy, linkageTree); newPop.add(firstNewIndy); } for (int i = 0; i < this.popSize; i++) { - if(this.elitism && i==0){ + if (this.elitism && i == 0) { continue; } Population indies = this.population.getRandNIndividuals(1); @@ -265,21 +265,21 @@ public class MLTGA implements InterfaceOptimizer, java.io.Serializable, Interfac } private AbstractEAIndividual buildNewIndy(AbstractEAIndividual indy, - Stack> linkageTree) { - for (Set mask : linkageTree) { - BitSet gen = getBinaryData(indy); - BitSet newGene = (BitSet) gen.clone(); - for (Integer flipID : mask) { - newGene.flip(flipID); - } - AbstractEAIndividual newIndy = (AbstractEAIndividual) this.template.clone(); - ((InterfaceDataTypeBinary) newIndy).SetBinaryGenotype(newGene); - evaluate(newIndy); - if (newIndy.getFitness(0) < indy.getFitness(0)) { - indy = newIndy; - } - } - return indy; + Stack> linkageTree) { + for (Set mask : linkageTree) { + BitSet gen = getBinaryData(indy); + BitSet newGene = (BitSet) gen.clone(); + for (Integer flipID : mask) { + newGene.flip(flipID); + } + AbstractEAIndividual newIndy = (AbstractEAIndividual) this.template.clone(); + ((InterfaceDataTypeBinary) newIndy).SetBinaryGenotype(newGene); + evaluate(newIndy); + if (newIndy.getFitness(0) < indy.getFitness(0)) { + indy = newIndy; + } + } + return indy; } /** @@ -320,16 +320,16 @@ public class MLTGA implements InterfaceOptimizer, java.io.Serializable, Interfac public void setProblem(InterfaceOptimizationProblem problem) { this.problem = (AbstractOptimizationProblem) problem; } - - public boolean getElitism(){ + + public boolean getElitism() { return this.elitism; } - - public void setElitism(boolean b){ + + public void setElitism(boolean b) { this.elitism = b; } - - public String elitismTipText(){ + + public String elitismTipText() { return "use elitism?"; } @@ -343,10 +343,6 @@ public class MLTGA implements InterfaceOptimizer, java.io.Serializable, Interfac return "Linkage Tree GA"; } - @Override - public void freeWilly() { - } - @Override public void registerPopulationStateChanged(Object source, String name) { // The events of the interim hill climbing population will be caught here diff --git a/src/eva2/server/go/strategies/MemeticAlgorithm.java b/src/eva2/server/go/strategies/MemeticAlgorithm.java index 74c87787..4e191b83 100644 --- a/src/eva2/server/go/strategies/MemeticAlgorithm.java +++ b/src/eva2/server/go/strategies/MemeticAlgorithm.java @@ -12,421 +12,400 @@ import eva2.server.go.problems.InterfaceLocalSearchable; import eva2.server.go.problems.InterfaceOptimizationProblem; import java.util.Hashtable; - /** * A memetic algorithm by hannes planatscher. The local search strategy can only * be applied to problems which implement the InterfaceLocalSearchable else the - * local search will not be activated at all. - *

- * Title: EvA2 - *

- *

- * Description: - *

- *

- * Copyright: Copyright (c) 2003 - *

- *

- * Company: - *

+ * local search will not be activated at all.

Title: EvA2

+ * Description:

Copyright: Copyright (c) 2003

Company:

* * @author not attributable * @version 1.0 */ - public class MemeticAlgorithm implements InterfaceOptimizer, - java.io.Serializable { + java.io.Serializable { - /** - * serial version uid. - */ - private static final long serialVersionUID = -1730086430763348568L; + /** + * serial version uid. + */ + private static final long serialVersionUID = -1730086430763348568L; + private int localSearchSteps = 1; + private int subsetsize = 5; + private int globalSearchIterations = 1; + private boolean lamarckism = true; + // int counter = 0; !? + // int maxfunctioncalls = 1000; !? + private boolean TRACE = false; + private String m_Identifier = ""; + private InterfaceOptimizationProblem m_Problem = new F1Problem(); + private InterfaceOptimizer m_GlobalOptimizer = new GeneticAlgorithm(); + private InterfaceSelection selectorPlug = new SelectBestIndividuals(); + transient private InterfacePopulationChangedEventListener m_Listener; - private int localSearchSteps = 1; + public MemeticAlgorithm() { + } - private int subsetsize = 5; - - private int globalSearchIterations = 1; - - private boolean lamarckism = true; - - // int counter = 0; !? - // int maxfunctioncalls = 1000; !? - - private boolean TRACE = false; - - private String m_Identifier = ""; - - private InterfaceOptimizationProblem m_Problem = new F1Problem(); - - private InterfaceOptimizer m_GlobalOptimizer = new GeneticAlgorithm(); - - private InterfaceSelection selectorPlug = new SelectBestIndividuals(); - - transient private InterfacePopulationChangedEventListener m_Listener; - - public MemeticAlgorithm() { - - } - - public MemeticAlgorithm(MemeticAlgorithm a) { - // this.m_Population = (Population)a.m_Population.clone(); - this.m_Problem = (InterfaceLocalSearchable) a.m_Problem.clone(); - this.m_GlobalOptimizer = (InterfaceOptimizer) a.m_GlobalOptimizer; - this.selectorPlug = (InterfaceSelection) a.selectorPlug; - this.m_Identifier = a.m_Identifier; - this.localSearchSteps = a.localSearchSteps; - this.subsetsize = a.subsetsize; - this.globalSearchIterations = a.globalSearchIterations; - this.lamarckism = a.lamarckism; - } - - @Override - public Object clone() { - return new MemeticAlgorithm(this); - } + public MemeticAlgorithm(MemeticAlgorithm a) { + // this.m_Population = (Population)a.m_Population.clone(); + this.m_Problem = (InterfaceLocalSearchable) a.m_Problem.clone(); + this.m_GlobalOptimizer = (InterfaceOptimizer) a.m_GlobalOptimizer; + this.selectorPlug = (InterfaceSelection) a.selectorPlug; + this.m_Identifier = a.m_Identifier; + this.localSearchSteps = a.localSearchSteps; + this.subsetsize = a.subsetsize; + this.globalSearchIterations = a.globalSearchIterations; + this.lamarckism = a.lamarckism; + } @Override - public void initByPopulation(Population pop, boolean reset) { - this.setPopulation((Population) pop.clone()); - if (reset) { - this.getPopulation().init(); - this.m_Problem.evaluate(this.getPopulation()); - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } - } + public Object clone() { + return new MemeticAlgorithm(this); + } @Override - public void init() { - // counter = 0; - this.m_GlobalOptimizer.setProblem(this.m_Problem); - this.m_GlobalOptimizer.init(); - this.evaluatePopulation(this.m_GlobalOptimizer.getPopulation()); - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } - - /** - * This method will evaluate the current population using the given problem. - * - * @param population - * The population that is to be evaluated - */ - private void evaluatePopulation(Population population) { - this.m_Problem.evaluate(population); - population.incrGeneration(); - } + public void initByPopulation(Population pop, boolean reset) { + this.setPopulation((Population) pop.clone()); + if (reset) { + this.getPopulation().init(); + this.m_Problem.evaluate(this.getPopulation()); + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + } + } @Override - public void optimize() { + public void init() { + // counter = 0; + this.m_GlobalOptimizer.setProblem(this.m_Problem); + this.m_GlobalOptimizer.init(); + this.evaluatePopulation(this.m_GlobalOptimizer.getPopulation()); + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + } - if (TRACE) { - System.out.println("global search"); + /** + * This method will evaluate the current population using the given problem. + * + * @param population The population that is to be evaluated + */ + private void evaluatePopulation(Population population) { + this.m_Problem.evaluate(population); + population.incrGeneration(); + } + + @Override + public void optimize() { + + if (TRACE) { + System.out.println("global search"); + } + this.m_GlobalOptimizer.optimize(); + + if ((globalSearchIterations > 0) && (((this.m_GlobalOptimizer.getPopulation().getGeneration() % this.globalSearchIterations) == 0)) + && (this.localSearchSteps > 0) + && (this.m_Problem instanceof InterfaceLocalSearchable)) { + // here the local search is performed + if (TRACE) { + System.out.println("Performing local search on " + subsetsize + + " individuals."); } - this.m_GlobalOptimizer.optimize(); - - if ((globalSearchIterations>0) && (((this.m_GlobalOptimizer.getPopulation().getGeneration() % this.globalSearchIterations) == 0)) - && (this.localSearchSteps > 0) - && (this.m_Problem instanceof InterfaceLocalSearchable)) { - // here the local search is performed - if (TRACE) { - System.out.println("Performing local search on " + subsetsize - + " individuals."); - } - Population gop = this.m_GlobalOptimizer.getPopulation(); - Population subset = selectorPlug.selectFrom(gop, subsetsize); - Population subsetclone = new Population(); - for (int i = 0; i < subset.size(); i++) { - subsetclone.add(((AbstractEAIndividual) subset.get(i)).clone()); - } - if (subset.size() != subsetsize) { - System.err.println("ALERT! identical individual instances in subset"); - } - Hashtable antilamarckismcache = new Hashtable(); - if (!this.lamarckism) { - for (int i = 0; i < subset.size(); i++) { - AbstractEAIndividual indy = (AbstractEAIndividual) subset.get(i); - AbstractEAIndividual indyclone = (AbstractEAIndividual) subsetclone - .get(i); - antilamarckismcache.put(indy, indyclone); - } - } - - // int dosearchsteps = this.localSearchSteps; - double cost = ((InterfaceLocalSearchable) this.m_Problem) - .getLocalSearchStepFunctionCallEquivalent(); - // int calls = gop.getFunctionCalls() + (int) Math.round(localSearchSteps - // * cost * subset.size()); - // nett aber total unn�tig-falsch man kann nicht davon ausgehen, dass man - // einen Fitnesscall Terminator hat.. - // if (calls > this.maxfunctioncalls) { - // int remainingfunctioncalls = this.maxfunctioncalls - - // gop.getFunctionCalls(); - // dosearchsteps = (int)Math.floor(((double) remainingfunctioncalls) / - // (cost * subsetsize)); - // stopit = true; - // } - for (int i = 0; i < localSearchSteps; i++) { - ((InterfaceLocalSearchable) this.m_Problem).doLocalSearch(subsetclone); - } - this.m_Problem.evaluate(subsetclone); - if (this.lamarckism) { - gop.removeAll(subset); - gop.addPopulation(subsetclone); - } else { - for (int i = 0; i < subset.size(); i++) { - AbstractEAIndividual indy = (AbstractEAIndividual) subset.get(i); - try { - AbstractEAIndividual newindy = (AbstractEAIndividual) antilamarckismcache - .get(indy); - indy.setFitness(newindy.getFitness()); - } catch (Exception ex) { - System.err.println("individual not found in antilamarckismcache"); - } - } - } - // eigentlich muss hier noch subsetsize drauf, aber lassen wir das - gop.SetFunctionCalls(gop.getFunctionCalls() - + (int) Math.round(localSearchSteps * cost * subset.size())); - - if (TRACE) { - System.out.println("Population size after local search:" + gop.size()); - } - - this.setPopulation(gop); - } - - if (TRACE) { - System.out.println("function calls" - + this.m_GlobalOptimizer.getPopulation().getFunctionCalls()); + Population gop = this.m_GlobalOptimizer.getPopulation(); + Population subset = selectorPlug.selectFrom(gop, subsetsize); + Population subsetclone = new Population(); + for (int i = 0; i < subset.size(); i++) { + subsetclone.add(((AbstractEAIndividual) subset.get(i)).clone()); + } + if (subset.size() != subsetsize) { + System.err.println("ALERT! identical individual instances in subset"); + } + Hashtable antilamarckismcache = new Hashtable(); + if (!this.lamarckism) { + for (int i = 0; i < subset.size(); i++) { + AbstractEAIndividual indy = (AbstractEAIndividual) subset.get(i); + AbstractEAIndividual indyclone = (AbstractEAIndividual) subsetclone + .get(i); + antilamarckismcache.put(indy, indyclone); + } } - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } - /** - * This method allows you to add the LectureGUI as listener to the Optimizer - * - * @param ea - */ - @Override - public void addPopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - this.m_Listener = ea; - } - @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - /** - * Something has changed - */ - protected void firePropertyChangedEvent(String name) { - if (this.m_Listener != null) { - if (TRACE) { - System.out.println("firePropertyChangedEvent MA"); + // int dosearchsteps = this.localSearchSteps; + double cost = ((InterfaceLocalSearchable) this.m_Problem) + .getLocalSearchStepFunctionCallEquivalent(); + // int calls = gop.getFunctionCalls() + (int) Math.round(localSearchSteps + // * cost * subset.size()); + // nett aber total unn�tig-falsch man kann nicht davon ausgehen, dass man + // einen Fitnesscall Terminator hat.. + // if (calls > this.maxfunctioncalls) { + // int remainingfunctioncalls = this.maxfunctioncalls - + // gop.getFunctionCalls(); + // dosearchsteps = (int)Math.floor(((double) remainingfunctioncalls) / + // (cost * subsetsize)); + // stopit = true; + // } + for (int i = 0; i < localSearchSteps; i++) { + ((InterfaceLocalSearchable) this.m_Problem).doLocalSearch(subsetclone); + } + this.m_Problem.evaluate(subsetclone); + if (this.lamarckism) { + gop.removeAll(subset); + gop.addPopulation(subsetclone); + } else { + for (int i = 0; i < subset.size(); i++) { + AbstractEAIndividual indy = (AbstractEAIndividual) subset.get(i); + try { + AbstractEAIndividual newindy = (AbstractEAIndividual) antilamarckismcache + .get(indy); + indy.setFitness(newindy.getFitness()); + } catch (Exception ex) { + System.err.println("individual not found in antilamarckismcache"); } - this.m_Listener.registerPopulationStateChanged(this, name); - } - } + } + } + // eigentlich muss hier noch subsetsize drauf, aber lassen wir das + gop.SetFunctionCalls(gop.getFunctionCalls() + + (int) Math.round(localSearchSteps * cost * subset.size())); - /** - * This method will set the problem that is to be optimized - * - * @param problem - */ + if (TRACE) { + System.out.println("Population size after local search:" + gop.size()); + } + + this.setPopulation(gop); + } + + if (TRACE) { + System.out.println("function calls" + + this.m_GlobalOptimizer.getPopulation().getFunctionCalls()); + } + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + } + + /** + * This method allows you to add the LectureGUI as listener to the Optimizer + * + * @param ea + */ @Override - public void setProblem(InterfaceOptimizationProblem problem) { - this.m_Problem = problem; - this.m_GlobalOptimizer.setProblem(this.m_Problem); - } + public void addPopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + this.m_Listener = ea; + } @Override - public InterfaceOptimizationProblem getProblem() { - return this.m_Problem; - } + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } - /** - * This method will return a string describing all properties of the optimizer - * and the applied methods. - * - * @return A descriptive string - */ - @Override - public String getStringRepresentation() { - String result = ""; - result += "Memetic Algorithm:\n"; - result += "Optimization Problem: "; - result += this.m_Problem.getStringRepresentationForProblem(this) + "\n"; - result += this.m_GlobalOptimizer.getStringRepresentation(); - return result; - } + /** + * Something has changed + */ + protected void firePropertyChangedEvent(String name) { + if (this.m_Listener != null) { + if (TRACE) { + System.out.println("firePropertyChangedEvent MA"); + } + this.m_Listener.registerPopulationStateChanged(this, name); + } + } - /** - * This method allows you to set an identifier for the algorithm - * - * @param name - * The indenifier - */ + /** + * This method will set the problem that is to be optimized + * + * @param problem + */ @Override - public void setIdentifier(String name) { - this.m_Identifier = name; - } + public void setProblem(InterfaceOptimizationProblem problem) { + this.m_Problem = problem; + this.m_GlobalOptimizer.setProblem(this.m_Problem); + } @Override - public String getIdentifier() { - return this.m_Identifier; - } + public InterfaceOptimizationProblem getProblem() { + return this.m_Problem; + } - /** - * This method is required to free the memory on a RMIServer, but there is - * nothing to implement. - */ + /** + * This method will return a string describing all properties of the + * optimizer and the applied methods. + * + * @return A descriptive string + */ @Override - public void freeWilly() { + public String getStringRepresentation() { + String result = ""; + result += "Memetic Algorithm:\n"; + result += "Optimization Problem: "; + result += this.m_Problem.getStringRepresentationForProblem(this) + "\n"; + result += this.m_GlobalOptimizer.getStringRepresentation(); + return result; + } - } - - /* - * ======================================================================================== - * These are for GUI - */ - /** - * This method returns a global info string - * - * @return description - */ - public static String globalInfo() { - return "This is a basic generational Memetic Algorithm. Local search steps are performed on a selected subset " + - "of individuals after certain numbers of global search iterations. Note " + - "that the problem class must implement InterfaceLocalSearchable."; - } - - /** - * This method will return a naming String - * - * @return The name of the algorithm - */ + /** + * This method allows you to set an identifier for the algorithm + * + * @param name The indenifier + */ @Override - public String getName() { - return "MemeticAlgorithm"; - } - - /** - * Assuming that all optimizer will store thier data in a population we will - * allow acess to this population to query to current state of the optimizer. - * - * @return The population of current solutions to a given problem. - */ - @Override - public Population getPopulation() { - return this.m_GlobalOptimizer.getPopulation(); - } + public void setIdentifier(String name) { + this.m_Identifier = name; + } @Override - public void setPopulation(Population pop) { - this.m_GlobalOptimizer.setPopulation(pop); - } + public String getIdentifier() { + return this.m_Identifier; + } - public String populationTipText() { - return "Edit the properties of the population used."; - } - /** - * Choose the global optimization strategy to use - * - * @param m_GlobalOptimizer - */ - public void setGlobalOptimizer(InterfaceOptimizer m_GlobalOptimizer) { - this.m_GlobalOptimizer = m_GlobalOptimizer; - this.m_GlobalOptimizer.setProblem(this.getProblem()); - this.init(); - } + /* + * ======================================================================================== + * These are for GUI + */ + /** + * This method returns a global info string + * + * @return description + */ + public static String globalInfo() { + return "This is a basic generational Memetic Algorithm. Local search steps are performed on a selected subset " + + "of individuals after certain numbers of global search iterations. Note " + + "that the problem class must implement InterfaceLocalSearchable."; + } - public InterfaceOptimizer getGlobalOptimizer() { - return m_GlobalOptimizer; - } + /** + * This method will return a naming String + * + * @return The name of the algorithm + */ + @Override + public String getName() { + return "MemeticAlgorithm"; + } - public String globalOptimizerTipText() { - return "Choose the global optimization strategy to use."; - } + /** + * Assuming that all optimizer will store thier data in a population we will + * allow acess to this population to query to current state of the + * optimizer. + * + * @return The population of current solutions to a given problem. + */ + @Override + public Population getPopulation() { + return this.m_GlobalOptimizer.getPopulation(); + } - /** - * Choose the number of local search steps to perform per selected individual. - * - * @param localSearchSteps - */ - public void setLocalSearchSteps(int localSearchSteps) { - this.localSearchSteps = localSearchSteps; - } - public int getLocalSearchSteps() { - return localSearchSteps; - } - public String localSearchStepsTipText() { - return "Choose the number of local search steps to perform per selected individual."; - } + @Override + public void setPopulation(Population pop) { + this.m_GlobalOptimizer.setPopulation(pop); + } - /** - * Choose the interval between the application of the local search - * - * @param globalSearchSteps - */ - public void setGlobalSearchIterations(int globalSearchSteps) { - this.globalSearchIterations = globalSearchSteps; - } - public int getGlobalSearchIterations() { - return globalSearchIterations; - } - public String globalSearchIterationsTipText() { - return "Choose the interval between the application of the local search."; - } + public String populationTipText() { + return "Edit the properties of the population used."; + } + + /** + * Choose the global optimization strategy to use + * + * @param m_GlobalOptimizer + */ + public void setGlobalOptimizer(InterfaceOptimizer m_GlobalOptimizer) { + this.m_GlobalOptimizer = m_GlobalOptimizer; + this.m_GlobalOptimizer.setProblem(this.getProblem()); + this.init(); + } + + public InterfaceOptimizer getGlobalOptimizer() { + return m_GlobalOptimizer; + } + + public String globalOptimizerTipText() { + return "Choose the global optimization strategy to use."; + } + + /** + * Choose the number of local search steps to perform per selected + * individual. + * + * @param localSearchSteps + */ + public void setLocalSearchSteps(int localSearchSteps) { + this.localSearchSteps = localSearchSteps; + } + + public int getLocalSearchSteps() { + return localSearchSteps; + } + + public String localSearchStepsTipText() { + return "Choose the number of local search steps to perform per selected individual."; + } + + /** + * Choose the interval between the application of the local search + * + * @param globalSearchSteps + */ + public void setGlobalSearchIterations(int globalSearchSteps) { + this.globalSearchIterations = globalSearchSteps; + } + + public int getGlobalSearchIterations() { + return globalSearchIterations; + } + + public String globalSearchIterationsTipText() { + return "Choose the interval between the application of the local search."; + } @Override public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(getPopulation()); + return new SolutionSet(getPopulation()); + } + + /** + * Choose the number of individual to be locally optimized + * + * @param subsetsize + */ + public void setSubsetsize(int subsetsize) { + this.subsetsize = subsetsize; } - /** - * Choose the number of individual to be locally optimized - * - * @param subsetsize - */ - public void setSubsetsize(int subsetsize) { - this.subsetsize = subsetsize; - } public int getSubsetsize() { - return subsetsize; - } - public String subsetsizeTipText() { - return "Choose the number of individuals to be locally optimized."; - } + return subsetsize; + } - /** - * Toggle between Lamarckism and the Baldwin Effect - * - * @param lamarckism - */ - public void setLamarckism(boolean lamarckism) { - this.lamarckism = lamarckism; - } - public String lamarckismTipText() { - return "Toggle between Lamarckism and the Baldwin Effect."; - } - public boolean isLamarckism() { - return lamarckism; - } + public String subsetsizeTipText() { + return "Choose the number of individuals to be locally optimized."; + } - public InterfaceSelection getSubSetSelector() { - return selectorPlug; - } - public void setSubSetSelector(InterfaceSelection selectorPlug) { - this.selectorPlug = selectorPlug; - } - public String subSetSelectorTipText() { - return "Selection method to select the subset on which local search is to be performed."; - } + /** + * Toggle between Lamarckism and the Baldwin Effect + * + * @param lamarckism + */ + public void setLamarckism(boolean lamarckism) { + this.lamarckism = lamarckism; + } + + public String lamarckismTipText() { + return "Toggle between Lamarckism and the Baldwin Effect."; + } + + public boolean isLamarckism() { + return lamarckism; + } + + public InterfaceSelection getSubSetSelector() { + return selectorPlug; + } + + public void setSubSetSelector(InterfaceSelection selectorPlug) { + this.selectorPlug = selectorPlug; + } + + public String subSetSelectorTipText() { + return "Selection method to select the subset on which local search is to be performed."; + } } diff --git a/src/eva2/server/go/strategies/MonteCarloSearch.java b/src/eva2/server/go/strategies/MonteCarloSearch.java index 9b4a3327..ea775409 100644 --- a/src/eva2/server/go/strategies/MonteCarloSearch.java +++ b/src/eva2/server/go/strategies/MonteCarloSearch.java @@ -9,35 +9,34 @@ import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; -/** - * The simple random or Monte-Carlo search, simple but useful - * to evaluate the complexity of the search space. - * This implements a Random Walk Search using the initialization - * method of the problem instance, meaning that the random characteristics - * may be problem dependent. - * - * Copyright: Copyright (c) 2003 - * Company: University of Tuebingen, Computer Architecture - * @author Felix Streichert - * @version: $Revision: 307 $ - * $Date: 2007-12-04 14:31:47 +0100 (Tue, 04 Dec 2007) $ - * $Author: mkron $ +/** + * The simple random or Monte-Carlo search, simple but useful to evaluate the + * complexity of the search space. This implements a Random Walk Search using + * the initialization method of the problem instance, meaning that the random + * characteristics may be problem dependent. + * + * Copyright: Copyright (c) 2003 Company: University of Tuebingen, Computer + * Architecture + * + * @author Felix Streichert + * @version: $Revision: 307 $ $Date: 2007-12-04 14:31:47 +0100 (Tue, 04 Dec + * 2007) $ $Author: mkron $ */ public class MonteCarloSearch implements InterfaceOptimizer, java.io.Serializable { - /** - * Generated serial version id. - */ - private static final long serialVersionUID = -751760624411490405L; - // These variables are necessary for the simple testcase - private InterfaceOptimizationProblem m_Problem = new B1Problem(); - private int m_MultiRuns = 100; - private int m_FitnessCalls = 100; - private int m_FitnessCallsNeeded = 0; - private Population m_Population; - private GAIndividualBinaryData m_Best, m_Test; + /** + * Generated serial version id. + */ + private static final long serialVersionUID = -751760624411490405L; + // These variables are necessary for the simple testcase + private InterfaceOptimizationProblem m_Problem = new B1Problem(); + private int m_MultiRuns = 100; + private int m_FitnessCalls = 100; + private int m_FitnessCallsNeeded = 0; + private Population m_Population; + private GAIndividualBinaryData m_Best, m_Test; // These variables are necessary for the more complex LectureGUI enviroment - transient private String m_Identifier = ""; + transient private String m_Identifier = ""; transient private InterfacePopulationChangedEventListener m_Listener; public MonteCarloSearch() { @@ -46,8 +45,8 @@ public class MonteCarloSearch implements InterfaceOptimizer, java.io.Serializabl } public MonteCarloSearch(MonteCarloSearch a) { - this.m_Population = (Population)a.m_Population.clone(); - this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone(); + this.m_Population = (Population) a.m_Population.clone(); + this.m_Problem = (InterfaceOptimizationProblem) a.m_Problem.clone(); } @Override @@ -55,7 +54,8 @@ public class MonteCarloSearch implements InterfaceOptimizer, java.io.Serializabl return (Object) new MonteCarloSearch(this); } - /** This method will init the MonteCarloSearch + /** + * This method will init the MonteCarloSearch */ @Override public void init() { @@ -64,37 +64,39 @@ public class MonteCarloSearch implements InterfaceOptimizer, java.io.Serializabl this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** This method will init the optimizer with a given population - * @param pop The initial population - * @param reset If true the population is reset. + /** + * This method will init the optimizer with a given population + * + * @param pop The initial population + * @param reset If true the population is reset. */ @Override public void initByPopulation(Population pop, boolean reset) { - this.m_Population = (Population)pop.clone(); + this.m_Population = (Population) pop.clone(); if (reset) { - this.m_Population.init(); + this.m_Population.init(); this.m_Problem.evaluate(this.m_Population); this.firePropertyChangedEvent(Population.nextGenerationPerformed); } } - /** - * This method will optimize without specific operators, by just calling the individual method - * for initialization. + /** + * This method will optimize without specific operators, by just calling the + * individual method for initialization. */ @Override public void optimize() { - Population original = (Population)this.m_Population.clone(); + Population original = (Population) this.m_Population.clone(); // this.m_Problem.initPopulation(this.m_Population); - for (int i=0; i SuccessCounterMap = new HashMap(); - /** - * This method will evaluate the current population using the given problem. - * - * @param population - * The population that is to be evaluated - */ - private void evaluatePopulation(Population population) { - this.m_Problem.evaluate(population); - } + // Eltern markieren und f�r die Z�hlung vorbereiten + for (int j = 0; j < m_lambdamo && j < m_Population.size(); j++) { + m_Population.getEAIndividual(j).putData("Parent", + m_Population.getEAIndividual(j)); + SuccessCounterMap.put(m_Population.getEAIndividual(j).getIndyID(), + new CounterClass(0)); + } - /* - * (non-Javadoc) - * - * @see eva2.server.go.strategies.InterfaceOptimizer#optimize() - */ - @Override - public void optimize() { + // Kinder erzeugen + Population children = new Population(m_lambdamo * m_lambda); + children.setGenerationTo(m_Population.getGeneration()); - HashMap SuccessCounterMap = new HashMap(); + for (int j = 0; j < children.getTargetSize(); j++) { + AbstractEAIndividual parent = m_Population.getEAIndividual(j + % m_lambdamo); + AbstractEAIndividual indy = (AbstractEAIndividual) parent.clone(); + indy.mutate(); + indy.putData("Parent", parent); + children.add(indy); + } + evaluatePopulation(children); - // Eltern markieren und f�r die Z�hlung vorbereiten - for (int j = 0; j < m_lambdamo && j < m_Population.size(); j++) { - m_Population.getEAIndividual(j).putData("Parent", - m_Population.getEAIndividual(j)); - SuccessCounterMap.put(m_Population.getEAIndividual(j).getIndyID(), - new CounterClass(0)); - } + m_Population.addPopulation(children); + // Ranking + ArchivingNSGAII dummyArchive = new ArchivingNSGAIISMeasure(); + Population[] store = dummyArchive + .getNonDominatedSortedFronts(m_Population); + store = dummyArchive.getNonDominatedSortedFronts(m_Population); + dummyArchive.calculateCrowdingDistance(store); - // Kinder erzeugen - Population children = new Population(m_lambdamo * m_lambda); - children.setGenerationTo(m_Population.getGeneration()); + // Vergleichen und den Successcounter hochz�hlen wenn wir besser als + // unser Elter sind + for (int j = 0; j < m_Population.size(); j++) { + AbstractEAIndividual parent = (AbstractEAIndividual) m_Population + .getEAIndividual(j).getData("Parent"); + if (m_Population.getEAIndividual(j) != parent) { // Eltern nicht mit + // sich selber + // vergleichen + int parentParetoLevel = ((Integer) parent + .getData("ParetoLevel")).intValue(); + double parentSMeasure = ((Double) parent.getData("HyperCube")) + .doubleValue(); + int childParetoLevel = ((Integer) m_Population.getEAIndividual( + j).getData("ParetoLevel")).intValue(); + double childSMeasure = ((Double) m_Population + .getEAIndividual(j).getData("HyperCube")).doubleValue(); + if (childParetoLevel < parentParetoLevel + || ((childParetoLevel == parentParetoLevel) && childSMeasure > parentSMeasure)) { + SuccessCounterMap.get(parent.getIndyID()).value++; + } + } else { // Debug - for (int j = 0; j < children.getTargetSize(); j++) { - AbstractEAIndividual parent = m_Population.getEAIndividual(j - % m_lambdamo); - AbstractEAIndividual indy = (AbstractEAIndividual) parent.clone(); - indy.mutate(); - indy.putData("Parent", parent); - children.add(indy); - } - evaluatePopulation(children); - - m_Population.addPopulation(children); - // Ranking - ArchivingNSGAII dummyArchive = new ArchivingNSGAIISMeasure(); - Population[] store = dummyArchive - .getNonDominatedSortedFronts(m_Population); - store = dummyArchive.getNonDominatedSortedFronts(m_Population); - dummyArchive.calculateCrowdingDistance(store); - - // Vergleichen und den Successcounter hochz�hlen wenn wir besser als - // unser Elter sind - for (int j = 0; j < m_Population.size(); j++) { - AbstractEAIndividual parent = (AbstractEAIndividual) m_Population - .getEAIndividual(j).getData("Parent"); - if (m_Population.getEAIndividual(j) != parent) { // Eltern nicht mit - // sich selber - // vergleichen - int parentParetoLevel = ((Integer) parent - .getData("ParetoLevel")).intValue(); - double parentSMeasure = ((Double) parent.getData("HyperCube")) - .doubleValue(); - int childParetoLevel = ((Integer) m_Population.getEAIndividual( - j).getData("ParetoLevel")).intValue(); - double childSMeasure = ((Double) m_Population - .getEAIndividual(j).getData("HyperCube")).doubleValue(); - if (childParetoLevel < parentParetoLevel - || ((childParetoLevel == parentParetoLevel) && childSMeasure > parentSMeasure)) { - SuccessCounterMap.get(parent.getIndyID()).value++; - } - } else { // Debug - - SuccessCounterMap.get(parent.getIndyID()).seen = true; - } - } - - // Selection - m_Population.clear(); - for (int i = 0; i < store.length; i++) { - if (m_Population.size() + store[i].size() <= m_lambdamo) { // Die - // Front - // passt - // noch - // komplett - m_Population.addPopulation(store[i]); - - } else { // die besten aus der aktuellen Front heraussuchen bis voll - while (store[i].size() > 0 && m_Population.size() < m_lambdamo) { - AbstractEAIndividual indy = store[i].getEAIndividual(0); - double bestMeasure = ((Double) indy.getData("HyperCube")) - .doubleValue(); // TODO mal noch effizient machen - // (sortieren und die besten n - // herausholen) - for (int j = 1; j < store[i].size(); j++) { - if (bestMeasure < ((Double) store[i].getEAIndividual(j) - .getData("HyperCube")).doubleValue()) { - bestMeasure = ((Double) store[i].getEAIndividual(j) - .getData("HyperCube")).doubleValue(); - indy = store[i].getEAIndividual(j); - } - } - m_Population.add(indy); - store[i].removeMember(indy); - } - } - - } - - // Strategieparemeter updaten - for (int j = 0; j < m_Population.size(); j++) { - - AbstractEAIndividual indy = m_Population.getEAIndividual(j); - if (indy.getMutationOperator() instanceof MutateESCovarianceMatrixAdaptionPlus) { // Das - // geht - // nur - // wenn - // wir - // auch - // die - // richtige - // Mutation - // haben - AbstractEAIndividual parent = (AbstractEAIndividual) indy - .getData("Parent"); - MutateESCovarianceMatrixAdaptionPlus muta = (MutateESCovarianceMatrixAdaptionPlus) indy - .getMutationOperator(); - double rate = ((double) SuccessCounterMap.get(parent - .getIndyID()).value) - / ((double) m_lambda); - - if (indy != parent) { - muta.updateCovariance(); - } - muta.updateStepSize(rate); - } - } - - for (int j = 0; j < children.size(); j++) { - children.getEAIndividual(j).putData("Parent", null); - } - - m_Population.incrFunctionCallsBy(children.size()); - m_Population.incrGeneration(); - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - - } - - /* - * (non-Javadoc) - * - * @seeeva2.server.go.strategies.InterfaceOptimizer# - * removePopulationChangedEventListener - * (eva2.server.go.InterfacePopulationChangedEventListener) - */ - @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - return false; - } - - /* - * (non-Javadoc) - * - * @see - * eva2.server.go.strategies.InterfaceOptimizer#setPopulation(eva2.server - * .go.populations.Population) - */ - @Override - public void setPopulation(Population pop) { - m_Population = pop; - m_Population.setNotifyEvalInterval(1); - m_lambdamo = m_Population.getTargetSize(); - - } - - /** - * Something has changed - * - * @param name - */ - protected void firePropertyChangedEvent(String name) { - if (this.m_Listener != null) { - this.m_Listener.registerPopulationStateChanged(this, name); + SuccessCounterMap.get(parent.getIndyID()).seen = true; } - } + } - public int getLambda() { - return m_lambda; - } + // Selection + m_Population.clear(); + for (int i = 0; i < store.length; i++) { + if (m_Population.size() + store[i].size() <= m_lambdamo) { // Die + // Front + // passt + // noch + // komplett + m_Population.addPopulation(store[i]); - public void setLambda(int mLambda) { - m_lambda = mLambda; - } + } else { // die besten aus der aktuellen Front heraussuchen bis voll + while (store[i].size() > 0 && m_Population.size() < m_lambdamo) { + AbstractEAIndividual indy = store[i].getEAIndividual(0); + double bestMeasure = ((Double) indy.getData("HyperCube")) + .doubleValue(); // TODO mal noch effizient machen + // (sortieren und die besten n + // herausholen) + for (int j = 1; j < store[i].size(); j++) { + if (bestMeasure < ((Double) store[i].getEAIndividual(j) + .getData("HyperCube")).doubleValue()) { + bestMeasure = ((Double) store[i].getEAIndividual(j) + .getData("HyperCube")).doubleValue(); + indy = store[i].getEAIndividual(j); + } + } + m_Population.add(indy); + store[i].removeMember(indy); + } + } - /* - * public int getLambdaMo() { return m_lambdamo; } - * - * public void setLambdaMo(int mLambda) { m_lambdamo = mLambda; } - */ + } + // Strategieparemeter updaten + for (int j = 0; j < m_Population.size(); j++) { + + AbstractEAIndividual indy = m_Population.getEAIndividual(j); + if (indy.getMutationOperator() instanceof MutateESCovarianceMatrixAdaptionPlus) { // Das + // geht + // nur + // wenn + // wir + // auch + // die + // richtige + // Mutation + // haben + AbstractEAIndividual parent = (AbstractEAIndividual) indy + .getData("Parent"); + MutateESCovarianceMatrixAdaptionPlus muta = (MutateESCovarianceMatrixAdaptionPlus) indy + .getMutationOperator(); + double rate = ((double) SuccessCounterMap.get(parent + .getIndyID()).value) + / ((double) m_lambda); + + if (indy != parent) { + muta.updateCovariance(); + } + muta.updateStepSize(rate); + } + } + + for (int j = 0; j < children.size(); j++) { + children.getEAIndividual(j).putData("Parent", null); + } + + m_Population.incrFunctionCallsBy(children.size()); + m_Population.incrGeneration(); + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + + } + + /* + * (non-Javadoc) + * + * @seeeva2.server.go.strategies.InterfaceOptimizer# + * removePopulationChangedEventListener + * (eva2.server.go.InterfacePopulationChangedEventListener) + */ + @Override + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + return false; + } + + /* + * (non-Javadoc) + * + * @see + * eva2.server.go.strategies.InterfaceOptimizer#setPopulation(eva2.server + * .go.populations.Population) + */ + @Override + public void setPopulation(Population pop) { + m_Population = pop; + m_Population.setNotifyEvalInterval(1); + m_lambdamo = m_Population.getTargetSize(); + + } + + /** + * Something has changed + * + * @param name + */ + protected void firePropertyChangedEvent(String name) { + if (this.m_Listener != null) { + this.m_Listener.registerPopulationStateChanged(this, name); + } + } + + public int getLambda() { + return m_lambda; + } + + public void setLambda(int mLambda) { + m_lambda = mLambda; + } + + /* + * public int getLambdaMo() { return m_lambdamo; } + * + * public void setLambdaMo(int mLambda) { m_lambdamo = mLambda; } + */ } diff --git a/src/eva2/server/go/strategies/MultiObjectiveEA.java b/src/eva2/server/go/strategies/MultiObjectiveEA.java index 6d4fcd3b..3f5a0ce4 100644 --- a/src/eva2/server/go/strategies/MultiObjectiveEA.java +++ b/src/eva2/server/go/strategies/MultiObjectiveEA.java @@ -15,61 +15,50 @@ import eva2.server.go.problems.AbstractOptimizationProblem; import eva2.server.go.problems.FM0Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; -/** - * A generic framework for multi-objecitve optimization, you need - * to specify an optimization strategy (like GA), an archiver and - * an information retrival strategy. With this scheme you can realized: - * Vector Evaluated GA - * Random Weight GA - * Multiple Objective GA - * NSGA - * NSGA-II - * SPEA - * SPEA 2 - * PESA - * PESA-II - * In case you address a multi-objective optimization problem with a single- - * objective optimizer instead of this MOEA, such an optimizer would randomly - * toggle between the objective for each selection and thus explore at least - * the extreme points of the objective space, but simpler methods like - * random search or hill-climbing might even fail on that. - * Created by IntelliJ IDEA. - * User: streiche - * Date: 05.06.2003 - * Time: 11:03:50 - * To change this template use Options | File Templates. +/** + * A generic framework for multi-objecitve optimization, you need to specify an + * optimization strategy (like GA), an archiver and an information retrival + * strategy. With this scheme you can realized: Vector Evaluated GA Random + * Weight GA Multiple Objective GA NSGA NSGA-II SPEA SPEA 2 PESA PESA-II In case + * you address a multi-objective optimization problem with a single- objective + * optimizer instead of this MOEA, such an optimizer would randomly toggle + * between the objective for each selection and thus explore at least the + * extreme points of the objective space, but simpler methods like random search + * or hill-climbing might even fail on that. Created by IntelliJ IDEA. User: + * streiche Date: 05.06.2003 Time: 11:03:50 To change this template use Options + * | File Templates. */ public class MultiObjectiveEA implements InterfaceOptimizer, java.io.Serializable { - private InterfaceOptimizer m_Optimizer = new GeneticAlgorithm(); - private InterfaceArchiving m_Archiver = new ArchivingNSGAII(); - private InterfaceInformationRetrieval m_InformationRetrieval = new InformationRetrievalInserting(); - private InterfaceOptimizationProblem m_Problem = new FM0Problem(); - private String m_Identifier = ""; + private InterfaceOptimizer m_Optimizer = new GeneticAlgorithm(); + private InterfaceArchiving m_Archiver = new ArchivingNSGAII(); + private InterfaceInformationRetrieval m_InformationRetrieval = new InformationRetrievalInserting(); + private InterfaceOptimizationProblem m_Problem = new FM0Problem(); + private String m_Identifier = ""; transient private InterfacePopulationChangedEventListener m_Listener; public MultiObjectiveEA() { this.m_Optimizer.getPopulation().setTargetSize(100); - ((GeneticAlgorithm)this.m_Optimizer).setParentSelection(new SelectMONonDominated()); - ((GeneticAlgorithm)this.m_Optimizer).setPartnerSelection(new SelectMONonDominated()); + ((GeneticAlgorithm) this.m_Optimizer).setParentSelection(new SelectMONonDominated()); + ((GeneticAlgorithm) this.m_Optimizer).setPartnerSelection(new SelectMONonDominated()); } public MultiObjectiveEA(MultiObjectiveEA a) { - this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone(); - this.m_Optimizer = (InterfaceOptimizer)a.m_Optimizer.clone(); - this.m_Archiver = (InterfaceArchiving)a.m_Archiver.clone(); - this.m_InformationRetrieval = (InterfaceInformationRetrieval)a.m_InformationRetrieval.clone(); + this.m_Problem = (InterfaceOptimizationProblem) a.m_Problem.clone(); + this.m_Optimizer = (InterfaceOptimizer) a.m_Optimizer.clone(); + this.m_Archiver = (InterfaceArchiving) a.m_Archiver.clone(); + this.m_InformationRetrieval = (InterfaceInformationRetrieval) a.m_InformationRetrieval.clone(); } public MultiObjectiveEA(InterfaceOptimizer subOpt, InterfaceArchiving archiving, int archiveSize, - InterfaceInformationRetrieval infoRetrieval, AbstractOptimizationProblem problem) { + InterfaceInformationRetrieval infoRetrieval, AbstractOptimizationProblem problem) { setOptimizer(subOpt); setArchivingStrategy(archiving); setArchiveSize(archiveSize); setInformationRetrieval(infoRetrieval); setProblem(problem); } - + @Override public Object clone() { return (Object) new MultiObjectiveEA(this); @@ -82,10 +71,11 @@ public class MultiObjectiveEA implements InterfaceOptimizer, java.io.Serializabl this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - - /** This method will init the optimizer with a given population - * @param pop The initial population - * @param reset If true the population is reset. + /** + * This method will init the optimizer with a given population + * + * @param pop The initial population + * @param reset If true the population is reset. */ @Override public void initByPopulation(Population pop, boolean reset) { @@ -94,7 +84,8 @@ public class MultiObjectiveEA implements InterfaceOptimizer, java.io.Serializabl this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** The optimize method will compute a 'improved' and evaluated population + /** + * The optimize method will compute a 'improved' and evaluated population */ @Override public void optimize() { @@ -144,7 +135,7 @@ public class MultiObjectiveEA implements InterfaceOptimizer, java.io.Serializabl double[][] fitness = new double[tmp.size()][]; for (int i = 0; i < tmp.size(); i++) { - fitness[i] = ((AbstractEAIndividual)tmp.get(i)).getFitness(); + fitness[i] = ((AbstractEAIndividual) tmp.get(i)).getFitness(); } double[] minY, maxY; minY = fitness[0]; @@ -168,39 +159,44 @@ public class MultiObjectiveEA implements InterfaceOptimizer, java.io.Serializabl public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { this.m_Listener = ea; } - - @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - protected void firePropertyChangedEvent (String name) { + @Override + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } + + protected void firePropertyChangedEvent(String name) { if (this.m_Listener != null) { this.m_Listener.registerPopulationStateChanged(this, name); } } - /** This method will set the problem that is to be optimized + /** + * This method will set the problem that is to be optimized + * * @param problem */ @Override - public void setProblem (InterfaceOptimizationProblem problem) { + public void setProblem(InterfaceOptimizationProblem problem) { this.m_Problem = problem; this.m_Optimizer.setProblem(problem); } + @Override - public InterfaceOptimizationProblem getProblem () { + public InterfaceOptimizationProblem getProblem() { return this.m_Problem; } - /** This method will return a string describing all properties of the optimizer - * and the applied methods. + /** + * This method will return a string describing all properties of the + * optimizer and the applied methods. + * * @return A descriptive string */ @Override @@ -212,42 +208,44 @@ public class MultiObjectiveEA implements InterfaceOptimizer, java.io.Serializabl result += " Information Retrieval = " + this.m_InformationRetrieval.getClass().toString() + "\n"; result += " Information Retrieval = " + this.getClass().toString() + "\n"; result += " Optimizer = " + this.m_Optimizer.getClass().toString() + "\n"; - result += this.m_Optimizer.getStringRepresentation() +"\n"; + result += this.m_Optimizer.getStringRepresentation() + "\n"; //result += "=> The Optimization Problem: "; //result += this.m_Problem.getStringRepresentationForProblem(this) +"\n"; //result += this.m_Population.getStringRepresentation(); return result; } - /** This method allows you to set an identifier for the algorithm - * @param name The indenifier + /** + * This method allows you to set an identifier for the algorithm + * + * @param name The indenifier */ @Override - public void setIdentifier(String name) { + public void setIdentifier(String name) { this.m_Identifier = name; } - @Override - public String getIdentifier() { - return this.m_Identifier; - } - /** This method is required to free the memory on a RMIServer, - * but there is nothing to implement. + @Override + public String getIdentifier() { + return this.m_Identifier; + } + + /** + * ******************************************************************************************************************** + * These are for GUI */ - @Override - public void freeWilly() { - - } -/********************************************************************************************************************** - * These are for GUI - */ - /** This method returns a global info string + /** + * This method returns a global info string + * * @return description */ public static String globalInfo() { return "This is a general Multi-objective Evolutionary Optimization Framework."; } - /** This method will return a naming String + + /** + * This method will return a naming String + * * @return The name of the algorithm */ @Override @@ -255,69 +253,87 @@ public class MultiObjectiveEA implements InterfaceOptimizer, java.io.Serializabl return "MOEA"; } - /** Assuming that all optimizer will store thier data in a population - * we will allow acess to this population to query to current state - * of the optimizer. + /** + * Assuming that all optimizer will store thier data in a population we will + * allow acess to this population to query to current state of the + * optimizer. + * * @return The population of current solutions to a given problem. */ @Override public Population getPopulation() { return this.m_Optimizer.getPopulation(); } + @Override - public void setPopulation(Population pop){ + public void setPopulation(Population pop) { this.m_Optimizer.setPopulation(pop); } + public String populationTipText() { return "Edit the properties of the Population used."; } - + @Override public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(getPopulation(), ArchivingNSGAII.getNonDominatedSortedFront(getPopulation().getArchive()).getSortedPop(new AbstractEAIndividualComparator(0))); + return new SolutionSet(getPopulation(), ArchivingNSGAII.getNonDominatedSortedFront(getPopulation().getArchive()).getSortedPop(new AbstractEAIndividualComparator(0))); } - /** This method allows you to set/get the optimizing technique to use. + /** + * This method allows you to set/get the optimizing technique to use. + * * @return The current optimizing method */ public InterfaceOptimizer getOptimizer() { return this.m_Optimizer; } - public void setOptimizer(InterfaceOptimizer b){ + + public void setOptimizer(InterfaceOptimizer b) { this.m_Optimizer = b; } + public String optimizerTipText() { return "Choose a population based optimizing technique to use."; } - /** This method allows you to set/get the archiving strategy to use. + /** + * This method allows you to set/get the archiving strategy to use. + * * @return The current optimizing method */ public InterfaceArchiving getArchivingStrategy() { return this.m_Archiver; } - public void setArchivingStrategy(InterfaceArchiving b){ + + public void setArchivingStrategy(InterfaceArchiving b) { this.m_Archiver = b; } + public String archivingStrategyTipText() { return "Choose the archiving strategy."; } - - /** This method allows you to set/get the Information Retrieval strategy to use. + /** + * This method allows you to set/get the Information Retrieval strategy to + * use. + * * @return The current optimizing method */ public InterfaceInformationRetrieval getInformationRetrieval() { return this.m_InformationRetrieval; } - public void setInformationRetrieval(InterfaceInformationRetrieval b){ + + public void setInformationRetrieval(InterfaceInformationRetrieval b) { this.m_InformationRetrieval = b; } + public String informationRetrievalTipText() { return "Choose the Information Retrieval strategy."; } - /** This method allows you to set/get the size of the archive. + /** + * This method allows you to set/get the size of the archive. + * * @return The current optimizing method */ public int getArchiveSize() { @@ -328,7 +344,8 @@ public class MultiObjectiveEA implements InterfaceOptimizer, java.io.Serializabl } return archive.getTargetSize(); } - public void setArchiveSize(int b){ + + public void setArchiveSize(int b) { Population archive = this.m_Optimizer.getPopulation().getArchive(); if (archive == null) { archive = new Population(); @@ -336,6 +353,7 @@ public class MultiObjectiveEA implements InterfaceOptimizer, java.io.Serializabl } archive.setTargetSize(b); } + public String archiveSizeTipText() { return "Choose the size of the archive."; } diff --git a/src/eva2/server/go/strategies/NelderMeadSimplex.java b/src/eva2/server/go/strategies/NelderMeadSimplex.java index b3ad3b16..219198c2 100644 --- a/src/eva2/server/go/strategies/NelderMeadSimplex.java +++ b/src/eva2/server/go/strategies/NelderMeadSimplex.java @@ -15,505 +15,497 @@ import java.io.Serializable; import java.util.Vector; /** - * Nelder-Mead-Simplex does not guarantee an equal number of evaluations within each optimize call - * because of the different step types. - * Range check is now available by projection at the bounds. - * + * Nelder-Mead-Simplex does not guarantee an equal number of evaluations within + * each optimize call because of the different step types. Range check is now + * available by projection at the bounds. + * * @author mkron * */ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, InterfacePopulationChangedEventListener { - private int populationSize = 100; - // simulating the generational cycle. Set rather small (eg 5) for use as local search, higher for global search (eg 50) - private int generationCycle = 50; - - private int fitIndex = 0; // choose criterion for multi objective functions - - private Population m_Population; - private AbstractOptimizationProblem m_Problem; - private transient Vector m_Listener; - private String m_Identifier = "NelderMeadSimplex"; - private boolean checkConstraints = true; + private int populationSize = 100; + // simulating the generational cycle. Set rather small (eg 5) for use as local search, higher for global search (eg 50) + private int generationCycle = 50; + private int fitIndex = 0; // choose criterion for multi objective functions + private Population m_Population; + private AbstractOptimizationProblem m_Problem; + private transient Vector m_Listener; + private String m_Identifier = "NelderMeadSimplex"; + private boolean checkConstraints = true; - public NelderMeadSimplex() { - setPopulation(new Population(populationSize)); - } - - public NelderMeadSimplex(int popSize) { - populationSize=popSize; - setPopulation(new Population(populationSize)); - } - - public NelderMeadSimplex(NelderMeadSimplex a) { - m_Problem = (AbstractOptimizationProblem)a.m_Problem.clone(); - setPopulation((Population)a.m_Population.clone()); - populationSize = a.populationSize; - generationCycle = a.generationCycle; - m_Identifier = a.m_Identifier; - } + public NelderMeadSimplex() { + setPopulation(new Population(populationSize)); + } + + public NelderMeadSimplex(int popSize) { + populationSize = popSize; + setPopulation(new Population(populationSize)); + } + + public NelderMeadSimplex(NelderMeadSimplex a) { + m_Problem = (AbstractOptimizationProblem) a.m_Problem.clone(); + setPopulation((Population) a.m_Population.clone()); + populationSize = a.populationSize; + generationCycle = a.generationCycle; + m_Identifier = a.m_Identifier; + } @Override - public NelderMeadSimplex clone() { - return new NelderMeadSimplex(this); - } + public NelderMeadSimplex clone() { + return new NelderMeadSimplex(this); + } @Override - public void setIdentifier(String name) { - m_Identifier = name; - } + public void setIdentifier(String name) { + m_Identifier = name; + } @Override - public void setProblem(InterfaceOptimizationProblem problem) { - m_Problem = (AbstractOptimizationProblem)problem; - } - - public boolean setProblemAndPopSize(InterfaceOptimizationProblem problem) { - setProblem(problem); - if (m_Problem instanceof AbstractProblemDouble) { - setPopulationSize(((AbstractProblemDouble)problem).getProblemDimension()+1); - return true; - } else { - Object ret=BeanInspector.callIfAvailable(problem, "getProblemDimension", null); - if (ret!=null) { - setPopulationSize(((Integer)ret)+1); - return true; - } - } - return false; - } + public void setProblem(InterfaceOptimizationProblem problem) { + m_Problem = (AbstractOptimizationProblem) problem; + } + + public boolean setProblemAndPopSize(InterfaceOptimizationProblem problem) { + setProblem(problem); + if (m_Problem instanceof AbstractProblemDouble) { + setPopulationSize(((AbstractProblemDouble) problem).getProblemDimension() + 1); + return true; + } else { + Object ret = BeanInspector.callIfAvailable(problem, "getProblemDimension", null); + if (ret != null) { + setPopulationSize(((Integer) ret) + 1); + return true; + } + } + return false; + } @Override - public void addPopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (ea!=null) { - if (m_Listener == null) { - m_Listener = new Vector(); - } - if (!m_Listener.contains(ea)) { - m_Listener.add(ea); - } - } - } - - @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==null) { - return false; - } - else { - return m_Listener.remove(ea); - } - } - - @Override - public void freeWilly() {} + public void addPopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (ea != null) { + if (m_Listener == null) { + m_Listener = new Vector(); + } + if (!m_Listener.contains(ea)) { + m_Listener.add(ea); + } + } + } - protected double[] calcChallengeVect(double[] centroid, double[] refX) { - double[] r = new double[centroid.length]; - for (int i=0; i Expansion - double[] e = new double[dim]; - for (int i=0; i Expansion + double[] e = new double[dim]; + for (int i = 0; i < dim; i++) { + e[i] = 3 * centroid[i] - 2 * x_worst[i]; } - if (checkConstraints && !Mathematics.isInRange(e, range)) { - Mathematics.projectToRange(e, range); - } - - AbstractEAIndividual e_ind = createEvalIndy(bestpop, e); - this.m_Population.incrFunctionCalls(); - - if (firstIsBetter(e_ind, reflectedInd)) { //expandiertes ist besser als reflektiertes - return e_ind; - } else { - return reflectedInd; - } - } else if (firstIsBetterEqual(bestpop.getWorstEAIndividual(fitIndex), reflectedInd)) { - //kontrahiere da neues indi keine verbesserung brachte - double[] c = new double[dim]; - for (int i=0; i= 1. || (perturbRelative <= 0.)) { - System.err.println("Warning: perturbation ratio should lie between 0 and 1! (NelderMeadSimplex:createNMSPopulation)"); - } - addPerturbedPopulation(perturbRelative, initPop, range, candidate); - return initPop; - } + evalsDone = m_Population.getFunctionCalls() - evalCntStart; + } while (evalsDone < generationCycle); + m_Problem.evaluatePopulationEnd(m_Population); + this.m_Population.incrGeneration(); + } - private static void addPerturbedPopulation(double perturbationRatio, - Population initialPop, double[][] range, AbstractEAIndividual candidate) { - AbstractEAIndividual indy = (AbstractEAIndividual)candidate.clone(); - // span by perturbation, every new individual i is modified in dimension i by - // a value of perturbRatio*range_i such that a simplex of relative side length perturbRatio is created. - for (int i=0; i= 1. || (perturbRelative <= 0.)) { + System.err.println("Warning: perturbation ratio should lie between 0 and 1! (NelderMeadSimplex:createNMSPopulation)"); + } + addPerturbedPopulation(perturbRelative, initPop, range, candidate); + return initPop; + } + + private static void addPerturbedPopulation(double perturbationRatio, + Population initialPop, double[][] range, AbstractEAIndividual candidate) { + AbstractEAIndividual indy = (AbstractEAIndividual) candidate.clone(); + // span by perturbation, every new individual i is modified in dimension i by + // a value of perturbRatio*range_i such that a simplex of relative side length perturbRatio is created. + for (int i = 0; i < range.length; i += 1) { + double curPerturb = ((range[i][1] - range[i][0]) * perturbationRatio); + double[] dat = ((InterfaceDataTypeDouble) indy).getDoubleData(); + if (dat[i] == range[i][1]) { // in this case the bound is said to be too close + dat[i] = Math.max(dat[i] - curPerturb, range[i][0]); + } else { + dat[i] = Math.min(dat[i] + curPerturb, range[i][1]); + } + ((InterfaceDataTypeDouble) indy).SetDoubleGenotype(dat); + indy.resetConstraintViolation(); + initialPop.add((AbstractEAIndividual) indy.clone()); + } + initialPop.synchSize(); + } + + /** + * @param generationCycle the generationCycle to set + */ + public void setGenerationCycle(int generationCycle) { + this.generationCycle = generationCycle; + } + + public boolean isCheckRange() { + return checkConstraints; + } + + public void setCheckRange(boolean checkRange) { + this.checkConstraints = checkRange; + } + + public String checkRangeTipText() { + return "Mark to check range constraints by reflection/projection"; + } + + public int getCritIndex() { + return fitIndex; + } + + public void setCritIndex(int fitIndex) { + this.fitIndex = fitIndex; + } + + public String critIndexTipText() { + return "For multi-criterial problems, set the index of the fitness to be used in 0..n-1. Default is 0"; + } } diff --git a/src/eva2/server/go/strategies/NichePSO.java b/src/eva2/server/go/strategies/NichePSO.java index 97768320..33ac74f4 100644 --- a/src/eva2/server/go/strategies/NichePSO.java +++ b/src/eva2/server/go/strategies/NichePSO.java @@ -54,917 +54,946 @@ import java.util.Date; import java.util.List; import java.util.Vector; - /** - * The NichePSO extends the particle swarm optimizer (PSO) by Kennedy and Eberhart - * to locate multiple optima of a multimodal objective function. - * The original algorithm is proposed in [1] and uses a main swarm to explore the search space. - * Subswarms are formed from that main swarm to refine and represent single niches - * which are assumed to correspond to local or global optima. - * - * Different strategies are employed in order to: - * create subswarms from the main swarm - * merge subswarms if they converge to the same solution - * absorb main swarm particles into a subswarm in case a particle enters the area covered by the subswarm - * deactivate subswarms when all containing particles converged on a solution - * - * Some implementations of these strategies and the deactivation strategy itself extend the original algorithm. - * As proposed in [1], NichePSO uses the "cognition only" model of the "inertness weight" PSO to train the main swarm. - * - * mainSwarmInertness sets the inertia weight omega and weights the particles tendency to follow its former movement. - * This controls exploration (favored by larger values) against exploitation (favored by smaller values). - * mainSwarmPhi1 sets Phi1 and weights the cognitive component. - * The term corresponds to the particles tendency to return to its personal best position. - * The combination of a typical value of mainSwarmInertness = 0.7 linearly decreasing to 0.2 - * and a typical value of mainSwarmPhi1 = 1.2 produces good results. - * maxAllowedSwarmRadius defines the maximal radius a subswarm can formally have, but it does not affect the actual radius. - * This adjustment is proposed in [2] in order to improve the performance of the NichePSO. - * Experiments showed a good performance for relatively small values of maxAllowedSwarmRadius <= 0.0001 - * on lower dimensional problems. For higher dimensional problems, larger values may be preferable. - * - * [1] R. Brits, A. P. Engelbrecht and B. Bergh. - * A Niching Particle Swarm Optimizer - * In Proceedings of the 4th Asia-Pacific Conference on Simulated Evolution and Learning (SEAL'02), - * 2002, 2, 692-696 - * [2] E. �zcan and M. Yilmaz. - * Particle Swarms for Multimodal Optimization. - * In: ICANNGA (1), Seiten 366�375, 2007 + * The NichePSO extends the particle swarm optimizer (PSO) by Kennedy and + * Eberhart to locate multiple optima of a multimodal objective function. The + * original algorithm is proposed in [1] and uses a main swarm to explore the + * search space. Subswarms are formed from that main swarm to refine and + * represent single niches which are assumed to correspond to local or global + * optima. + * + * Different strategies are employed in order to: create subswarms from the main + * swarm merge subswarms if they converge to the same solution absorb main swarm + * particles into a subswarm in case a particle enters the area covered by the + * subswarm deactivate subswarms when all containing particles converged on a + * solution + * + * Some implementations of these strategies and the deactivation strategy itself + * extend the original algorithm. As proposed in [1], NichePSO uses the + * "cognition only" model of the "inertness weight" PSO to train the main swarm. + * + * mainSwarmInertness sets the inertia weight omega and weights the particles + * tendency to follow its former movement. This controls exploration (favored by + * larger values) against exploitation (favored by smaller values). + * mainSwarmPhi1 sets Phi1 and weights the cognitive component. The term + * corresponds to the particles tendency to return to its personal best + * position. The combination of a typical value of mainSwarmInertness = 0.7 + * linearly decreasing to 0.2 and a typical value of mainSwarmPhi1 = 1.2 + * produces good results. maxAllowedSwarmRadius defines the maximal radius a + * subswarm can formally have, but it does not affect the actual radius. This + * adjustment is proposed in [2] in order to improve the performance of the + * NichePSO. Experiments showed a good performance for relatively small values + * of maxAllowedSwarmRadius <= 0.0001 on lower dimensional problems. For higher + * dimensional problems, larger values may be preferable. + * + * [1] R. Brits, A. P. Engelbrecht and B. Bergh. A Niching Particle Swarm + * Optimizer In Proceedings of the 4th Asia-Pacific Conference on Simulated + * Evolution and Learning (SEAL'02), 2002, 2, 692-696 [2] E. �zcan and M. + * Yilmaz. Particle Swarms for Multimodal Optimization. In: ICANNGA (1), Seiten + * 366�375, 2007 * */ public class NichePSO implements InterfaceAdditionalPopulationInformer, InterfaceOptimizer, java.io.Serializable { -/** - * - */ - private static final long serialVersionUID = 2036532085674554490L; -/********************************************************************************************************************** - * members - */ - // nichePSO Parameter - protected int mainSwarmSize = 75; - protected double maxAllowedSwarmRadius = 0.0001; // formally limits the swarm radius of the subswarms - - // Parameter for the mainswarm + /** + * + */ + private static final long serialVersionUID = 2036532085674554490L; + /** + * ******************************************************************************************************************** + * members + */ + // nichePSO Parameter + protected int mainSwarmSize = 75; + protected double maxAllowedSwarmRadius = 0.0001; // formally limits the swarm radius of the subswarms + // Parameter for the mainswarm // protected double mainSwarmPhi1 = 1.2; // protected double mainSwarmPhi2 = 0; // by default no communication in the mainswarm - protected PSOTopologyEnum mainSwarmTopology = PSOTopologyEnum.grid; // = 1; - protected int mainSwarmTopologyRange = 0; - private int mainSwarmAlgoType = 0; // 0: inertness, 1: constriction + protected PSOTopologyEnum mainSwarmTopology = PSOTopologyEnum.grid; // = 1; + protected int mainSwarmTopologyRange = 0; + private int mainSwarmAlgoType = 0; // 0: inertness, 1: constriction // private InterfaceParameterAging mainSwarmParamAging = new LinearParameterAging(); - protected ParameterControlManager paramControl = new ParameterControlManager(); - - boolean returnRepresentativeSolutionsOnly = true; // if true only the representatives of every subswarm are returned, else every particles pbest - boolean partlyInactive = false; // used to inactivate parts of the optimizer to see the effect on the performance - private boolean verbose = false; // print events on the console - transient boolean log = false; // for debugging: produce the NichePSO-file and FinalSuggestedOptima-plot with the elite - transient boolean plotFinal = false; // plot finalSuggestedOptima - protected boolean plot = false; // produce plots - protected boolean useSinglePlotWindow = true; - transient boolean savePlots = false; // save produced plots as jpegs (turn off for many multiruns...) - protected int showCycle = 10; // produce a plot every n generations - protected transient String dirForCurrentExperiment = "unset"; - - // the main swarm and the subswarms - protected ParticleSubSwarmOptimization mainSwarm = new ParticleSubSwarmOptimization(); - protected Vector subSwarms = new Vector(); - protected ParticleSubSwarmOptimization subswarmOptimizerTemplate = new ParticleSubSwarmOptimization(); - // individuals to be reinitialized in the next iteration - protected Vector indicesToReinit = null; + protected ParameterControlManager paramControl = new ParameterControlManager(); + boolean returnRepresentativeSolutionsOnly = true; // if true only the representatives of every subswarm are returned, else every particles pbest + boolean partlyInactive = false; // used to inactivate parts of the optimizer to see the effect on the performance + private boolean verbose = false; // print events on the console + transient boolean log = false; // for debugging: produce the NichePSO-file and FinalSuggestedOptima-plot with the elite + transient boolean plotFinal = false; // plot finalSuggestedOptima + protected boolean plot = false; // produce plots + protected boolean useSinglePlotWindow = true; + transient boolean savePlots = false; // save produced plots as jpegs (turn off for many multiruns...) + protected int showCycle = 10; // produce a plot every n generations + protected transient String dirForCurrentExperiment = "unset"; + // the main swarm and the subswarms + protected ParticleSubSwarmOptimization mainSwarm = new ParticleSubSwarmOptimization(); + protected Vector subSwarms = new Vector(); + protected ParticleSubSwarmOptimization subswarmOptimizerTemplate = new ParticleSubSwarmOptimization(); + // individuals to be reinitialized in the next iteration + protected Vector indicesToReinit = null; + // the strategies + protected InterfaceDeactivationStrategy deactivationStrategy = new StandardDeactivationStrategy(); + protected InterfaceMergingStrategy mergingStrategy = new StandardMergingStrategy(); + protected InterfaceAbsorptionStrategy absorptionStrategy = new StandardAbsorptionStrategy(); + protected InterfaceSubswarmCreationStrategy subswarmCreationStrategy = new StandardSubswarmCreationStrategy(); + // the problem + protected InterfaceOptimizationProblem m_Problem = new FM0Problem(); + // only used by island model ? + protected String m_Identifier = ""; + // eventListener + transient protected InterfacePopulationChangedEventListener m_Listener; + // for debugging: file containing the output + transient protected BufferedWriter outputFile = null; + // for debugging and plotting ----------------------------------------------- + transient protected TopoPlot m_TopologySwarm; + transient protected boolean m_shownextplot = false; + transient protected boolean deactivationOccured = false; + transient protected boolean mergingOccurd = false; + transient protected boolean absorbtionOccurd = false; + transient protected boolean creationOccurd = false; + // deactivation + transient protected Vector deactivatedSwarm; + // merging + transient protected Vector borg; + transient protected Vector others; + transient protected Vector borgbest; + transient protected Vector othersbest; + // absorbtion + transient protected Vector indytoabsorb; + // subswarmcreation + transient protected Vector indyconverged; + transient protected Vector convergedneighbor; + //----------------------------------------------------------------------------- + public static final String stdDevKey = "StdDevKey"; + public static final String fitArchiveKey = "FitnessArchiveKey"; + // by default, calculate the individuals fitness std dev using this number of past fitness values + public static final int defaultFitStdDevHorizon = 3; - // the strategies - protected InterfaceDeactivationStrategy deactivationStrategy = new StandardDeactivationStrategy(); - protected InterfaceMergingStrategy mergingStrategy = new StandardMergingStrategy(); - protected InterfaceAbsorptionStrategy absorptionStrategy = new StandardAbsorptionStrategy(); - protected InterfaceSubswarmCreationStrategy subswarmCreationStrategy = new StandardSubswarmCreationStrategy(); - - // the problem - protected InterfaceOptimizationProblem m_Problem = new FM0Problem(); - - // only used by island model ? - protected String m_Identifier = ""; + /** + * ******************************************************************************************************************** + * ctors, clone + */ + /** + * @tested + * + */ + public NichePSO() { + if (log) { + initLogFile(); + } + initMainSwarm(); // not really necessary if init is called before optimization but this way init doesnt change the parameters of a newly constructed object + initSubswarmOptimizerTemplate(); - // eventListener - transient protected InterfacePopulationChangedEventListener m_Listener; - - // for debugging: file containing the output - transient protected BufferedWriter outputFile = null; + hideHideable(); + } - // for debugging and plotting ----------------------------------------------- - transient protected TopoPlot m_TopologySwarm; - transient protected boolean m_shownextplot = false; - transient protected boolean deactivationOccured = false; - transient protected boolean mergingOccurd = false; - transient protected boolean absorbtionOccurd = false; - transient protected boolean creationOccurd = false; - // deactivation - transient protected Vector deactivatedSwarm; - // merging - transient protected Vector borg; - transient protected Vector others; - transient protected Vector borgbest; - transient protected Vector othersbest; - // absorbtion - transient protected Vector indytoabsorb; - // subswarmcreation - transient protected Vector indyconverged; - transient protected Vector convergedneighbor; - //----------------------------------------------------------------------------- - public static final String stdDevKey = "StdDevKey"; - public static final String fitArchiveKey = "FitnessArchiveKey"; - // by default, calculate the individuals fitness std dev using this number of past fitness values - public static final int defaultFitStdDevHorizon = 3; - -/********************************************************************************************************************** - * ctors, clone - */ - /** @tested - * - */ - public NichePSO(){ - if (log) { - initLogFile(); - } - initMainSwarm(); // not really necessary if init is called before optimization but this way init doesnt change the parameters of a newly constructed object - initSubswarmOptimizerTemplate(); - - hideHideable(); - } + /** + * Take care that all properties which may be hidden (and currently are) + * send a "hide" message to the Java Bean properties. This is called by + * PropertySheetPanel in use with the GenericObjectEditor. + */ + public void hideHideable() { + // the following properties are hidden from the GUI in the ANPSO ctor but should be shown for the NichePSO + GenericObjectEditor.setHideProperty(getClass(), "subswarmCreationStrategy", false); + GenericObjectEditor.setHideProperty(getClass(), "mergingStrategy", false); + GenericObjectEditor.setHideProperty(getClass(), "absorptionStrategy", false); + GenericObjectEditor.setHideProperty(getClass(), "maxAllowedSwarmRadius", false); + } + + /** + * @tested @param a + */ + public NichePSO(NichePSO a) { + this.mainSwarmSize = a.mainSwarmSize; + this.maxAllowedSwarmRadius = a.maxAllowedSwarmRadius; - /** - * Take care that all properties which may be hidden (and currently are) send a "hide" message to the Java Bean properties. - * This is called by PropertySheetPanel in use with the GenericObjectEditor. - */ - public void hideHideable() { - // the following properties are hidden from the GUI in the ANPSO ctor but should be shown for the NichePSO - GenericObjectEditor.setHideProperty(getClass(), "subswarmCreationStrategy", false); - GenericObjectEditor.setHideProperty(getClass(), "mergingStrategy", false); - GenericObjectEditor.setHideProperty(getClass(), "absorptionStrategy", false); - GenericObjectEditor.setHideProperty(getClass(), "maxAllowedSwarmRadius", false); - } - - /** @tested - * @param a - */ - public NichePSO(NichePSO a){ - this.mainSwarmSize = a.mainSwarmSize; - this.maxAllowedSwarmRadius = a.maxAllowedSwarmRadius; - // this.mainSwarmPhi1 = a.mainSwarmPhi1; // this.mainSwarmPhi2 = a.mainSwarmPhi2; - this.mainSwarmTopology = a.mainSwarmTopology; - this.mainSwarmTopologyRange = a.mainSwarmTopologyRange; - this.mainSwarmAlgoType = a.mainSwarmAlgoType; + this.mainSwarmTopology = a.mainSwarmTopology; + this.mainSwarmTopologyRange = a.mainSwarmTopologyRange; + this.mainSwarmAlgoType = a.mainSwarmAlgoType; // this.mainSwarmParamAging = (InterfaceParameterAging)a.mainSwarmParamAging.clone(); - this.paramControl = (ParameterControlManager)a.paramControl.clone(); - - this.returnRepresentativeSolutionsOnly = a.returnRepresentativeSolutionsOnly; - this.partlyInactive = a.partlyInactive; - this.verbose = a.verbose; - this.log = a.log; - this.useSinglePlotWindow = a.useSinglePlotWindow; - this.savePlots = a.savePlots; - this.showCycle = a.showCycle; - this.SetDirForCurrentExperiment(a.getDirForCurrentExperiment()); - - this.setMainSwarm((ParticleSubSwarmOptimization)a.getMainSwarm().clone()); - this.SetSubSwarms((Vector)a.getSubSwarms().clone()); - this.setSubswarmOptimizerTemplate((ParticleSubSwarmOptimization)a.getSubswarmOptimizerTemplate().clone()); - - this.deactivationStrategy = (InterfaceDeactivationStrategy)a.deactivationStrategy.clone(); - this.mergingStrategy = (InterfaceMergingStrategy)a.mergingStrategy.clone(); - this.absorptionStrategy = (InterfaceAbsorptionStrategy)a.absorptionStrategy.clone(); - this.subswarmCreationStrategy = (InterfaceSubswarmCreationStrategy)a.subswarmCreationStrategy.clone(); - - this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone(); - - this.m_Identifier = a.m_Identifier; - } - - /** @tested - * (non-Javadoc) @see java.lang.Object#clone() - */ + this.paramControl = (ParameterControlManager) a.paramControl.clone(); + + this.returnRepresentativeSolutionsOnly = a.returnRepresentativeSolutionsOnly; + this.partlyInactive = a.partlyInactive; + this.verbose = a.verbose; + this.log = a.log; + this.useSinglePlotWindow = a.useSinglePlotWindow; + this.savePlots = a.savePlots; + this.showCycle = a.showCycle; + this.SetDirForCurrentExperiment(a.getDirForCurrentExperiment()); + + this.setMainSwarm((ParticleSubSwarmOptimization) a.getMainSwarm().clone()); + this.SetSubSwarms((Vector) a.getSubSwarms().clone()); + this.setSubswarmOptimizerTemplate((ParticleSubSwarmOptimization) a.getSubswarmOptimizerTemplate().clone()); + + this.deactivationStrategy = (InterfaceDeactivationStrategy) a.deactivationStrategy.clone(); + this.mergingStrategy = (InterfaceMergingStrategy) a.mergingStrategy.clone(); + this.absorptionStrategy = (InterfaceAbsorptionStrategy) a.absorptionStrategy.clone(); + this.subswarmCreationStrategy = (InterfaceSubswarmCreationStrategy) a.subswarmCreationStrategy.clone(); + + this.m_Problem = (InterfaceOptimizationProblem) a.m_Problem.clone(); + + this.m_Identifier = a.m_Identifier; + } + + /** + * @tested (non-Javadoc) + * @see java.lang.Object#clone() + */ @Override - public Object clone(){ - return (Object) new NichePSO(this); - } - -/********************************************************************************************************************** - * inits - */ - /** @tested ps - * sets the mainswarm according to the NichePSO Parameters, - * called via init() - */ - protected void initMainSwarm(){ - // pass NichePSO parameter on to the mainswarmoptimzer - setMainSwarmSize(mainSwarmSize); // (particles are initialized later via init) - getMainSwarm().setProblem(m_Problem); - getMainSwarm().SetMaxAllowedSwarmRadius(maxAllowedSwarmRadius); - getMainSwarm().getPopulation().setGenerationTo(0); - - // choose PSO-type for the mainswarmoptimizer - getMainSwarm().setGcpso(false); + public Object clone() { + return (Object) new NichePSO(this); + } + + /** + * ******************************************************************************************************************** + * inits + */ + /** + * @tested ps sets the mainswarm according to the NichePSO Parameters, + * called via init() + */ + protected void initMainSwarm() { + // pass NichePSO parameter on to the mainswarmoptimzer + setMainSwarmSize(mainSwarmSize); // (particles are initialized later via init) + getMainSwarm().setProblem(m_Problem); + getMainSwarm().SetMaxAllowedSwarmRadius(maxAllowedSwarmRadius); + getMainSwarm().getPopulation().setGenerationTo(0); + + // choose PSO-type for the mainswarmoptimizer + getMainSwarm().setGcpso(false); // getMainSwarm().setAlgoType(new SelectedTag("Inertness")); - getMainSwarm().setParameterControl(new ParamAdaption[]{getDefaultInertnessAdaption()}); - setMainSwarmAlgoType(getMainSwarm().getAlgoType().setSelectedTag(mainSwarmAlgoType)); // set algo type, may influence aging - + getMainSwarm().setParameterControl(new ParamAdaption[]{getDefaultInertnessAdaption()}); + setMainSwarmAlgoType(getMainSwarm().getAlgoType().setSelectedTag(mainSwarmAlgoType)); // set algo type, may influence aging + // getMainSwarm().setPhi1(mainSwarmPhi1); // cognitive component "tendency to return to the best position visited so far" // getMainSwarm().setPhi2(mainSwarmPhi2); // social component "tendency to be attracted towards the best position found in its neighbourhood." - - getMainSwarm().setTopology(mainSwarmTopology); - getMainSwarm().setTopologyRange(mainSwarmTopologyRange); - } - - public static ParamAdaption getDefaultInertnessAdaption() { - return new LinearParamAdaption("inertnessOrChi", 0.7, 0.2); - } - - /** @tested - * inits the template used for creating subswarms - * this is only called in the ctor not via init() - * (would overwrite changes set from outside for the next run) - * - */ - protected void initSubswarmOptimizerTemplate(){ - // pass on the parameters set via NichePSO (done in the analogous nichePSO-Setters as well -> no init() necessary) - getSubswarmOptimizerTemplate().setProblem(m_Problem); - getSubswarmOptimizerTemplate().SetMaxAllowedSwarmRadius(maxAllowedSwarmRadius); - - // choose PSO-type for the subswarmoptimizer - getSubswarmOptimizerTemplate().setGcpso(true); - getSubswarmOptimizerTemplate().setRho(0.1); // on 2D Problems empirically better than default value 1 - getSubswarmOptimizerTemplate().getAlgoType().setSelectedTag("Constriction");//setAlgoType(new SelectedTag("Inertness")); - - //"Several studies propose different values for these parameters" (http://tracer.uc3m.es/tws/pso/parameters.html) - //Bergh2002 p.87 - //Particle Swarm Optimization - an introduction and its recent developments slide 22 P6 (in the constriction variant) - getSubswarmOptimizerTemplate().setInertnessOrChi(0.7298437881283576); - getSubswarmOptimizerTemplate().setPhi1(2.05); - getSubswarmOptimizerTemplate().setPhi2(2.05); - - //subswarmOptimizerTemplate.initGCPSOMember(); + + getMainSwarm().setTopology(mainSwarmTopology); + getMainSwarm().setTopologyRange(mainSwarmTopologyRange); + } + + public static ParamAdaption getDefaultInertnessAdaption() { + return new LinearParamAdaption("inertnessOrChi", 0.7, 0.2); + } + + /** + * @tested inits the template used for creating subswarms this is only + * called in the ctor not via init() (would overwrite changes set from + * outside for the next run) + * + */ + protected void initSubswarmOptimizerTemplate() { + // pass on the parameters set via NichePSO (done in the analogous nichePSO-Setters as well -> no init() necessary) + getSubswarmOptimizerTemplate().setProblem(m_Problem); + getSubswarmOptimizerTemplate().SetMaxAllowedSwarmRadius(maxAllowedSwarmRadius); + + // choose PSO-type for the subswarmoptimizer + getSubswarmOptimizerTemplate().setGcpso(true); + getSubswarmOptimizerTemplate().setRho(0.1); // on 2D Problems empirically better than default value 1 + getSubswarmOptimizerTemplate().getAlgoType().setSelectedTag("Constriction");//setAlgoType(new SelectedTag("Inertness")); + + //"Several studies propose different values for these parameters" (http://tracer.uc3m.es/tws/pso/parameters.html) + //Bergh2002 p.87 + //Particle Swarm Optimization - an introduction and its recent developments slide 22 P6 (in the constriction variant) + getSubswarmOptimizerTemplate().setInertnessOrChi(0.7298437881283576); + getSubswarmOptimizerTemplate().setPhi1(2.05); + getSubswarmOptimizerTemplate().setPhi2(2.05); + + //subswarmOptimizerTemplate.initGCPSOMember(); // getSubswarmOptimizerTemplate().getPopulation().setMaxHistoryLength(25); - } + } - /** @tested - * returns the optimizer that should be used to create a new subswarm - * @return an optimizer with parameters set according to the nichePSO - */ - public ParticleSubSwarmOptimization getNewSubSwarmOptimizer(){ - //initSubswarmOptimizerTemplate(); - ParticleSubSwarmOptimization template = (ParticleSubSwarmOptimization)getSubswarmOptimizerTemplate().clone(); // this implicitely clones the problem but does not initialize it again... - template.setProblem(this.m_Problem); //... let all subswarms use the same correct initialised problem instance - return template; - } - - /** @tested junit, junit&, emp, ... - * (non-Javadoc) @see javaeva.server.oa.go.Strategies.InterfaceOptimizer#init() - */ - @Override - public void init() { // (called right before next optimize/mutltirun) - // initialize main swarm - initMainSwarm(); // MOE: auch bei multirun: m�gliche �nderungen an Gr��e, AlgoType, maxrad, delta etc. aus letzter Optimierung zur�cksetzen - // mainSwarm.init(): - // - place all indys rndly in search space (depends on: mainSwarmSize, problem) - // - use rnd init velocity vector - // - evaluate (depends on: problem) - // - init fit-archive,stddev, pbest, PBestImprovementsInARow - // - update mbestindividual, maxposdist - // - set particleIndexCounter - getMainSwarm().init(); - - // initialize subswarms - //initSubswarmOptimizerTemplate(); //only in ctor, would change parameters for the next multirun - //subwarmOptimizerTemplate.init(); // dont init and evaluate individuals ! - SetSubSwarms(new Vector()); // dont want to use subswarms from old optimization run (especially not in multiruns)... - indicesToReinit=null; - // show in plot - //MainSwarm.setShow(true); - if (isPlot()) { - initPlotSwarm(); - } - } - - /** @tested - * (non-Javadoc) - * uses the given population and basically sets rnd velocity vectors (if reset == false) - */ - @Override - public void initByPopulation(Population pop, boolean reset) { - // initByPopulation(...): - // - use indys from pop - // - use rnd init velocity vector - // - evaluate (depends on: problem) - // - init fit-archive,stddev and pbest - getMainSwarm().initByPopulation(pop, reset); + /** + * @tested returns the optimizer that should be used to create a new + * subswarm + * @return an optimizer with parameters set according to the nichePSO + */ + public ParticleSubSwarmOptimization getNewSubSwarmOptimizer() { + //initSubswarmOptimizerTemplate(); + ParticleSubSwarmOptimization template = (ParticleSubSwarmOptimization) getSubswarmOptimizerTemplate().clone(); // this implicitely clones the problem but does not initialize it again... + template.setProblem(this.m_Problem); //... let all subswarms use the same correct initialised problem instance + return template; + } - initSubswarmOptimizerTemplate(); - } - -/********************************************************************************************************************** - * Optimization - */ - /** @tested - * (non-Javadoc) @see javaeva.server.oa.go.Strategies.InterfaceOptimizer#optimize() - */ + /** + * @tested junit, junit&, emp, ... (non-Javadoc) + * @see javaeva.server.oa.go.Strategies.InterfaceOptimizer#init() + */ @Override - public void optimize() { + public void init() { // (called right before next optimize/mutltirun) + // initialize main swarm + initMainSwarm(); // MOE: auch bei multirun: m�gliche �nderungen an Gr��e, AlgoType, maxrad, delta etc. aus letzter Optimierung zur�cksetzen + // mainSwarm.init(): + // - place all indys rndly in search space (depends on: mainSwarmSize, problem) + // - use rnd init velocity vector + // - evaluate (depends on: problem) + // - init fit-archive,stddev, pbest, PBestImprovementsInARow + // - update mbestindividual, maxposdist + // - set particleIndexCounter + getMainSwarm().init(); + + // initialize subswarms + //initSubswarmOptimizerTemplate(); //only in ctor, would change parameters for the next multirun + //subwarmOptimizerTemplate.init(); // dont init and evaluate individuals ! + SetSubSwarms(new Vector()); // dont want to use subswarms from old optimization run (especially not in multiruns)... + indicesToReinit = null; + // show in plot + //MainSwarm.setShow(true); + if (isPlot()) { + initPlotSwarm(); + } + } + + /** + * @tested (non-Javadoc) uses the given population and basically sets rnd + * velocity vectors (if reset == false) + */ + @Override + public void initByPopulation(Population pop, boolean reset) { + // initByPopulation(...): + // - use indys from pop + // - use rnd init velocity vector + // - evaluate (depends on: problem) + // - init fit-archive,stddev and pbest + getMainSwarm().initByPopulation(pop, reset); + + initSubswarmOptimizerTemplate(); + } + + /** + * ******************************************************************************************************************** + * Optimization + */ + /** + * @tested (non-Javadoc) + * @see javaeva.server.oa.go.Strategies.InterfaceOptimizer#optimize() + */ + @Override + public void optimize() { // System.out.println(BeanInspector.toString(getMainSwarm())); - if (isVerbose()) { - Population pop = getPopulation(); - System.out.println("pop bef: " + pop.size() + " " + pop.getFunctionCalls()); - } - // main swarm: - if (getMainSwarm().getPopulation().size() == 0){// || mainSwarm.getPopulation().size() == 1){ - if (isVerbose()) { - System.out.print("MainSwarm size is 0\n"); - } - // increment the generationcount for the terminator: - // 1 generation equals one optimize call including the optimization of the - // (possibly empty) mainswarm and all subswarms - getMainSwarm().getPopulation().incrGeneration(); - } - else { - getMainSwarm().optimize(); + if (isVerbose()) { + Population pop = getPopulation(); + System.out.println("pop bef: " + pop.size() + " " + pop.getFunctionCalls()); + } + // main swarm: + if (getMainSwarm().getPopulation().size() == 0) {// || mainSwarm.getPopulation().size() == 1){ + if (isVerbose()) { + System.out.print("MainSwarm size is 0\n"); } - - maybeReinitIndies(); + // increment the generationcount for the terminator: + // 1 generation equals one optimize call including the optimization of the + // (possibly empty) mainswarm and all subswarms + getMainSwarm().getPopulation().incrGeneration(); + } else { + getMainSwarm().optimize(); + } - // subswarms: - for (int i = 0; i < getSubSwarms().size(); ++i) { - ParticleSubSwarmOptimization subswarm = getSubSwarms().get(i); - if (subswarm.isActive()) { - subswarm.optimize(); - } + maybeReinitIndies(); + + // subswarms: + for (int i = 0; i < getSubSwarms().size(); ++i) { + ParticleSubSwarmOptimization subswarm = getSubSwarms().get(i); + if (subswarm.isActive()) { + subswarm.optimize(); + } // System.out.println(i + " " + subswarm.getPopulation().getFunctionCalls()); - } - - // deactivation: - deactivateSubSwarmsIfPossible(); - - // merging: - mergeSubswarmsIfPossible(); - - // absorption: - absorbParticlesIfPossible(); - - // create new subswarms: - createSubswarmIfPossible(); - - firePropertyChangedEvent("NextGenerationPerformed"); // calls Listener that sth changed... - if (isVerbose()) { - Population pop = getPopulation(); - System.out.println("pop aft: " + pop.size() + " " + pop.getFunctionCalls()); - } - - /** plotting **********************************************************************************/ - if (isPlot()){ - doPlot(); - } - /** end plotting *******************************************************************************/ - - // reset flags etc for: - // deactivation - deactivationOccured = false; - deactivatedSwarm = new Vector(); + } + + // deactivation: + deactivateSubSwarmsIfPossible(); + + // merging: + mergeSubswarmsIfPossible(); + + // absorption: + absorbParticlesIfPossible(); + + // create new subswarms: + createSubswarmIfPossible(); + + firePropertyChangedEvent("NextGenerationPerformed"); // calls Listener that sth changed... + if (isVerbose()) { + Population pop = getPopulation(); + System.out.println("pop aft: " + pop.size() + " " + pop.getFunctionCalls()); + } + + /** + * plotting ********************************************************************************* + */ + if (isPlot()) { + doPlot(); + } + /** + * end plotting ****************************************************************************** + */ + // reset flags etc for: + // deactivation + deactivationOccured = false; + deactivatedSwarm = new Vector(); // reinitedSwarm = new Vector(); - // merging - mergingOccurd = false; - borg = new Vector(); - others = new Vector(); - borgbest = new Vector(); - othersbest = new Vector(); - // absorbtion - absorbtionOccurd = false; - indytoabsorb = new Vector(); - // subswarmcreation - creationOccurd = false; - indyconverged = new Vector(); - convergedneighbor = new Vector(); - } + // merging + mergingOccurd = false; + borg = new Vector(); + others = new Vector(); + borgbest = new Vector(); + othersbest = new Vector(); + // absorbtion + absorbtionOccurd = false; + indytoabsorb = new Vector(); + // subswarmcreation + creationOccurd = false; + indyconverged = new Vector(); + convergedneighbor = new Vector(); + } - /** - * Check if lone individuals are scheduled for reinitialization into - * the main swarm. This happens after subswarm deactivation. - * Should be called only directly after the main swarm optimization call. - */ - protected void maybeReinitIndies() { - if (indicesToReinit!=null && (indicesToReinit.size()>0)) { // add new individuals - getMainSwarm().reinitIndividuals(indicesToReinit); - indicesToReinit.clear(); - } - } + /** + * Check if lone individuals are scheduled for reinitialization into the + * main swarm. This happens after subswarm deactivation. Should be called + * only directly after the main swarm optimization call. + */ + protected void maybeReinitIndies() { + if (indicesToReinit != null && (indicesToReinit.size() > 0)) { // add new individuals + getMainSwarm().reinitIndividuals(indicesToReinit); + indicesToReinit.clear(); + } + } - /** - * Schedule new particles to be added to this swarm, rndly inited over the search space by the problem - * @param size number of particles to be created - * @param particleIndices set of indices that should be used for the added particles, if null new indices are created - */ - public void scheduleNewParticlesToPopulation(int[] particleIndices) { - if (particleIndices != null) { - if (indicesToReinit==null) { - indicesToReinit = new Vector(); + /** + * Schedule new particles to be added to this swarm, rndly inited over the + * search space by the problem + * + * @param size number of particles to be created + * @param particleIndices set of indices that should be used for the added + * particles, if null new indices are created + */ + public void scheduleNewParticlesToPopulation(int[] particleIndices) { + if (particleIndices != null) { + if (indicesToReinit == null) { + indicesToReinit = new Vector(); + } + indicesToReinit.add(particleIndices); + } + } + + protected void doPlot() { + m_shownextplot = (deactivationOccured || mergingOccurd || absorbtionOccurd || creationOccurd);// repopoccurd || reinitoccurd); + if (this.getMainSwarm().getPopulation().getGeneration() % this.getShowCycle() == 0) {// || m_shownextplot){ + // plot merging step + if (mergingOccurd) { + plotMainSwarm(false); + plotMergingCondition(); + if (savePlots) { + String generation = String.valueOf(getMainSwarm().getPopulation().getGeneration()); + // saveCurrentPlotAsJPG(getCurrentDateAsString()+generation+"a"); + } else { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { } - indicesToReinit.add(particleIndices); - } - } - - protected void doPlot() { - m_shownextplot = (deactivationOccured || mergingOccurd || absorbtionOccurd || creationOccurd);// repopoccurd || reinitoccurd); - if (this.getMainSwarm().getPopulation().getGeneration()%this.getShowCycle() == 0){// || m_shownextplot){ - // plot merging step - if (mergingOccurd){ - plotMainSwarm(false); - plotMergingCondition(); - if (savePlots){ - String generation = String.valueOf(getMainSwarm().getPopulation().getGeneration()); - // saveCurrentPlotAsJPG(getCurrentDateAsString()+generation+"a"); - } else{ - try { - Thread.sleep(1000); - } catch (InterruptedException e) {} - } - } - // plot main step - synchronized(m_TopologySwarm.getClass()){ - plotMainSwarm(false); - plotSubSwarms(); - //plotAdditionalInfo(); - //plotAllStdDevsInMainSwarm(); - //plotBoundStdDevInMainSwarm(0.03); - } - if (savePlots){ - String gen = String.valueOf(getMainSwarm().getPopulation().getGeneration()); - // saveCurrentPlotAsJPG(getCurrentDateAsString()+gen+"b"); - }else{ - try { - Thread.sleep(1000); - } catch (InterruptedException e) {} - } - - //plotBoundStdDevInMainSwarm(0.5); - m_shownextplot = false; - } - } - + } + } + // plot main step + synchronized (m_TopologySwarm.getClass()) { + plotMainSwarm(false); + plotSubSwarms(); + //plotAdditionalInfo(); + //plotAllStdDevsInMainSwarm(); + //plotBoundStdDevInMainSwarm(0.03); + } + if (savePlots) { + String gen = String.valueOf(getMainSwarm().getPopulation().getGeneration()); + // saveCurrentPlotAsJPG(getCurrentDateAsString()+gen+"b"); + } else { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + } -/********************************************************************************************************************** - * Deactivation - */ - protected void deactivationEventFor(ParticleSubSwarmOptimization subswarm) { - if (isVerbose()) { - System.out.println("deactivating subswarm"); - } - deactivatedSwarm.add(subswarm); // only for plotting - deactivationOccured = true; - } - - /** @tested junit - * deactivates the subswarms according to the decativation strategy - */ - protected void deactivateSubSwarmsIfPossible(){ - // check for every subswarm... - for (int i = 0; i < getSubSwarms().size(); ++i){ - ParticleSubSwarmOptimization currentsubswarm = getSubSwarms().get(i); - //.. if it meets the criterion of the deactivation strategy - if (getDeactivationStrategy().shouldDeactivateSubswarm(currentsubswarm)){ - if (isVerbose()) { - System.out.println("deactivation in NPSO!"); - } - deactivationEventFor(currentsubswarm); - scheduleNewParticlesToPopulation(getDeactivationStrategy().deactivateSubswarm(currentsubswarm, getMainSwarm())); - } - } - } - - protected double getAvgActiveSubSwarmSize(){ - double avgSize = 0; - int actCnt = 0; - // check for every subswarm... - for (int i = 0; i < getSubSwarms().size(); ++i){ - ParticleSubSwarmOptimization currentsubswarm = getSubSwarms().get(i); - if (currentsubswarm.isActive()) { - actCnt++; - avgSize+=currentsubswarm.m_Population.size(); - } - } - if (actCnt>0) { - return (avgSize/actCnt); - } - else { - return 0; - } - } - - protected int countActiveSubswarms(){ - int actCnt = 0; - // check for every subswarm... - for (int i = 0; i < getSubSwarms().size(); ++i){ - ParticleSubSwarmOptimization currentsubswarm = getSubSwarms().get(i); - if (currentsubswarm.isActive()) { - actCnt++; - } - } - return actCnt; - } -/********************************************************************************************************************** - * Merging - */ - protected void mergingEventFor(int i, int j){ - if (isVerbose()) { - System.out.print("merge condition \n"); - } - ParticleSubSwarmOptimization borg = getSubSwarms().get(i); - ParticleSubSwarmOptimization others= getSubSwarms().get(j); - this.borg.add((ParticleSubSwarmOptimization)borg.clone()); // for plotting only - this.others.add((ParticleSubSwarmOptimization)others.clone()); // for plotting only - mergingOccurd = true; - this.borgbest.add(borg.m_BestIndividual); // for plotting only - this.othersbest.add(others.m_BestIndividual); // for plotting only - } + //plotBoundStdDevInMainSwarm(0.5); + m_shownextplot = false; + } + } - /** @tested junit - * merges the subswarms according to the merging strategy - */ - protected void mergeSubswarmsIfPossible(){ - boolean runagain = false; - if (isVerbose()) { - System.out.println("possibly merging " + getSubSwarms().size() + " subswarms..."); + /** + * ******************************************************************************************************************** + * Deactivation + */ + protected void deactivationEventFor(ParticleSubSwarmOptimization subswarm) { + if (isVerbose()) { + System.out.println("deactivating subswarm"); + } + deactivatedSwarm.add(subswarm); // only for plotting + deactivationOccured = true; + } + + /** + * @tested junit deactivates the subswarms according to the decativation + * strategy + */ + protected void deactivateSubSwarmsIfPossible() { + // check for every subswarm... + for (int i = 0; i < getSubSwarms().size(); ++i) { + ParticleSubSwarmOptimization currentsubswarm = getSubSwarms().get(i); + //.. if it meets the criterion of the deactivation strategy + if (getDeactivationStrategy().shouldDeactivateSubswarm(currentsubswarm)) { + if (isVerbose()) { + System.out.println("deactivation in NPSO!"); + } + deactivationEventFor(currentsubswarm); + scheduleNewParticlesToPopulation(getDeactivationStrategy().deactivateSubswarm(currentsubswarm, getMainSwarm())); } - // check for every two subswarms... - for (int i = 0; i < getSubSwarms().size(); ++i){ + } + } + + protected double getAvgActiveSubSwarmSize() { + double avgSize = 0; + int actCnt = 0; + // check for every subswarm... + for (int i = 0; i < getSubSwarms().size(); ++i) { + ParticleSubSwarmOptimization currentsubswarm = getSubSwarms().get(i); + if (currentsubswarm.isActive()) { + actCnt++; + avgSize += currentsubswarm.m_Population.size(); + } + } + if (actCnt > 0) { + return (avgSize / actCnt); + } else { + return 0; + } + } + + protected int countActiveSubswarms() { + int actCnt = 0; + // check for every subswarm... + for (int i = 0; i < getSubSwarms().size(); ++i) { + ParticleSubSwarmOptimization currentsubswarm = getSubSwarms().get(i); + if (currentsubswarm.isActive()) { + actCnt++; + } + } + return actCnt; + } + + /** + * ******************************************************************************************************************** + * Merging + */ + protected void mergingEventFor(int i, int j) { + if (isVerbose()) { + System.out.print("merge condition \n"); + } + ParticleSubSwarmOptimization borg = getSubSwarms().get(i); + ParticleSubSwarmOptimization others = getSubSwarms().get(j); + this.borg.add((ParticleSubSwarmOptimization) borg.clone()); // for plotting only + this.others.add((ParticleSubSwarmOptimization) others.clone()); // for plotting only + mergingOccurd = true; + this.borgbest.add(borg.m_BestIndividual); // for plotting only + this.othersbest.add(others.m_BestIndividual); // for plotting only + } + + /** + * @tested junit merges the subswarms according to the merging strategy + */ + protected void mergeSubswarmsIfPossible() { + boolean runagain = false; + if (isVerbose()) { + System.out.println("possibly merging " + getSubSwarms().size() + " subswarms..."); + } + // check for every two subswarms... + for (int i = 0; i < getSubSwarms().size(); ++i) { // System.out.print(" " + getSubSwarms().get(i).getPopulation().size()); - for (int j = i+1; j < getSubSwarms().size(); ++j){ - //... if they should be merged according to the merging strategy - if (getMergingStrategy().shouldMergeSubswarms(getSubSwarms().get(i), getSubSwarms().get(j))){ - if (isVerbose()) { - System.out.println("Merging in NPSO!"); - } - mergingEventFor(i,j); // for plotting - getMergingStrategy().mergeSubswarms(i, j, getSubSwarms(), getMainSwarm()); - runagain = true; // merged subswarm may overlap with another swarm now. This might not have been considered in this run... - --j; // subSwarms.size() has decreased and all elements >=j were shifted one position to the left - } - } - } -// System.out.println(); - if (runagain) { - mergeSubswarmsIfPossible(); - } - } - -/********************************************************************************************************************** - * Absorbtion - */ - /** @tested - * adds indy to an active subswarm, then removes indy from the mainswarm. - * @param indy - * @param subswarm - * @return - */ - protected void absorbtionEventFor(AbstractEAIndividual indy, ParticleSubSwarmOptimization subswarm){ - if (isVerbose()) { - System.out.print("Absorbtion \n"); - } - absorbtionOccurd = true; - this.indytoabsorb.add(indy); - } - - /** @tested junit - * absorbs the mainswarm particles into the subswarm according to the absorbtion strategy - */ - protected void absorbParticlesIfPossible(){ - boolean runagain = false; - // check for every particle in the main swarm... - for (int i = 0; i < getMainSwarm().getPopulation().size(); ++i){ - AbstractEAIndividual currentindy = getMainSwarm().getPopulation().getEAIndividual(i); - // ...if it matches the absorption-criterion for any subswarm: - for (int j = 0; j < getSubSwarms().size(); ++j){ - ParticleSubSwarmOptimization currentsubwarm = getSubSwarms().get(j); - if (getAbsorptionStrategy().shouldAbsorbParticleIntoSubswarm(currentindy, currentsubwarm, this.getMainSwarm())){ - if (isVerbose()) { - System.out.println("Absorbing particle (NPSO)"); - } - absorbtionEventFor(currentindy, currentsubwarm); - getAbsorptionStrategy().absorbParticle(currentindy, currentsubwarm, this.getMainSwarm()); - --i; // ith particle is removed, all indizes shift one position to the left - runagain = true; // if the absorbed particle provides a new best position, the radius of the swarm will change -> run absorption again - break; // dont try to absorb this particle again into another subswarm - } - } - } - if (runagain) { - absorbParticlesIfPossible(); - } - } - -/********************************************************************************************************************** - * Subswarm Creation - */ - protected void subswarmCreationEventFor(AbstractEAIndividual currentindy, ParticleSubSwarmOptimization subswarm) { - if (isVerbose()) { - System.out.print("creating subswarm\n"); - } - creationOccurd = true; - this.indyconverged.add(currentindy); - for (int i = 0; i < subswarm.getPopulation().size(); ++i){ - AbstractEAIndividual indy = subswarm.getPopulation().getEAIndividual(i); - if (indy.getIndyID()!=currentindy.getIndyID()){ - this.convergedneighbor.add(indy); - } - } - } - - /** @tested junit - * creates a subswarm from every particle in the mainswarm that meets the convergence-criteria of the creation strategy - */ - protected void createSubswarmIfPossible(){ - // for every particle... - for (int i = 0; i < getMainSwarm().getPopulation().size(); ++i){ - AbstractEAIndividual currentindy = getMainSwarm().getPopulation().getEAIndividual(i); - //... that meets the convergence-criteria of the creation strategie - if (getSubswarmCreationStrategy().shouldCreateSubswarm(currentindy,getMainSwarm())){ - if (isVerbose()) { - System.out.println("Creating sub swarm (NPSO)"); - } - // use an optimizer according to the template - ParticleSubSwarmOptimization newSubswarm = getNewSubSwarmOptimizer(); - // and create a subswarm from the given particle - getSubswarmCreationStrategy().createSubswarm(newSubswarm,currentindy,getMainSwarm()); - subswarmCreationEventFor(currentindy,newSubswarm); - // add the subswarm to the set of subswarms: - this.getSubSwarms().add(newSubswarm); - i=0; // start again because indizes changed and we dont know how... - } - } - } - -/********************************************************************************************************************** - * event listening - */ - /** @tested - * Something has changed - */ - protected void firePropertyChangedEvent (String name) { - if (this.m_Listener != null) { - this.m_Listener.registerPopulationStateChanged(this, name); - } - } - - /** @tested - * This method allows you to add the LectureGUI as listener to the Optimizer - * @param ea - */ - @Override - public void addPopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - this.m_Listener = ea; - } - @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - /** @tested nn - * This method is required to free the memory on a RMIServer, - * but there is nothing to implement. - */ - @Override - public void freeWilly() { - - } - -/********************************************************************************************************************** - * setter, getter: population and solutions - */ - /** @tested nn - * (non-Javadoc) @see eva2.server.go.strategies.InterfaceOptimizer#setPopulation(javaeva.server.oa.go.Populations.Population) - */ - @Override - public void setPopulation(Population pop) { - //pass on to mainswarm optimizer - getMainSwarm().setPopulation(pop); - } - - /** @tested junit, junit& - * @return a population consisting of copies from the mainswarm and all active subswarms - */ - public Population getActivePopulation(){ - // construct a metapop with clones from the mainswarm and all active subswarms - Population metapop = (Population)getMainSwarm().getPopulation().clone(); - for (int i = 0; i < getSubSwarms().size(); ++i){ - ParticleSubSwarmOptimization currentsubswarm = getSubSwarms().get(i); - if (currentsubswarm.isActive()){ - Population currentsubswarmpop = (Population)currentsubswarm.getPopulation().clone(); - metapop.addPopulation(currentsubswarmpop); - } - } - - // set correct number of generations - metapop.setGenerationTo(getMainSwarm().getPopulation().getGeneration()); - - // set correct number of function calls - int calls = getMainSwarm().getPopulation().getFunctionCalls(); - for (int i = 0; i < getSubSwarms().size(); ++i){ - ParticleSubSwarmOptimization currentsubswarm = getSubSwarms().get(i); - // calls from inactive populations have to be counted as well... - calls += currentsubswarm.getPopulation().getFunctionCalls(); - } - metapop.SetFunctionCalls(calls); - // care for consistent size: - metapop.synchSize(); - return metapop; - } - - /** @tested junit - * returns a population consisting of copies from the mainswarm and all subswarms - * (active and inactive, so the size of this Population is not necessarily constant). - * (Especially important for the call back regarding the output file... ) - * Beware: getPopulation().getPopulationSize() returns the !initial! size of the main swarm, - * the actual size of the complete population is accessed via getPopulation().size() - * @return a population consisting of copies from the mainswarm and all subswarms. - */ - @Override - public Population getPopulation() { - boolean activeOnly = true; // true makes problems if all subswarms are deactivated at the same time! - // construct a metapop with clones from the mainswarm and all subswarms - Population metapop = (Population)getMainSwarm().getPopulation().cloneWithoutInds(); - metapop.ensureCapacity(getMainSwarmSize()); - metapop.addPopulation(getMainSwarm().getPopulation()); - int activeCnt = 0; -// Population currentsubswarm; - for (int i = 0; i < getSubSwarms().size(); ++i){ -// currentsubswarm = (Population)getSubSwarms().get(i).getPopulation().clone(); - if (getSubSwarms().get(i).isActive()) { - activeCnt++; - metapop.addPopulation(getSubSwarms().get(i).getPopulation()); - } else if (!activeOnly) { - metapop.addPopulation(getSubSwarms().get(i).getPopulation()); - } - } - - if (isVerbose()) { - System.out.println("Active populations: " + activeCnt); - } - // set correct number of generations - metapop.setGenerationTo(getMainSwarm().getPopulation().getGeneration()); - - // set correct number of function calls - int calls = getMainSwarm().getPopulation().getFunctionCalls(); - for (int i = 0; i < getSubSwarms().size(); ++i){ - calls += getSubSwarms().get(i).getPopulation().getFunctionCalls(); - } -// System.out.println("metapop size " + metapop.size()); - metapop.SetFunctionCalls(calls); - - if (metapop.size()==0) { - System.err.println("NichePSO ERROR! " + metapop.getFunctionCalls()); - - int i=getSubSwarms().size()-1; - while (i>=0 && (metapop.size() subSwarms = getSubSwarms(); -// AbstractEAIndividual[] representatives = new AbstractEAIndividual[getSubSwarms().size()+1]; - for (int i = 0; i < getSubSwarms().size(); ++i){ - if (!onlyInactive || (!subSwarms.get(i).isActive())) { - representatives.add((AbstractEAIndividual)(subSwarms.get(i)).m_BestIndividual.clone()); + for (int j = i + 1; j < getSubSwarms().size(); ++j) { + //... if they should be merged according to the merging strategy + if (getMergingStrategy().shouldMergeSubswarms(getSubSwarms().get(i), getSubSwarms().get(j))) { + if (isVerbose()) { + System.out.println("Merging in NPSO!"); } - } - if (!onlyInactive && (getMainSwarm().getPopulation().size() != 0)) { - representatives.add((AbstractEAIndividual)getMainSwarm().m_BestIndividual.clone()); // assures at least one solution, even if no subswarm has been created - } - return representatives; - } + mergingEventFor(i, j); // for plotting + getMergingStrategy().mergeSubswarms(i, j, getSubSwarms(), getMainSwarm()); + runagain = true; // merged subswarm may overlap with another swarm now. This might not have been considered in this run... + --j; // subSwarms.size() has decreased and all elements >=j were shifted one position to the left + } + } + } +// System.out.println(); + if (runagain) { + mergeSubswarmsIfPossible(); + } + } -/********************************************************************************************************************** - * setter, getter: members - */ - - public String globalInfo(){ - return "A Niching Particle Swarm Optimizer"; - } - - /** @tested ps - * sets the !initial! size of the mainswarm population - * use this instead of getPopulation.setPopulationSize() - * @param size - */ - public void setMainSwarmSize(int size){ - // set member - this.mainSwarmSize = size; - // pass on to the mainswarm optimizer - getMainSwarm().getPopulation().setTargetSize(size); - } - - /** @tested nn - * returns the !initial! size of the mainswarm population - * @return the !initial! size of the mainswarm population - */ - public int getMainSwarmSize(){ - return this.mainSwarmSize; - } - - public String mainSwarmSizeTipText(){ - return "sets the initial size of the mainswarm population"; - } - - /** @tested ps - * defines the maximal allowed subswarm radius for absorption and merging - * @param val - */ - public void setMaxAllowedSwarmRadius(double val){ - // set member - this.maxAllowedSwarmRadius = val; - // pass on to the main- and subswarm optimizers - getMainSwarm().SetMaxAllowedSwarmRadius(val); - for (int i = 0; i < getSubSwarms().size(); ++i){ - getSubSwarms().get(i).SetMaxAllowedSwarmRadius(val); - } - getSubswarmOptimizerTemplate().SetMaxAllowedSwarmRadius(val); - } - - /** @tested nn - * @return - */ - public double getMaxAllowedSwarmRadius(){ - return this.maxAllowedSwarmRadius; - } - - public String maxAllowedSwarmRadiusTipText(){ - return "no subswarm radius is allowed to (formally) exceed this threshold (see help for details)"; - } + /** + * ******************************************************************************************************************** + * Absorbtion + */ + /** + * @tested adds indy to an active subswarm, then removes indy from the + * mainswarm. + * @param indy + * @param subswarm + * @return + */ + protected void absorbtionEventFor(AbstractEAIndividual indy, ParticleSubSwarmOptimization subswarm) { + if (isVerbose()) { + System.out.print("Absorbtion \n"); + } + absorbtionOccurd = true; + this.indytoabsorb.add(indy); + } + + /** + * @tested junit absorbs the mainswarm particles into the subswarm according + * to the absorbtion strategy + */ + protected void absorbParticlesIfPossible() { + boolean runagain = false; + // check for every particle in the main swarm... + for (int i = 0; i < getMainSwarm().getPopulation().size(); ++i) { + AbstractEAIndividual currentindy = getMainSwarm().getPopulation().getEAIndividual(i); + // ...if it matches the absorption-criterion for any subswarm: + for (int j = 0; j < getSubSwarms().size(); ++j) { + ParticleSubSwarmOptimization currentsubwarm = getSubSwarms().get(j); + if (getAbsorptionStrategy().shouldAbsorbParticleIntoSubswarm(currentindy, currentsubwarm, this.getMainSwarm())) { + if (isVerbose()) { + System.out.println("Absorbing particle (NPSO)"); + } + absorbtionEventFor(currentindy, currentsubwarm); + getAbsorptionStrategy().absorbParticle(currentindy, currentsubwarm, this.getMainSwarm()); + --i; // ith particle is removed, all indizes shift one position to the left + runagain = true; // if the absorbed particle provides a new best position, the radius of the swarm will change -> run absorption again + break; // dont try to absorb this particle again into another subswarm + } + } + } + if (runagain) { + absorbParticlesIfPossible(); + } + } + + /** + * ******************************************************************************************************************** + * Subswarm Creation + */ + protected void subswarmCreationEventFor(AbstractEAIndividual currentindy, ParticleSubSwarmOptimization subswarm) { + if (isVerbose()) { + System.out.print("creating subswarm\n"); + } + creationOccurd = true; + this.indyconverged.add(currentindy); + for (int i = 0; i < subswarm.getPopulation().size(); ++i) { + AbstractEAIndividual indy = subswarm.getPopulation().getEAIndividual(i); + if (indy.getIndyID() != currentindy.getIndyID()) { + this.convergedneighbor.add(indy); + } + } + } + + /** + * @tested junit creates a subswarm from every particle in the mainswarm + * that meets the convergence-criteria of the creation strategy + */ + protected void createSubswarmIfPossible() { + // for every particle... + for (int i = 0; i < getMainSwarm().getPopulation().size(); ++i) { + AbstractEAIndividual currentindy = getMainSwarm().getPopulation().getEAIndividual(i); + //... that meets the convergence-criteria of the creation strategie + if (getSubswarmCreationStrategy().shouldCreateSubswarm(currentindy, getMainSwarm())) { + if (isVerbose()) { + System.out.println("Creating sub swarm (NPSO)"); + } + // use an optimizer according to the template + ParticleSubSwarmOptimization newSubswarm = getNewSubSwarmOptimizer(); + // and create a subswarm from the given particle + getSubswarmCreationStrategy().createSubswarm(newSubswarm, currentindy, getMainSwarm()); + subswarmCreationEventFor(currentindy, newSubswarm); + // add the subswarm to the set of subswarms: + this.getSubSwarms().add(newSubswarm); + i = 0; // start again because indizes changed and we dont know how... + } + } + } + + /** + * ******************************************************************************************************************** + * event listening + */ + /** + * @tested Something has changed + */ + protected void firePropertyChangedEvent(String name) { + if (this.m_Listener != null) { + this.m_Listener.registerPopulationStateChanged(this, name); + } + } + + /** + * @tested This method allows you to add the LectureGUI as listener to the + * Optimizer + * @param ea + */ + @Override + public void addPopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + this.m_Listener = ea; + } + + @Override + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } + + /** + * @tested nn This method is required to free the memory on a RMIServer, but + * there is nothing to implement. + */ + /** + * ******************************************************************************************************************** + * setter, getter: population and solutions + */ + /** + * @tested nn (non-Javadoc) + * @see + * eva2.server.go.strategies.InterfaceOptimizer#setPopulation(javaeva.server.oa.go.Populations.Population) + */ + @Override + public void setPopulation(Population pop) { + //pass on to mainswarm optimizer + getMainSwarm().setPopulation(pop); + } + + /** + * @tested junit, junit& + * @return a population consisting of copies from the mainswarm and all + * active subswarms + */ + public Population getActivePopulation() { + // construct a metapop with clones from the mainswarm and all active subswarms + Population metapop = (Population) getMainSwarm().getPopulation().clone(); + for (int i = 0; i < getSubSwarms().size(); ++i) { + ParticleSubSwarmOptimization currentsubswarm = getSubSwarms().get(i); + if (currentsubswarm.isActive()) { + Population currentsubswarmpop = (Population) currentsubswarm.getPopulation().clone(); + metapop.addPopulation(currentsubswarmpop); + } + } + + // set correct number of generations + metapop.setGenerationTo(getMainSwarm().getPopulation().getGeneration()); + + // set correct number of function calls + int calls = getMainSwarm().getPopulation().getFunctionCalls(); + for (int i = 0; i < getSubSwarms().size(); ++i) { + ParticleSubSwarmOptimization currentsubswarm = getSubSwarms().get(i); + // calls from inactive populations have to be counted as well... + calls += currentsubswarm.getPopulation().getFunctionCalls(); + } + metapop.SetFunctionCalls(calls); + // care for consistent size: + metapop.synchSize(); + return metapop; + } + + /** + * @tested junit returns a population consisting of copies from the + * mainswarm and all subswarms (active and inactive, so the size of this + * Population is not necessarily constant). (Especially important for the + * call back regarding the output file... ) Beware: + * getPopulation().getPopulationSize() returns the !initial! size of the + * main swarm, the actual size of the complete population is accessed via + * getPopulation().size() + * @return a population consisting of copies from the mainswarm and all + * subswarms. + */ + @Override + public Population getPopulation() { + boolean activeOnly = true; // true makes problems if all subswarms are deactivated at the same time! + // construct a metapop with clones from the mainswarm and all subswarms + Population metapop = (Population) getMainSwarm().getPopulation().cloneWithoutInds(); + metapop.ensureCapacity(getMainSwarmSize()); + metapop.addPopulation(getMainSwarm().getPopulation()); + int activeCnt = 0; +// Population currentsubswarm; + for (int i = 0; i < getSubSwarms().size(); ++i) { +// currentsubswarm = (Population)getSubSwarms().get(i).getPopulation().clone(); + if (getSubSwarms().get(i).isActive()) { + activeCnt++; + metapop.addPopulation(getSubSwarms().get(i).getPopulation()); + } else if (!activeOnly) { + metapop.addPopulation(getSubSwarms().get(i).getPopulation()); + } + } + + if (isVerbose()) { + System.out.println("Active populations: " + activeCnt); + } + // set correct number of generations + metapop.setGenerationTo(getMainSwarm().getPopulation().getGeneration()); + + // set correct number of function calls + int calls = getMainSwarm().getPopulation().getFunctionCalls(); + for (int i = 0; i < getSubSwarms().size(); ++i) { + calls += getSubSwarms().get(i).getPopulation().getFunctionCalls(); + } +// System.out.println("metapop size " + metapop.size()); + metapop.SetFunctionCalls(calls); + + if (metapop.size() == 0) { + System.err.println("NichePSO ERROR! " + metapop.getFunctionCalls()); + + int i = getSubSwarms().size() - 1; + while (i >= 0 && (metapop.size() < mainSwarmSize)) { +// for (int i = 0; i < getSubSwarms().size(); ++i){ + metapop.addPopulation(getSubSwarms().get(i).getPopulation()); + i--; + } + } + return metapop; + } + + public String populationTipText() { + return "please use mainSwarmSize to set the population size"; + } + + /** + * @tested junit (non-Javadoc) + * @see eva2.server.go.strategies.InterfaceOptimizer#getAllSolutions() + * @return a population consisting of the personal best solutions of every + * particle in the mainswarm and all subswarms + */ + @Override + public SolutionSet getAllSolutions() { + // hier kann dasselbe geliefert werden wie bei getPopulation + // speziell fuer multi-modale optimierung kann aber noch "mehr" als die aktuelle Population zurueckgeliefert werden + // zB die aktuelle Population und ein Archiv fruehererer Loesungen (das machen CBN und CHC jetzt). + + if (returnRepresentativeSolutionsOnly) { + Population sols = getSubswarmRepresentatives(false); + Population metapop = getPopulation(); + sols.SetFunctionCalls(metapop.getFunctionCalls()); + sols.setGenerationTo(metapop.getGeneration()); + return new SolutionSet(metapop, sols); + } else { + Population metapop = getPopulation(); + Population sols = new Population(); + for (int i = 0; i < metapop.size(); ++i) { + AbstractEAIndividual indy = metapop.getEAIndividual(i); + AbstractEAIndividual pbest = (AbstractEAIndividual) indy.getData("PersonalBestKey"); + sols.add(pbest); + } + sols.SetFunctionCalls(metapop.getFunctionCalls()); + sols.setGenerationTo(metapop.getFunctionCalls()); + return new SolutionSet(sols); + } + } + + /** + * @tested junit + * @return the best solution found by any particle in any swarm + */ + public AbstractEAIndividual getGlobalBestSolution() { + Population metapop = getPopulation(); + if (metapop.size() == 0) { + System.out.println("getGlobalBestSolution: all swarms are empty "); + return null; + } + AbstractEAIndividual gbest = (AbstractEAIndividual) metapop.getEAIndividual(0).getData("PersonalBestKey"); + for (int i = 1; i < metapop.size(); ++i) { + AbstractEAIndividual currentPBest = (AbstractEAIndividual) metapop.getEAIndividual(i).getData("PersonalBestKey"); + if (currentPBest.isDominating(gbest)) { + gbest = currentPBest; + } + } + return gbest; + } + + /** + * @tested junit returns the cloned global best individuals (ie best of all + * time) from every subswarm and the main swarm + * @return array with copies of the gbest individuals + */ + public Population getSubswarmRepresentatives(boolean onlyInactive) { + Population representatives = new Population(getSubSwarms().size() + 1); + Vector subSwarms = getSubSwarms(); +// AbstractEAIndividual[] representatives = new AbstractEAIndividual[getSubSwarms().size()+1]; + for (int i = 0; i < getSubSwarms().size(); ++i) { + if (!onlyInactive || (!subSwarms.get(i).isActive())) { + representatives.add((AbstractEAIndividual) (subSwarms.get(i)).m_BestIndividual.clone()); + } + } + if (!onlyInactive && (getMainSwarm().getPopulation().size() != 0)) { + representatives.add((AbstractEAIndividual) getMainSwarm().m_BestIndividual.clone()); // assures at least one solution, even if no subswarm has been created + } + return representatives; + } + + /** + * ******************************************************************************************************************** + * setter, getter: members + */ + public String globalInfo() { + return "A Niching Particle Swarm Optimizer"; + } + + /** + * @tested ps sets the !initial! size of the mainswarm population use this + * instead of getPopulation.setPopulationSize() + * @param size + */ + public void setMainSwarmSize(int size) { + // set member + this.mainSwarmSize = size; + // pass on to the mainswarm optimizer + getMainSwarm().getPopulation().setTargetSize(size); + } + + /** + * @tested nn returns the !initial! size of the mainswarm population + * @return the !initial! size of the mainswarm population + */ + public int getMainSwarmSize() { + return this.mainSwarmSize; + } + + public String mainSwarmSizeTipText() { + return "sets the initial size of the mainswarm population"; + } + + /** + * @tested ps defines the maximal allowed subswarm radius for absorption and + * merging + * @param val + */ + public void setMaxAllowedSwarmRadius(double val) { + // set member + this.maxAllowedSwarmRadius = val; + // pass on to the main- and subswarm optimizers + getMainSwarm().SetMaxAllowedSwarmRadius(val); + for (int i = 0; i < getSubSwarms().size(); ++i) { + getSubSwarms().get(i).SetMaxAllowedSwarmRadius(val); + } + getSubswarmOptimizerTemplate().SetMaxAllowedSwarmRadius(val); + } + + /** + * @tested nn + * @return + */ + public double getMaxAllowedSwarmRadius() { + return this.maxAllowedSwarmRadius; + } + + public String maxAllowedSwarmRadiusTipText() { + return "no subswarm radius is allowed to (formally) exceed this threshold (see help for details)"; + } // public double getMainSwarmPhi1() { // return mainSwarmPhi1; @@ -982,20 +1011,21 @@ public class NichePSO implements InterfaceAdditionalPopulationInformer, Interfac // public double getMainSwarmPhi2() { // return mainSwarmPhi2; // } - - public double getMainSwarmInitialVelocity() { - return mainSwarm.getInitialVelocity(); - } - public void setMainSwarmInitialVelocity(double v) { - mainSwarm.setInitialVelocity(v); - } - public String mainSwarmInitialVelocityTipText() { - return "The initial velocity (normed by search range) for the main swarm."; - } - - public String mainSwarmPhi1TipText(){ - return "weights the cognitive component for the PSO used to train the main swarm"; - } + public double getMainSwarmInitialVelocity() { + return mainSwarm.getInitialVelocity(); + } + + public void setMainSwarmInitialVelocity(double v) { + mainSwarm.setInitialVelocity(v); + } + + public String mainSwarmInitialVelocityTipText() { + return "The initial velocity (normed by search range) for the main swarm."; + } + + public String mainSwarmPhi1TipText() { + return "weights the cognitive component for the PSO used to train the main swarm"; + } // public void setMainSwarmPhi2(double p2) { // this.SetMainSwarmPhi2(p2); @@ -1010,178 +1040,181 @@ public class NichePSO implements InterfaceAdditionalPopulationInformer, Interfac //// if (getMainSwarm().getInertnessOrChi() != inertChi) mainSwarmParamAging.setStartValue(getMainSwarm().getInertnessOrChi()); // if (getMainSwarm().getInertnessOrChi() != inertChi) getMainSwarm().setInertnessOrChi(mainSwarmPhi2); // } - // public int getMainSwarmTopologyTag() { // return mainSwarmTopologyTag; // } + public void SetMainSwarmTopologyTag(int mainSwarmTopologyTag) { + // Possible topologies are: "Linear", "Grid", "Star", "Multi-Swarm", "Tree", "HPSO", "Random" in that order starting by 0. + this.mainSwarmTopology = PSOTopologyEnum.translateOldID(mainSwarmTopologyTag); + } - public void SetMainSwarmTopologyTag(int mainSwarmTopologyTag) { - // Possible topologies are: "Linear", "Grid", "Star", "Multi-Swarm", "Tree", "HPSO", "Random" in that order starting by 0. - this.mainSwarmTopology = PSOTopologyEnum.translateOldID(mainSwarmTopologyTag); - } - - public PSOTopologyEnum getMainSwarmTopology() { - return mainSwarm.topology; - } - - /** This method allows you to choose the topology type. - * @param t The type. - */ - public void setMainSwarmTopology(PSOTopologyEnum t) { - mainSwarm.topology = t; - this.mainSwarmTopology = t; - GenericObjectEditor.setHideProperty(getClass(), "mainSwarmTopologyRange", mainSwarmTopology == PSOTopologyEnum.multiSwarm); // "Multi-Swarm" has no topologyRange - } - - public int getMainSwarmTopologyRange() { - return mainSwarmTopologyRange; - } + public PSOTopologyEnum getMainSwarmTopology() { + return mainSwarm.topology; + } - public void setMainSwarmTopologyRange(int mainSwarmTopologyRange) { - this.mainSwarmTopologyRange = mainSwarmTopologyRange; - } - - public SelectedTag getMainSwarmAlgoType() { - if (mainSwarmAlgoType != getMainSwarm().getAlgoType().getSelectedTagID()) { - System.err.println("Error in NichePSO:getMainSwarmAlgoType() !!"); - } - return getMainSwarm().getAlgoType(); - } - - public void setMainSwarmAlgoType(SelectedTag st) { - getMainSwarm().setAlgoType(st); - mainSwarmAlgoType = st.getSelectedTagID(); + /** + * This method allows you to choose the topology type. + * + * @param t The type. + */ + public void setMainSwarmTopology(PSOTopologyEnum t) { + mainSwarm.topology = t; + this.mainSwarmTopology = t; + GenericObjectEditor.setHideProperty(getClass(), "mainSwarmTopologyRange", mainSwarmTopology == PSOTopologyEnum.multiSwarm); // "Multi-Swarm" has no topologyRange + } + + public int getMainSwarmTopologyRange() { + return mainSwarmTopologyRange; + } + + public void setMainSwarmTopologyRange(int mainSwarmTopologyRange) { + this.mainSwarmTopologyRange = mainSwarmTopologyRange; + } + + public SelectedTag getMainSwarmAlgoType() { + if (mainSwarmAlgoType != getMainSwarm().getAlgoType().getSelectedTagID()) { + System.err.println("Error in NichePSO:getMainSwarmAlgoType() !!"); + } + return getMainSwarm().getAlgoType(); + } + + public void setMainSwarmAlgoType(SelectedTag st) { + getMainSwarm().setAlgoType(st); + mainSwarmAlgoType = st.getSelectedTagID(); // mainSwarmParamAging.setStartValue(getMainSwarm().getInertnessOrChi()); - } - - /** - * Allow GOE/PropertySheetPanel to know about change references in sub-objects. - * - * @return - */ - public String[] getGOEPropertyUpdateLinks() { - return new String[] {"mainSwarmAlgoType", "mainSwarmInertness", "mainSwarmPhi1", "mainSwarmInertness", "mainSwarmPhi2", "mainSwarmInertness"}; - } - - public boolean isReturnRepresentativeSolutionsOnly() { - return returnRepresentativeSolutionsOnly; - } + } - public void SetReturnRepresentativeSolutionsOnly(boolean returnRepresentativeSolutionsOnly) { - this.returnRepresentativeSolutionsOnly = returnRepresentativeSolutionsOnly; - } + /** + * Allow GOE/PropertySheetPanel to know about change references in + * sub-objects. + * + * @return + */ + public String[] getGOEPropertyUpdateLinks() { + return new String[]{"mainSwarmAlgoType", "mainSwarmInertness", "mainSwarmPhi1", "mainSwarmInertness", "mainSwarmPhi2", "mainSwarmInertness"}; + } - /** @tested nn - * @param val - */ - public void SetPartlyInactive(boolean val){ - this.partlyInactive = val; - } - - /** @tested nn - * @return - */ - public boolean isPartlyInactive(){ - return partlyInactive; - } - - public void setVerbose(boolean verbose) { - this.verbose = verbose; - } + public boolean isReturnRepresentativeSolutionsOnly() { + return returnRepresentativeSolutionsOnly; + } - public boolean isVerbose() { - return verbose; - } - - public String verboseTipText(){ - return "activate to print additional information to the console during optimization"; - } - - public boolean isLog() { - return log; - } + public void SetReturnRepresentativeSolutionsOnly(boolean returnRepresentativeSolutionsOnly) { + this.returnRepresentativeSolutionsOnly = returnRepresentativeSolutionsOnly; + } - public void SetLog(boolean log) { - this.log = log; - } - - public boolean isPlotFinal() { - return plotFinal; - } - - public void SetPlotFinal(boolean plotFinal) { - this.plotFinal = plotFinal; - } - - public void setPlot(boolean plot) { - this.plot = plot; - } + /** + * @tested nn + * @param val + */ + public void SetPartlyInactive(boolean val) { + this.partlyInactive = val; + } - public boolean isPlot() { - return plot; - } - - public String plotTipText(){ - return "toggles the plot window"; - } - - public boolean isUseSinglePlotWindow() { - return useSinglePlotWindow; - } + /** + * @tested nn + * @return + */ + public boolean isPartlyInactive() { + return partlyInactive; + } - public void setUseSinglePlotWindow(boolean useSinglePlotWindow) { - this.useSinglePlotWindow = useSinglePlotWindow; - } + public void setVerbose(boolean verbose) { + this.verbose = verbose; + } - public String useSinglePlotWindowTipText(){ - return "deactivate to open a new window for every plot"; - } - - public boolean isSavePlots() { - return savePlots; - } + public boolean isVerbose() { + return verbose; + } - public void SetSavePlots(boolean savePlots) { - this.savePlots = savePlots; - } + public String verboseTipText() { + return "activate to print additional information to the console during optimization"; + } - public void setShowCycle(int showCycle) { - this.showCycle = showCycle; - } + public boolean isLog() { + return log; + } - public int getShowCycle() { - return showCycle; - } - - public String showCycleTipText(){ - return "sets the interval (in generations) used to update the plot window"; - } + public void SetLog(boolean log) { + this.log = log; + } - /** - * @return - */ - public String getDirForCurrentExperiment() { - return dirForCurrentExperiment; - } - - /** sets the base directory for any output. - * Output produced: - * - if isLog(), a log file is written - * - if isPlot and isSavePlots, pictures are produced - * @param dirForCurrentExperiment - */ - public void SetDirForCurrentExperiment(String dirForCurrentExperiment) { - this.dirForCurrentExperiment = dirForCurrentExperiment; - } - - public void setMainSwarm(ParticleSubSwarmOptimization mainSwarm) { - this.mainSwarm = mainSwarm; - } + public boolean isPlotFinal() { + return plotFinal; + } + + public void SetPlotFinal(boolean plotFinal) { + this.plotFinal = plotFinal; + } + + public void setPlot(boolean plot) { + this.plot = plot; + } + + public boolean isPlot() { + return plot; + } + + public String plotTipText() { + return "toggles the plot window"; + } + + public boolean isUseSinglePlotWindow() { + return useSinglePlotWindow; + } + + public void setUseSinglePlotWindow(boolean useSinglePlotWindow) { + this.useSinglePlotWindow = useSinglePlotWindow; + } + + public String useSinglePlotWindowTipText() { + return "deactivate to open a new window for every plot"; + } + + public boolean isSavePlots() { + return savePlots; + } + + public void SetSavePlots(boolean savePlots) { + this.savePlots = savePlots; + } + + public void setShowCycle(int showCycle) { + this.showCycle = showCycle; + } + + public int getShowCycle() { + return showCycle; + } + + public String showCycleTipText() { + return "sets the interval (in generations) used to update the plot window"; + } + + /** + * @return + */ + public String getDirForCurrentExperiment() { + return dirForCurrentExperiment; + } + + /** + * sets the base directory for any output. Output produced: - if isLog(), a + * log file is written - if isPlot and isSavePlots, pictures are produced + * + * @param dirForCurrentExperiment + */ + public void SetDirForCurrentExperiment(String dirForCurrentExperiment) { + this.dirForCurrentExperiment = dirForCurrentExperiment; + } + + public void setMainSwarm(ParticleSubSwarmOptimization mainSwarm) { + this.mainSwarm = mainSwarm; + } + + public ParticleSubSwarmOptimization getMainSwarm() { + return mainSwarm; + } - public ParticleSubSwarmOptimization getMainSwarm() { - return mainSwarm; - } - // public InterfaceParameterAging getMainSwarmInertness(){ // return mainSwarmParamAging; //// return this.mainSwarm.getInertnessAging(); @@ -1192,857 +1225,867 @@ public class NichePSO implements InterfaceAdditionalPopulationInformer, Interfac // this.mainSwarm.setInertnessAging(pa); // getMainSwarm().setInertnessOrChi(pa.getStartValue()); // } - - public String mainSwarmInertnessTipText(){ - return "sets the inertness weight used for the PSO to train the main swarm (see help for details)"; - } + public String mainSwarmInertnessTipText() { + return "sets the inertness weight used for the PSO to train the main swarm (see help for details)"; + } - public void SetSubSwarms(Vector subSwarms) { - this.subSwarms = subSwarms; - } + public void SetSubSwarms(Vector subSwarms) { + this.subSwarms = subSwarms; + } - public Vector getSubSwarms() { - return subSwarms; - } + public Vector getSubSwarms() { + return subSwarms; + } - public void setSubswarmOptimizerTemplate(ParticleSubSwarmOptimization subswarmOptimizerTemplate) { - this.subswarmOptimizerTemplate = subswarmOptimizerTemplate; - } + public void setSubswarmOptimizerTemplate(ParticleSubSwarmOptimization subswarmOptimizerTemplate) { + this.subswarmOptimizerTemplate = subswarmOptimizerTemplate; + } - public ParticleSubSwarmOptimization getSubswarmOptimizerTemplate() { - return subswarmOptimizerTemplate; - } - - public String subswarmOptimizerTemplateTipText(){ - return "sets the optimizer used to train the subswarms"; - } + public ParticleSubSwarmOptimization getSubswarmOptimizerTemplate() { + return subswarmOptimizerTemplate; + } - public void setDeactivationStrategy(InterfaceDeactivationStrategy deactivationStrategy) { - this.deactivationStrategy = deactivationStrategy; - } - - public InterfaceDeactivationStrategy getDeactivationStrategy() { - return deactivationStrategy; - } - - public String deactivationStrategyTipText(){ - return "sets the strategy used to deactivate subswarms"; - } - - public void setMergingStrategy(InterfaceMergingStrategy mergingStrategy) { - this.mergingStrategy = mergingStrategy; - } - - public InterfaceMergingStrategy getMergingStrategy() { - return mergingStrategy; - } - - public String mergingStrategyTipText(){ - return "sets the strategy used to merge subswarms"; - } - - public void setAbsorptionStrategy(InterfaceAbsorptionStrategy absorptionStrategy) { - this.absorptionStrategy = absorptionStrategy; - } - - public InterfaceAbsorptionStrategy getAbsorptionStrategy() { - return absorptionStrategy; - } - - public String absorptionStrategyTipText(){ - return "sets the strategy used to absorb main swarm particles into a subswarm"; - } - - public void setSubswarmCreationStrategy(InterfaceSubswarmCreationStrategy subswarmCreationStrategy) { - this.subswarmCreationStrategy = subswarmCreationStrategy; - } - - - public InterfaceSubswarmCreationStrategy getSubswarmCreationStrategy() { - return subswarmCreationStrategy; - } - - public String subswarmCreationStrategyTipText(){ - return "sets the strategy to create subswarms from the main swarm"; - } - - /** @tested nn - * (non-Javadoc) @see javaeva.server.oa.go.Strategies.InterfaceOptimizer#getProblem() - */ + public String subswarmOptimizerTemplateTipText() { + return "sets the optimizer used to train the subswarms"; + } + + public void setDeactivationStrategy(InterfaceDeactivationStrategy deactivationStrategy) { + this.deactivationStrategy = deactivationStrategy; + } + + public InterfaceDeactivationStrategy getDeactivationStrategy() { + return deactivationStrategy; + } + + public String deactivationStrategyTipText() { + return "sets the strategy used to deactivate subswarms"; + } + + public void setMergingStrategy(InterfaceMergingStrategy mergingStrategy) { + this.mergingStrategy = mergingStrategy; + } + + public InterfaceMergingStrategy getMergingStrategy() { + return mergingStrategy; + } + + public String mergingStrategyTipText() { + return "sets the strategy used to merge subswarms"; + } + + public void setAbsorptionStrategy(InterfaceAbsorptionStrategy absorptionStrategy) { + this.absorptionStrategy = absorptionStrategy; + } + + public InterfaceAbsorptionStrategy getAbsorptionStrategy() { + return absorptionStrategy; + } + + public String absorptionStrategyTipText() { + return "sets the strategy used to absorb main swarm particles into a subswarm"; + } + + public void setSubswarmCreationStrategy(InterfaceSubswarmCreationStrategy subswarmCreationStrategy) { + this.subswarmCreationStrategy = subswarmCreationStrategy; + } + + public InterfaceSubswarmCreationStrategy getSubswarmCreationStrategy() { + return subswarmCreationStrategy; + } + + public String subswarmCreationStrategyTipText() { + return "sets the strategy to create subswarms from the main swarm"; + } + + /** + * @tested nn (non-Javadoc) + * @see javaeva.server.oa.go.Strategies.InterfaceOptimizer#getProblem() + */ @Override - public InterfaceOptimizationProblem getProblem() { - return this.m_Problem; - } - - /** @tested ps - * This method will set the problem that is to be optimized - * @param problem - */ - @Override - public void setProblem(InterfaceOptimizationProblem problem) { - // set member - this.m_Problem = problem; - // pass on to the main- and subswarm optimizers - getMainSwarm().setProblem(problem); - for (int i = 0; i < getSubSwarms().size(); ++i){ - getSubSwarms().get(i).setProblem(problem); - } - getSubswarmOptimizerTemplate().setProblem(problem); - } - - /** @tested nn - * This method allows you to set an identifier for the algorithm - * @param name The indenifier - */ - @Override - public void setIdentifier(String name) { - this.m_Identifier = name; - } - - /** @tested nn - * (non-Javadoc) @see javaeva.server.oa.go.Strategies.InterfaceOptimizer#getIdentifier() - */ - @Override - public String getIdentifier() { - return this.m_Identifier; - } - -/********************************************************************************************************************** - * getter: "descriptive parameters" for the mainswarm and subswarms - */ - public double getAveDistToNeighborInMainswarm(){ - return getMainSwarm().getAveDistToNeighbor(); - } - - public double[] getFitDevsInMain(){ - double[] res = new double[getMainSwarm().getPopulation().size()]; - for (int i = 0; i < getMainSwarm().getPopulation().size(); ++i){ - AbstractEAIndividual indy = getMainSwarm().getPopulation().getEAIndividual(i); - res[i] = ((Double)indy.getData(NichePSO.stdDevKey)).doubleValue(); - } - return res; - } + public InterfaceOptimizationProblem getProblem() { + return this.m_Problem; + } - /** @tested junit - * @param vals - * @return - */ - public double getMedian(double[] vals) { - java.util.Arrays.sort(vals); - double result; - if (vals.length % 2 == 0){ // even - int mid1 = (vals.length/2)-1; - int mid2 = (vals.length/2); - result = 1.0/2.0*(vals[mid1]+vals[mid2]); - - }else { // odd - int mid = ((vals.length+1)/2)-1; - result = vals[mid]; - } - return result; - } - - public double getMedianSubswarmSize() { - if (getSubSwarms().size() == 0) { - return 0; + /** + * @tested ps This method will set the problem that is to be optimized + * @param problem + */ + @Override + public void setProblem(InterfaceOptimizationProblem problem) { + // set member + this.m_Problem = problem; + // pass on to the main- and subswarm optimizers + getMainSwarm().setProblem(problem); + for (int i = 0; i < getSubSwarms().size(); ++i) { + getSubSwarms().get(i).setProblem(problem); + } + getSubswarmOptimizerTemplate().setProblem(problem); + } + + /** + * @tested nn This method allows you to set an identifier for the algorithm + * @param name The indenifier + */ + @Override + public void setIdentifier(String name) { + this.m_Identifier = name; + } + + /** + * @tested nn (non-Javadoc) + * @see javaeva.server.oa.go.Strategies.InterfaceOptimizer#getIdentifier() + */ + @Override + public String getIdentifier() { + return this.m_Identifier; + } + + /** + * ******************************************************************************************************************** + * getter: "descriptive parameters" for the mainswarm and subswarms + */ + public double getAveDistToNeighborInMainswarm() { + return getMainSwarm().getAveDistToNeighbor(); + } + + public double[] getFitDevsInMain() { + double[] res = new double[getMainSwarm().getPopulation().size()]; + for (int i = 0; i < getMainSwarm().getPopulation().size(); ++i) { + AbstractEAIndividual indy = getMainSwarm().getPopulation().getEAIndividual(i); + res[i] = ((Double) indy.getData(NichePSO.stdDevKey)).doubleValue(); + } + return res; + } + + /** + * @tested junit + * @param vals + * @return + */ + public double getMedian(double[] vals) { + java.util.Arrays.sort(vals); + double result; + if (vals.length % 2 == 0) { // even + int mid1 = (vals.length / 2) - 1; + int mid2 = (vals.length / 2); + result = 1.0 / 2.0 * (vals[mid1] + vals[mid2]); + + } else { // odd + int mid = ((vals.length + 1) / 2) - 1; + result = vals[mid]; + } + return result; + } + + public double getMedianSubswarmSize() { + if (getSubSwarms().size() == 0) { + return 0; + } + double[] size = new double[getSubSwarms().size()]; + for (int i = 0; i < getSubSwarms().size(); ++i) { + if (getSubSwarms().get(i) == null) { // happend once - cant reproduce... + System.out.println("getMedianSubswarmSize: subSwarms has null objects - why ?"); + break; } - double[] size = new double[getSubSwarms().size()]; - for (int i = 0; i < getSubSwarms().size(); ++i){ - if (getSubSwarms().get(i) == null) { // happend once - cant reproduce... - System.out.println("getMedianSubswarmSize: subSwarms has null objects - why ?"); - break; - } - size[i] = getSubSwarms().get(i).getPopulation().size(); - } - return getMedian(size); - } - - public double getMeanSubswarmSize() { - double mean = 0; - for (int i = 0; i < getSubSwarms().size(); ++i){ - mean += getSubSwarms().get(i).getPopulation().size(); - } - mean /= getSubSwarms().size(); - return mean; - } - - public double getMaxSubswarmSize() { - double max = 0; - for (int i = 0; i < getSubSwarms().size(); ++i){ - if (getSubSwarms().get(i).getPopulation().size() > max){ - max = getSubSwarms().get(i).getPopulation().size(); - } - } - return max; - } - - public double getMeanSubswarmDistanceNormalised(){ - double meanDist = 0; - int pairs = 0; - for (int i = 0; i < getSubSwarms().size(); ++i){ - for (int j = i+1; j < getSubSwarms().size(); ++j){ - ParticleSubSwarmOptimization sub1 = getSubSwarms().get(i); - ParticleSubSwarmOptimization sub2 = getSubSwarms().get(j); - meanDist += getMainSwarm().distance(sub1.getGBestIndividual(), sub2.getGBestIndividual()); - ++pairs; - } - } - meanDist /= pairs; - meanDist /= getMainSwarm().maxPosDist; - return meanDist; - } - - public double getMeanSubswarmDiversityNormalised() { - double meanDiv = 0; - for (int i = 0; i < getSubSwarms().size(); ++i){ - ParticleSubSwarmOptimization currentSubswarm = getSubSwarms().get(i); - meanDiv += currentSubswarm.getEuclideanDiversity(); - } - meanDiv /= (double)getSubSwarms().size(); - meanDiv /= getMainSwarm().maxPosDist; - return meanDiv; - } - -/********************************************************************************************************************** - * setter, getter: infostrings - */ - /** @tested nn - * This method will return a naming String - * @return The name of the algorithm - */ - @Override - public String getName() { - return "NichePSO-"+getMainSwarmSize(); - } - - /** @tested nn - * This method will return a string describing all properties of the optimizer - * and the applied methods. - * @return A descriptive string - */ - @Override - public String getStringRepresentation() { - String result = ""; - result += "niching particle swarm optimization." + - " This algorithm optimizes multiple optima of an multimodal objective function in parallel.\n"; - return result; - } - - /** @tested emp - * returns a string that lists the global best individuals (ie best of all time) from every subswarm - * @return descriptive string of the elite - */ - public String getSubswarmRepresentativesAsString(boolean onlyInactive){ - String result = "\nSubswarmRepresentatives: \n"; - Population reps = getSubswarmRepresentatives(onlyInactive); - for (int i = 0; i < getSubSwarms().size(); ++i){ - result += reps.getEAIndividual(i).getStringRepresentation() + "\n"; - } - //result += "\n"; - return result; - } - - /** @tested emp - * @return - */ - public String getPerformanceAsString(){ - if (!(m_Problem instanceof InterfaceMultimodalProblem)){ - System.out.println("getPerformanceAsString: problem not instanceof InterfaceMultimodalProblem"); - return ""; - } - - String result = "Performance (#Optima found, Max Peak Ratio, which optima are found): \n"; - - // construct an elite-population (with the gbest individual from every subswarm) - Population elitepop = getSubswarmRepresentatives(false); - - // use elite population to compute performance - if (m_Problem instanceof InterfaceMultimodalProblem){ - result += ((InterfaceMultimodalProblemKnown)m_Problem).getNumberOfFoundOptima(elitepop); - result += "(" + ((InterfaceMultimodalProblemKnown)m_Problem).getRealOptima().size() + ")\t"; - result += ((InterfaceMultimodalProblemKnown)m_Problem).getMaximumPeakRatio(elitepop) + "\t"; - //boolean[] opts = ((InterfaceMultimodalProblem)m_Problem).whichOptimaAreFound(elitepop); - //result += "Optima:"; - //for (int i = 0; i < opts.length; ++i){ - //result += String.valueOf(opts[i])+" "; - //} - result += "\n"; - } - return result; - } - - public String getReport(){ - String result = new String(); - result = "Generations: " + getPopulation().getGeneration(); - result += " FunctionCalls: " + getPopulation().getFunctionCalls(); - result += " MainSwarmSize: " + getMainSwarm().getPopulation().size(); - result += " Subswarms: "; - for (int i = 0; i < getSubSwarms().size(); ++i){ - result += "("+i+")"+getSubSwarms().get(i).getPopulation().size() + " "; - } - result += "SwarmSize: " + getPopulation().size(); - result +="\n"; - - return result; + size[i] = getSubSwarms().get(i).getPopulation().size(); + } + return getMedian(size); } -/********************************************************************************************************************** - * for the logfile - */ - /** @tested emp - * generates the NichePSO_date file - */ - protected void initLogFile(){ - // opening output file... - if (getDirForCurrentExperiment().equals("unset")) { - System.out.println("initLogFile: no directory for output specified, please use setDirForCurrentExperiment first"); - return; - } - - // path - File outputPath = new File(getDirForCurrentExperiment()+"\\NichePSO-LogFiles\\"); - if (!outputPath.exists()) { + public double getMeanSubswarmSize() { + double mean = 0; + for (int i = 0; i < getSubSwarms().size(); ++i) { + mean += getSubSwarms().get(i).getPopulation().size(); + } + mean /= getSubSwarms().size(); + return mean; + } + + public double getMaxSubswarmSize() { + double max = 0; + for (int i = 0; i < getSubSwarms().size(); ++i) { + if (getSubSwarms().get(i).getPopulation().size() > max) { + max = getSubSwarms().get(i).getPopulation().size(); + } + } + return max; + } + + public double getMeanSubswarmDistanceNormalised() { + double meanDist = 0; + int pairs = 0; + for (int i = 0; i < getSubSwarms().size(); ++i) { + for (int j = i + 1; j < getSubSwarms().size(); ++j) { + ParticleSubSwarmOptimization sub1 = getSubSwarms().get(i); + ParticleSubSwarmOptimization sub2 = getSubSwarms().get(j); + meanDist += getMainSwarm().distance(sub1.getGBestIndividual(), sub2.getGBestIndividual()); + ++pairs; + } + } + meanDist /= pairs; + meanDist /= getMainSwarm().maxPosDist; + return meanDist; + } + + public double getMeanSubswarmDiversityNormalised() { + double meanDiv = 0; + for (int i = 0; i < getSubSwarms().size(); ++i) { + ParticleSubSwarmOptimization currentSubswarm = getSubSwarms().get(i); + meanDiv += currentSubswarm.getEuclideanDiversity(); + } + meanDiv /= (double) getSubSwarms().size(); + meanDiv /= getMainSwarm().maxPosDist; + return meanDiv; + } + + /** + * ******************************************************************************************************************** + * setter, getter: infostrings + */ + /** + * @tested nn This method will return a naming String + * @return The name of the algorithm + */ + @Override + public String getName() { + return "NichePSO-" + getMainSwarmSize(); + } + + /** + * @tested nn This method will return a string describing all properties of + * the optimizer and the applied methods. + * @return A descriptive string + */ + @Override + public String getStringRepresentation() { + String result = ""; + result += "niching particle swarm optimization." + + " This algorithm optimizes multiple optima of an multimodal objective function in parallel.\n"; + return result; + } + + /** + * @tested emp returns a string that lists the global best individuals (ie + * best of all time) from every subswarm + * @return descriptive string of the elite + */ + public String getSubswarmRepresentativesAsString(boolean onlyInactive) { + String result = "\nSubswarmRepresentatives: \n"; + Population reps = getSubswarmRepresentatives(onlyInactive); + for (int i = 0; i < getSubSwarms().size(); ++i) { + result += reps.getEAIndividual(i).getStringRepresentation() + "\n"; + } + //result += "\n"; + return result; + } + + /** + * @tested emp + * @return + */ + public String getPerformanceAsString() { + if (!(m_Problem instanceof InterfaceMultimodalProblem)) { + System.out.println("getPerformanceAsString: problem not instanceof InterfaceMultimodalProblem"); + return ""; + } + + String result = "Performance (#Optima found, Max Peak Ratio, which optima are found): \n"; + + // construct an elite-population (with the gbest individual from every subswarm) + Population elitepop = getSubswarmRepresentatives(false); + + // use elite population to compute performance + if (m_Problem instanceof InterfaceMultimodalProblem) { + result += ((InterfaceMultimodalProblemKnown) m_Problem).getNumberOfFoundOptima(elitepop); + result += "(" + ((InterfaceMultimodalProblemKnown) m_Problem).getRealOptima().size() + ")\t"; + result += ((InterfaceMultimodalProblemKnown) m_Problem).getMaximumPeakRatio(elitepop) + "\t"; + //boolean[] opts = ((InterfaceMultimodalProblem)m_Problem).whichOptimaAreFound(elitepop); + //result += "Optima:"; + //for (int i = 0; i < opts.length; ++i){ + //result += String.valueOf(opts[i])+" "; + //} + result += "\n"; + } + return result; + } + + public String getReport() { + String result = new String(); + result = "Generations: " + getPopulation().getGeneration(); + result += " FunctionCalls: " + getPopulation().getFunctionCalls(); + result += " MainSwarmSize: " + getMainSwarm().getPopulation().size(); + result += " Subswarms: "; + for (int i = 0; i < getSubSwarms().size(); ++i) { + result += "(" + i + ")" + getSubSwarms().get(i).getPopulation().size() + " "; + } + result += "SwarmSize: " + getPopulation().size(); + result += "\n"; + + return result; + } + + /** + * ******************************************************************************************************************** + * for the logfile + */ + /** + * @tested emp generates the NichePSO_date file + */ + protected void initLogFile() { + // opening output file... + if (getDirForCurrentExperiment().equals("unset")) { + System.out.println("initLogFile: no directory for output specified, please use setDirForCurrentExperiment first"); + return; + } + + // path + File outputPath = new File(getDirForCurrentExperiment() + "\\NichePSO-LogFiles\\"); + if (!outputPath.exists()) { outputPath.mkdirs(); } - - //String outputPath = getDirForCurrentExperiment()+"/NichePSO-LogFiles/"; - //OutputPath = OutputPath + dirForCurrentExperiment+"\\NichePSO-LogFiles\\"; - - // file name - SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd'_'HH.mm.ss'_'E"); - String m_StartDate = formatter.format(new Date()); - String name ="NichePSO-LogFile"+"__"+m_StartDate+".dat"; - - File f = new File(outputPath,name); // plattform independent representation... - - try { - if (outputFile != null) { + + //String outputPath = getDirForCurrentExperiment()+"/NichePSO-LogFiles/"; + //OutputPath = OutputPath + dirForCurrentExperiment+"\\NichePSO-LogFiles\\"; + + // file name + SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd'_'HH.mm.ss'_'E"); + String m_StartDate = formatter.format(new Date()); + String name = "NichePSO-LogFile" + "__" + m_StartDate + ".dat"; + + File f = new File(outputPath, name); // plattform independent representation... + + try { + if (outputFile != null) { outputFile.close(); } // close old file - outputFile = new BufferedWriter(new OutputStreamWriter (new FileOutputStream (f))); - } catch (FileNotFoundException e) { - System.out.println("Could not open output file! Filename: " + name); - }catch (IOException e) { - System.out.println("Could not close old output file! Filename: " + name); - } + outputFile = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f))); + } catch (FileNotFoundException e) { + System.out.println("Could not open output file! Filename: " + name); + } catch (IOException e) { + System.out.println("Could not close old output file! Filename: " + name); + } } - - /** @tested emp - * writes something to the LogFile + + /** + * @tested emp writes something to the LogFile * @param line string to be written */ protected void writeToLogFile(String line) { - String write = line + "\n"; - if (outputFile == null) { + String write = line + "\n"; + if (outputFile == null) { return; } - try { - outputFile.write(write, 0, write.length()); - outputFile.flush(); - } catch (IOException e) { - System.out.println("Problems writing to output file!"); - } + try { + outputFile.write(write, 0, write.length()); + outputFile.flush(); + } catch (IOException e) { + System.out.println("Problems writing to output file!"); + } } -/**************************************************- plotting analysing debugging -************************************ -/********************************************************************************************************************** - * getter for debugging and analysing - */ - /** @tested - * @param pop + /** + * ************************************************- plotting analysing + * debugging -************************************ + * /********************************************************************************************************************** + * getter for debugging and analysing + */ + /** + * @tested @param pop * @param index * @return particle with given index */ - public AbstractEAIndividual getIndyByParticleIndexAndPopulation(Population pop, Integer index){ - for (int i = 0; i < pop.size(); ++i) - { - AbstractEAIndividual indy = pop.getEAIndividual(i); - //Integer tmp = (Integer)indy.getData("particleIndex"); // here getData was a cpu-time hotspot -> AbstractEAIndividual now has an index as "direct member" - //if (index.equals(tmp)) return indy; - if (index.intValue() == indy.getIndividualIndex()) { + public AbstractEAIndividual getIndyByParticleIndexAndPopulation(Population pop, Integer index) { + for (int i = 0; i < pop.size(); ++i) { + AbstractEAIndividual indy = pop.getEAIndividual(i); + //Integer tmp = (Integer)indy.getData("particleIndex"); // here getData was a cpu-time hotspot -> AbstractEAIndividual now has an index as "direct member" + //if (index.equals(tmp)) return indy; + if (index.intValue() == indy.getIndividualIndex()) { return indy; } - } - return null; + } + return null; } - /** @tested - * @param index + /** + * @tested @param index * @return main swarm particle with given index */ - public AbstractEAIndividual getIndyByParticleIndex(Integer index){ - AbstractEAIndividual indy = null; - Population pop = getMainSwarm().getPopulation(); - indy = getIndyByParticleIndexAndPopulation(pop, index); - if (indy != null) { + public AbstractEAIndividual getIndyByParticleIndex(Integer index) { + AbstractEAIndividual indy = null; + Population pop = getMainSwarm().getPopulation(); + indy = getIndyByParticleIndexAndPopulation(pop, index); + if (indy != null) { return indy; } - for (int i = 0; i < getSubSwarms().size(); ++i){ - pop = getSubSwarms().get(i).getPopulation(); - indy = getIndyByParticleIndexAndPopulation(pop, index); - if (indy != null) { + for (int i = 0; i < getSubSwarms().size(); ++i) { + pop = getSubSwarms().get(i).getPopulation(); + indy = getIndyByParticleIndexAndPopulation(pop, index); + if (indy != null) { return indy; } - } - return null; + } + return null; } - /** @tested - * @return particle with minimal stddev in fitness over the last 3 iterations + /** + * @tested @return particle with minimal stddev in fitness over the last 3 + * iterations */ - protected AbstractEAIndividual getIndyWithMinStdDev(){ - Population mainpop = getMainSwarm().getPopulation(); - if (mainpop.size() == 0) { + protected AbstractEAIndividual getIndyWithMinStdDev() { + Population mainpop = getMainSwarm().getPopulation(); + if (mainpop.size() == 0) { return null; } - - double min = Double.POSITIVE_INFINITY; + + double min = Double.POSITIVE_INFINITY; int minindex = 0; - AbstractEAIndividual tmpIndy1; - for (int i = 0; i < mainpop.size(); ++i){ - tmpIndy1 = (AbstractEAIndividual)mainpop.get(i); - Double da = (Double)((tmpIndy1).getData(NichePSO.stdDevKey)); - if (da.doubleValue() < min){ - min = da.doubleValue(); - minindex = i; - } + AbstractEAIndividual tmpIndy1; + for (int i = 0; i < mainpop.size(); ++i) { + tmpIndy1 = (AbstractEAIndividual) mainpop.get(i); + Double da = (Double) ((tmpIndy1).getData(NichePSO.stdDevKey)); + if (da.doubleValue() < min) { + min = da.doubleValue(); + minindex = i; + } } - return (AbstractEAIndividual)mainpop.get(minindex); + return (AbstractEAIndividual) mainpop.get(minindex); } - -/********************************************************************************************************************** - * plotting - */ - - /** @tested - * inits a new Topoplot + + /** + * ******************************************************************************************************************** + * plotting */ - protected void initPlotSwarm(){ - double[] a = new double[2]; + /** + * @tested inits a new Topoplot + */ + protected void initPlotSwarm() { + double[] a = new double[2]; a[0] = 0.0; a[1] = 0.0; - this.m_TopologySwarm = new TopoPlot("NichePSO-MainSwarm","x","y",a,a); - this.m_TopologySwarm.setParams(60,60); + this.m_TopologySwarm = new TopoPlot("NichePSO-MainSwarm", "x", "y", a, a); + this.m_TopologySwarm.setParams(60, 60); if (m_Problem instanceof Interface2DBorderProblem) { - this.m_TopologySwarm.setTopology((Interface2DBorderProblem)this.m_Problem); + this.m_TopologySwarm.setTopology((Interface2DBorderProblem) this.m_Problem); } // draws colored plot } - /** @tested - * clean everything except topology colors + /** + * @tested clean everything except topology colors */ - protected void cleanPlotSwarm(){ + protected void cleanPlotSwarm() { // delete all previous points DElement[] elements = this.m_TopologySwarm.getFunctionArea().getDElements(); - int lastIndex = elements.length-1; + int lastIndex = elements.length - 1; DElement last = elements[lastIndex]; - while (last instanceof DPointSet || last instanceof DPoint || last instanceof DPointIcon){ - this.m_TopologySwarm.getFunctionArea().removeDElement(last); + while (last instanceof DPointSet || last instanceof DPoint || last instanceof DPointIcon) { + this.m_TopologySwarm.getFunctionArea().removeDElement(last); // elements = this.m_TopologySwarm.getFunctionArea().getDElements(); - lastIndex--; - last = elements[lastIndex]; - } + lastIndex--; + last = elements[lastIndex]; + } } - - /** @tested - * plots the std dev of all particles in the main swarm + + /** + * @tested plots the std dev of all particles in the main swarm */ - protected void plotAllStdDevsInMainSwarm(){ - //add further information to MainSwarm-Plot point by point - InterfaceDataTypeDouble tmpIndy1; - Population mainpop = getMainSwarm().getPopulation(); - for (int i = 0; i < mainpop.size(); ++i){ - // add particle index to plot so it can be tracked over time - AbstractEAIndividual indy = mainpop.getEAIndividual(i); - Integer index= indy.getIndividualIndex();//(Integer)indy.getData("particleIndex"); - String id = "("+index.toString()+") "; - - tmpIndy1 = (InterfaceDataTypeDouble)mainpop.get(i); - DPoint point = new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]); - Double da = (Double)(((AbstractEAIndividual)tmpIndy1).getData(NichePSO.stdDevKey)); + protected void plotAllStdDevsInMainSwarm() { + //add further information to MainSwarm-Plot point by point + InterfaceDataTypeDouble tmpIndy1; + Population mainpop = getMainSwarm().getPopulation(); + for (int i = 0; i < mainpop.size(); ++i) { + // add particle index to plot so it can be tracked over time + AbstractEAIndividual indy = mainpop.getEAIndividual(i); + Integer index = indy.getIndividualIndex();//(Integer)indy.getData("particleIndex"); + String id = "(" + index.toString() + ") "; + + tmpIndy1 = (InterfaceDataTypeDouble) mainpop.get(i); + DPoint point = new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]); + Double da = (Double) (((AbstractEAIndividual) tmpIndy1).getData(NichePSO.stdDevKey)); double d = da.doubleValue(); String ds = String.format("%6.2f", d); - DPointIcon icon = new Chart2DDPointIconText(id+ds); - ((Chart2DDPointIconText)icon).setIcon(new Chart2DDPointIconCircle()); - point.setIcon(icon); - this.m_TopologySwarm.getFunctionArea().addDElement(point); - } - - //try to add further information to MainSwarm-Plot at once - /* popRep = new DPointSet(); - for (int i = 0; i < mainpop.size(); ++i){ - tmpIndy1 = (InterfaceDataTypeDouble)mainpop.get(i); - DPoint point = new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]); - double[] da = (double[])(((AbstractEAIndividual)tmpIndy1).getData("StdDevKey"));//Math.round(100*((AbstractEAIndividual)tmpIndy1).getFitness(0))/(double)100; - double d = da[0]; - String ds = String.format("%6.2f", d); - DPointIcon icon = new Chart2DDPointIconText(ds); - ((Chart2DDPointIconText)icon).setIcon(new Chart2DDPointIconCircle()); + DPointIcon icon = new Chart2DDPointIconText(id + ds); + ((Chart2DDPointIconText) icon).setIcon(new Chart2DDPointIconCircle()); point.setIcon(icon); - popRep.addDPoint(point); + this.m_TopologySwarm.getFunctionArea().addDElement(point); } - this.m_TopologyMainSwarm.m_PlotArea.addDElement(popRep); */ + + //try to add further information to MainSwarm-Plot at once + /* popRep = new DPointSet(); + for (int i = 0; i < mainpop.size(); ++i){ + tmpIndy1 = (InterfaceDataTypeDouble)mainpop.get(i); + DPoint point = new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]); + double[] da = (double[])(((AbstractEAIndividual)tmpIndy1).getData("StdDevKey"));//Math.round(100*((AbstractEAIndividual)tmpIndy1).getFitness(0))/(double)100; + double d = da[0]; + String ds = String.format("%6.2f", d); + DPointIcon icon = new Chart2DDPointIconText(ds); + ((Chart2DDPointIconText)icon).setIcon(new Chart2DDPointIconCircle()); + point.setIcon(icon); + popRep.addDPoint(point); + } + this.m_TopologyMainSwarm.m_PlotArea.addDElement(popRep); */ } - - /** @tested - * plots only the minimal std dev for the respective particle + + /** + * @tested plots only the minimal std dev for the respective particle */ - protected void plotMinStdDevInMainSwarm(){ + protected void plotMinStdDevInMainSwarm() { //add further information to MainSwarm-Plot (minimal stddev) - InterfaceDataTypeDouble tmpIndy1; + InterfaceDataTypeDouble tmpIndy1; AbstractEAIndividual indy = getIndyWithMinStdDev(); - tmpIndy1 = (InterfaceDataTypeDouble)indy; - Double da = (Double)((indy).getData(NichePSO.stdDevKey)); + tmpIndy1 = (InterfaceDataTypeDouble) indy; + Double da = (Double) ((indy).getData(NichePSO.stdDevKey)); double min = da.doubleValue(); DPoint point = new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]); String ds = String.format("%6.2f", min); DPointIcon icon = new Chart2DDPointIconText(ds); - ((Chart2DDPointIconText)icon).setIcon(new Chart2DDPointIconCircle()); - point.setIcon(icon); - this.m_TopologySwarm.getFunctionArea().addDElement(point); + ((Chart2DDPointIconText) icon).setIcon(new Chart2DDPointIconCircle()); + point.setIcon(icon); + this.m_TopologySwarm.getFunctionArea().addDElement(point); } - - /** @tested - * plots all std devs < boundary for the respective particles + + /** + * @tested plots all std devs < boundary for the respective particles * @param boundary */ - protected void plotBoundStdDevInMainSwarm(double boundary){ - InterfaceDataTypeDouble tmpIndy1; - Population mainpop = getMainSwarm().getPopulation(); - for (int i = 0; i < mainpop.size(); ++i){ - // add particle index to plot so it can be tracked over time - AbstractEAIndividual indy = mainpop.getEAIndividual(i); - Integer index= indy.getIndividualIndex();//(Integer)indy.getData("particleIndex"); - String id = "("+index.toString()+") "; - - tmpIndy1 = (InterfaceDataTypeDouble)mainpop.get(i); - DPoint point = new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]); - Double da = (Double)(((AbstractEAIndividual)tmpIndy1).getData(NichePSO.stdDevKey)); + protected void plotBoundStdDevInMainSwarm(double boundary) { + InterfaceDataTypeDouble tmpIndy1; + Population mainpop = getMainSwarm().getPopulation(); + for (int i = 0; i < mainpop.size(); ++i) { + // add particle index to plot so it can be tracked over time + AbstractEAIndividual indy = mainpop.getEAIndividual(i); + Integer index = indy.getIndividualIndex();//(Integer)indy.getData("particleIndex"); + String id = "(" + index.toString() + ") "; + + tmpIndy1 = (InterfaceDataTypeDouble) mainpop.get(i); + DPoint point = new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]); + Double da = (Double) (((AbstractEAIndividual) tmpIndy1).getData(NichePSO.stdDevKey)); double d = da.doubleValue(); String ds = String.format("%6.2f", d); - DPointIcon icon = new Chart2DDPointIconText(id+ds); - ((Chart2DDPointIconText)icon).setIcon(new Chart2DDPointIconCircle()); - point.setIcon(icon); + DPointIcon icon = new Chart2DDPointIconText(id + ds); + ((Chart2DDPointIconText) icon).setIcon(new Chart2DDPointIconCircle()); + point.setIcon(icon); if (d < boundary) { this.m_TopologySwarm.getFunctionArea().addDElement(point); - } + } } } - /** @tested - * plots a circle around the individual and adds some information + /** + * @tested plots a circle around the individual and adds some information * @param index index of the particle * @param text information to be added */ - protected void plotCircleForIndy(int index, String text){ - AbstractEAIndividual indy = getIndyByParticleIndex(new Integer(index)); - InterfaceDataTypeDouble tmpIndy1 = (InterfaceDataTypeDouble)indy; - DPoint point = new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]); - DPointIcon icon = new Chart2DDPointIconText(text); - ((Chart2DDPointIconText)icon).setIcon(new Chart2DDPointIconCircle()); + protected void plotCircleForIndy(int index, String text) { + AbstractEAIndividual indy = getIndyByParticleIndex(new Integer(index)); + InterfaceDataTypeDouble tmpIndy1 = (InterfaceDataTypeDouble) indy; + DPoint point = new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]); + DPointIcon icon = new Chart2DDPointIconText(text); + ((Chart2DDPointIconText) icon).setIcon(new Chart2DDPointIconCircle()); point.setIcon(icon); this.m_TopologySwarm.getFunctionArea().addDElement(point); } - - /** @tested - * plots a circle around the individual and adds some information + + /** + * @tested plots a circle around the individual and adds some information * @param indy invidual * @param text information to be added */ - protected void plotCircleForIndy(AbstractEAIndividual indy, String text){ - InterfaceDataTypeDouble tmpIndy1 = (InterfaceDataTypeDouble)indy; - DPoint point = new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]); - DPointIcon icon = new Chart2DDPointIconText(text); - ((Chart2DDPointIconText)icon).setIcon(new Chart2DDPointIconCircle()); + protected void plotCircleForIndy(AbstractEAIndividual indy, String text) { + InterfaceDataTypeDouble tmpIndy1 = (InterfaceDataTypeDouble) indy; + DPoint point = new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]); + DPointIcon icon = new Chart2DDPointIconText(text); + ((Chart2DDPointIconText) icon).setIcon(new Chart2DDPointIconCircle()); point.setIcon(icon); this.m_TopologySwarm.getFunctionArea().addDElement(point); } - - /** @tested - * cleans the previous plot and plots the mainswarm as points - */ + + /** + * @tested cleans the previous plot and plots the mainswarm as points + */ protected void plotMainSwarm(boolean withIDs) { - if (this.m_Problem instanceof Interface2DBorderProblem) { - DPointSet popRep = new DPointSet(); - InterfaceDataTypeDouble tmpIndy1; - - cleanPlotSwarm(); - - //draw MainSwarm - Population mainpop = getMainSwarm().getPopulation(); - for (int i = 0; i < mainpop.size(); i++) { - tmpIndy1 = (InterfaceDataTypeDouble)mainpop.get(i); - popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1])); - } - this.m_TopologySwarm.getFunctionArea().addDElement(popRep); // time consuming - - // identify every particle in the main swarm - if (withIDs){ - for (int i = 0; i < getMainSwarm().getPopulation().size(); ++i){ - AbstractEAIndividual currentindy = getMainSwarm().getPopulation().getEAIndividual(i); - int particleindex = currentindy.getIndividualIndex(); // should be unique and constant - - AbstractEAIndividual leader = (AbstractEAIndividual)currentindy.getData("MultiSwarmType"); - int leaderIndex = 0; - if (leader != null) { - leaderIndex = leader.getIndividualIndex(); - } - - if (currentindy.getData("newParticleFlag") != null){ - plotCircleForIndy(currentindy,particleindex + " reinit"); - currentindy.putData("newParticleFlag", null); - }else{ - String info = particleindex+ " (" + leaderIndex + ")"; - plotCircleForIndy(currentindy, info); - } - } - } - - //plotBoundStdDevInMainSwarm(MainSwarm.getDelta()+0.05); - //plotMinStdDevInMainSwarm(); - //plotAllStdDevsInMainSwarm(); - } - } - - protected void plotSubSwarmsWithIndizes(boolean plotActive,boolean plotInactive){ - for (int i = 0; i < this.getSubSwarms().size(); ++i){ - ParticleSubSwarmOptimization currentsub = this.getSubSwarms().get(i); - if (!currentsub.isActive() && plotInactive){ - plotCircleForIndy(currentsub.m_BestIndividual, String.valueOf(i)+"[I]"); - } - if (currentsub.isActive() && plotActive){ - plotCircleForIndy(currentsub.m_BestIndividual,String.valueOf(i)); - } - } - } - - protected void plotAbsorptionCondition(){ - for (int i = 0; i < indytoabsorb.size(); ++i){ - AbstractEAIndividual indy = indytoabsorb.get(i); - int particleIndex = indy.getIndividualIndex();//((Integer)indy.getData("particleIndex")).intValue(); - plotCircleForIndy(indytoabsorb.get(i), String.valueOf(particleIndex)+" absorption"); - } - } - - protected void plotMergingCondition(){ - for (int i = 0; i < this.borg.size(); ++i){ - plotSwarmToMerge(borg.get(i),i); - plotSwarmToMerge(others.get(i),i); - } - plotAbsorptionCondition(); - } - - protected void plotSwarmToMerge(ParticleSubSwarmOptimization swarm,int index) { - InterfaceDataTypeDouble tmpIndy1; - Population swarmpop = (Population)swarm.getPopulation(); - InterfaceDataTypeDouble best = (InterfaceDataTypeDouble)swarm.m_BestIndividual; - DPointSet popRep = new DPointSet(); - - //...draw SubSwarm as points - for (int j = 0; j < swarmpop.size(); j++) { - popRep.setConnected(false); - tmpIndy1 = (InterfaceDataTypeDouble)swarmpop.get(j); - popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1])); - } - this.m_TopologySwarm.getFunctionArea().addDElement(popRep); // time consuming + if (this.m_Problem instanceof Interface2DBorderProblem) { + DPointSet popRep = new DPointSet(); + InterfaceDataTypeDouble tmpIndy1; - //...draw circle for best - if (!swarm.isActive()){ - plotCircleForIndy((AbstractEAIndividual)best,"[I]-Merging "+String.valueOf(index)); - }else { - plotCircleForIndy((AbstractEAIndividual)best,getMaxStdDevFromSwarmAsString(swarm)+"-Merging "+String.valueOf(index)); + cleanPlotSwarm(); + + //draw MainSwarm + Population mainpop = getMainSwarm().getPopulation(); + for (int i = 0; i < mainpop.size(); i++) { + tmpIndy1 = (InterfaceDataTypeDouble) mainpop.get(i); + popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1])); + } + this.m_TopologySwarm.getFunctionArea().addDElement(popRep); // time consuming + + // identify every particle in the main swarm + if (withIDs) { + for (int i = 0; i < getMainSwarm().getPopulation().size(); ++i) { + AbstractEAIndividual currentindy = getMainSwarm().getPopulation().getEAIndividual(i); + int particleindex = currentindy.getIndividualIndex(); // should be unique and constant + + AbstractEAIndividual leader = (AbstractEAIndividual) currentindy.getData("MultiSwarmType"); + int leaderIndex = 0; + if (leader != null) { + leaderIndex = leader.getIndividualIndex(); + } + + if (currentindy.getData("newParticleFlag") != null) { + plotCircleForIndy(currentindy, particleindex + " reinit"); + currentindy.putData("newParticleFlag", null); + } else { + String info = particleindex + " (" + leaderIndex + ")"; + plotCircleForIndy(currentindy, info); + } + } + } + + //plotBoundStdDevInMainSwarm(MainSwarm.getDelta()+0.05); + //plotMinStdDevInMainSwarm(); + //plotAllStdDevsInMainSwarm(); } - - //...draw SubSwarm as connected lines to best - popRep = new DPointSet(); - for (int j = 0; j < swarmpop.size(); j++) { - tmpIndy1 = (InterfaceDataTypeDouble)swarmpop.get(j); - popRep.setConnected(true); - popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1])); - popRep.addDPoint(new DPoint(best.getDoubleData()[0], best.getDoubleData()[1])); - } - this.m_TopologySwarm.getFunctionArea().addDElement(popRep); // time consuming - - } + } - /** @tested - * plots all subswarms as connected lines to their respective best individual - */ + protected void plotSubSwarmsWithIndizes(boolean plotActive, boolean plotInactive) { + for (int i = 0; i < this.getSubSwarms().size(); ++i) { + ParticleSubSwarmOptimization currentsub = this.getSubSwarms().get(i); + if (!currentsub.isActive() && plotInactive) { + plotCircleForIndy(currentsub.m_BestIndividual, String.valueOf(i) + "[I]"); + } + if (currentsub.isActive() && plotActive) { + plotCircleForIndy(currentsub.m_BestIndividual, String.valueOf(i)); + } + } + } + + protected void plotAbsorptionCondition() { + for (int i = 0; i < indytoabsorb.size(); ++i) { + AbstractEAIndividual indy = indytoabsorb.get(i); + int particleIndex = indy.getIndividualIndex();//((Integer)indy.getData("particleIndex")).intValue(); + plotCircleForIndy(indytoabsorb.get(i), String.valueOf(particleIndex) + " absorption"); + } + } + + protected void plotMergingCondition() { + for (int i = 0; i < this.borg.size(); ++i) { + plotSwarmToMerge(borg.get(i), i); + plotSwarmToMerge(others.get(i), i); + } + plotAbsorptionCondition(); + } + + protected void plotSwarmToMerge(ParticleSubSwarmOptimization swarm, int index) { + InterfaceDataTypeDouble tmpIndy1; + Population swarmpop = (Population) swarm.getPopulation(); + InterfaceDataTypeDouble best = (InterfaceDataTypeDouble) swarm.m_BestIndividual; + DPointSet popRep = new DPointSet(); + + //...draw SubSwarm as points + for (int j = 0; j < swarmpop.size(); j++) { + popRep.setConnected(false); + tmpIndy1 = (InterfaceDataTypeDouble) swarmpop.get(j); + popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1])); + } + this.m_TopologySwarm.getFunctionArea().addDElement(popRep); // time consuming + + //...draw circle for best + if (!swarm.isActive()) { + plotCircleForIndy((AbstractEAIndividual) best, "[I]-Merging " + String.valueOf(index)); + } else { + plotCircleForIndy((AbstractEAIndividual) best, getMaxStdDevFromSwarmAsString(swarm) + "-Merging " + String.valueOf(index)); + } + + //...draw SubSwarm as connected lines to best + popRep = new DPointSet(); + for (int j = 0; j < swarmpop.size(); j++) { + tmpIndy1 = (InterfaceDataTypeDouble) swarmpop.get(j); + popRep.setConnected(true); + popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1])); + popRep.addDPoint(new DPoint(best.getDoubleData()[0], best.getDoubleData()[1])); + } + this.m_TopologySwarm.getFunctionArea().addDElement(popRep); // time consuming + + } + + /** + * @tested plots all subswarms as connected lines to their respective best + * individual + */ protected void plotSubSwarms() { - if (this.m_Problem instanceof Interface2DBorderProblem) { - //DPointSet popRep = new DPointSet(); - InterfaceDataTypeDouble tmpIndy1; - - //cleanPlotSubSwarms(); + if (this.m_Problem instanceof Interface2DBorderProblem) { + //DPointSet popRep = new DPointSet(); + InterfaceDataTypeDouble tmpIndy1; - // for all SubSwarms... - for (int i = 0; i < this.getSubSwarms().size(); i++) { - ParticleSubSwarmOptimization currentsubswarm = this.getSubSwarms().get(i); - Population currentsubswarmpop = (Population)currentsubswarm.getPopulation(); - //InterfaceDataTypeDouble best = (InterfaceDataTypeDouble)currentsubswarmpop.getBestIndividual(); - InterfaceDataTypeDouble best = (InterfaceDataTypeDouble)currentsubswarm.m_BestIndividual; - DPointSet popRep = new DPointSet(); - - //...draw SubSwarm as points - for (int j = 0; j < currentsubswarmpop.size(); j++) { - popRep.setConnected(false); - tmpIndy1 = (InterfaceDataTypeDouble)currentsubswarmpop.get(j); - popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1])); - } - this.m_TopologySwarm.getFunctionArea().addDElement(popRep); // time consuming + //cleanPlotSubSwarms(); - //...draw circle for best - if (!currentsubswarm.isActive()){ - plotCircleForIndy((AbstractEAIndividual)best,"[I]"); - }else{ - if (!getSubswarmOptimizerTemplate().isGcpso()){ - //plotCircleForIndy((AbstractEAIndividual)best,getMaxStdDevFromSwarmAsString(currentsubswarm)); - } - if (getSubswarmOptimizerTemplate().isGcpso()){ - String rhoAsString = String.format("%6.3f", currentsubswarm.getRho()); - //plotCircleForIndy((AbstractEAIndividual)best,rhoAsString); - if (currentsubswarm.gbestParticle != null){ - //plotCircleForIndy((AbstractEAIndividual)currentsubswarm.gbestParticle,"gbest"); - } - } - } - - //...draw SubSwarm as connected lines to best - popRep = new DPointSet(); - for (int j = 0; j < currentsubswarmpop.size(); j++) { - //popRep.setConnected(false); - tmpIndy1 = (InterfaceDataTypeDouble)currentsubswarmpop.get(j); - //popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1])); - - popRep.setConnected(true); - popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1])); - popRep.addDPoint(new DPoint(best.getDoubleData()[0], best.getDoubleData()[1])); - } - this.m_TopologySwarm.getFunctionArea().addDElement(popRep); // time consuming - } - } // endif - } + // for all SubSwarms... + for (int i = 0; i < this.getSubSwarms().size(); i++) { + ParticleSubSwarmOptimization currentsubswarm = this.getSubSwarms().get(i); + Population currentsubswarmpop = (Population) currentsubswarm.getPopulation(); + //InterfaceDataTypeDouble best = (InterfaceDataTypeDouble)currentsubswarmpop.getBestIndividual(); + InterfaceDataTypeDouble best = (InterfaceDataTypeDouble) currentsubswarm.m_BestIndividual; + DPointSet popRep = new DPointSet(); + + //...draw SubSwarm as points + for (int j = 0; j < currentsubswarmpop.size(); j++) { + popRep.setConnected(false); + tmpIndy1 = (InterfaceDataTypeDouble) currentsubswarmpop.get(j); + popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1])); + } + this.m_TopologySwarm.getFunctionArea().addDElement(popRep); // time consuming + + //...draw circle for best + if (!currentsubswarm.isActive()) { + plotCircleForIndy((AbstractEAIndividual) best, "[I]"); + } else { + if (!getSubswarmOptimizerTemplate().isGcpso()) { + //plotCircleForIndy((AbstractEAIndividual)best,getMaxStdDevFromSwarmAsString(currentsubswarm)); + } + if (getSubswarmOptimizerTemplate().isGcpso()) { + String rhoAsString = String.format("%6.3f", currentsubswarm.getRho()); + //plotCircleForIndy((AbstractEAIndividual)best,rhoAsString); + if (currentsubswarm.gbestParticle != null) { + //plotCircleForIndy((AbstractEAIndividual)currentsubswarm.gbestParticle,"gbest"); + } + } + } + + //...draw SubSwarm as connected lines to best + popRep = new DPointSet(); + for (int j = 0; j < currentsubswarmpop.size(); j++) { + //popRep.setConnected(false); + tmpIndy1 = (InterfaceDataTypeDouble) currentsubswarmpop.get(j); + //popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1])); + + popRep.setConnected(true); + popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1])); + popRep.addDPoint(new DPoint(best.getDoubleData()[0], best.getDoubleData()[1])); + } + this.m_TopologySwarm.getFunctionArea().addDElement(popRep); // time consuming + } + } // endif + } protected String getMaxStdDevFromSwarmAsString(ParticleSubSwarmOptimization swarm) { - double max = -1; - for (int i = 0; i < swarm.getPopulation().size(); ++i){ - AbstractEAIndividual currentindy = swarm.getPopulation().getEAIndividual(i); - Double da = (Double)((currentindy).getData(NichePSO.stdDevKey)); - double d = da.doubleValue(); - if (d > max){ - max = d; - } - } + double max = -1; + for (int i = 0; i < swarm.getPopulation().size(); ++i) { + AbstractEAIndividual currentindy = swarm.getPopulation().getEAIndividual(i); + Double da = (Double) ((currentindy).getData(NichePSO.stdDevKey)); + double d = da.doubleValue(); + if (d > max) { + max = d; + } + } String ds = String.format("%6.3f", max); - return ds; - } + return ds; + } - /** @tested - * plots information about merging, absorbtion and subswarm-creation - */ - protected void plotAdditionalInfo(){ - // from merging - if (mergingOccurd){ - for (int i = 0; i < borgbest.size(); ++i){ - plotCircleForIndy(borgbest.get(i), "merging " + i); - plotCircleForIndy(othersbest.get(i), "merging " + i); - } - } - - // from absorbtion - if (absorbtionOccurd){ - for (int i = 0; i < indytoabsorb.size(); ++i){ - AbstractEAIndividual indy = indytoabsorb.get(i); - int particleIndex = indy.getIndividualIndex(); - plotCircleForIndy(indy, particleIndex + " absorbed"); - } - } - - // from subswarm-creation - if (creationOccurd){ - for (int i = 0; i < indyconverged.size(); ++i){ - int convergedIndex = indyconverged.get(i).getIndividualIndex();//((Integer)indyconverged.get(i).getData("particleIndex")).intValue(); - int convergedneighborIndex = convergedneighbor.get(i).getIndividualIndex();//((Integer)convergedneighbor.get(i).getData("particleIndex")).intValue(); - plotCircleForIndy(indyconverged.get(i),"converged "+convergedIndex); - plotCircleForIndy(convergedneighbor.get(i),"neighbor "+convergedneighborIndex); - } - } - - // from deactivation and reinit - if (deactivationOccured){ - for (int i = 0; i < deactivatedSwarm.size(); ++i){ - plotCircleForIndy(deactivatedSwarm.get(i).m_BestIndividual," deac"); - } + /** + * @tested plots information about merging, absorbtion and subswarm-creation + */ + protected void plotAdditionalInfo() { + // from merging + if (mergingOccurd) { + for (int i = 0; i < borgbest.size(); ++i) { + plotCircleForIndy(borgbest.get(i), "merging " + i); + plotCircleForIndy(othersbest.get(i), "merging " + i); + } + } + + // from absorbtion + if (absorbtionOccurd) { + for (int i = 0; i < indytoabsorb.size(); ++i) { + AbstractEAIndividual indy = indytoabsorb.get(i); + int particleIndex = indy.getIndividualIndex(); + plotCircleForIndy(indy, particleIndex + " absorbed"); + } + } + + // from subswarm-creation + if (creationOccurd) { + for (int i = 0; i < indyconverged.size(); ++i) { + int convergedIndex = indyconverged.get(i).getIndividualIndex();//((Integer)indyconverged.get(i).getData("particleIndex")).intValue(); + int convergedneighborIndex = convergedneighbor.get(i).getIndividualIndex();//((Integer)convergedneighbor.get(i).getData("particleIndex")).intValue(); + plotCircleForIndy(indyconverged.get(i), "converged " + convergedIndex); + plotCircleForIndy(convergedneighbor.get(i), "neighbor " + convergedneighborIndex); + } + } + + // from deactivation and reinit + if (deactivationOccured) { + for (int i = 0; i < deactivatedSwarm.size(); ++i) { + plotCircleForIndy(deactivatedSwarm.get(i).m_BestIndividual, " deac"); + } // for (int i = 0; i < reinitedSwarm.size(); ++i){ // plotSwarm(reinitedSwarm.get(i)," reinit"); // } - } - } - - protected void plotSwarm(ParticleSubSwarmOptimization swarm, String text) { - for (int i = 0; i < swarm.getPopulation().size(); ++i){ - AbstractEAIndividual currentindy = swarm.getPopulation().getEAIndividual(i); - plotCircleForIndy(currentindy, text); - } - } - - /** @tested - * @param particleIndex - */ - protected void plotTraceIndy(int particleIndex){ - AbstractEAIndividual indy = getIndyByParticleIndex(new Integer(particleIndex)); - - // collect Information to be printed - String text = new String(); - double[] vel = (double[])indy.getData("velocity"); //beware: curVel -> newPos -> plot (not curVel -> plot -> newPos) - String xv = String.format("%6.2f", vel[0]); - String yv = String.format("%6.2f", vel[1]); - text = xv + " " + yv; - - // mark indy and add information - plotCircleForIndy(indy, text); - } - - /** @tested - * plots the old position, new position, personal best position and neighborhood best position for a given individual - * @param indy - */ - protected void plotStatusForIndy(AbstractEAIndividual indy){ - //plot newPos - InterfaceDataTypeDouble tmpIndy1 = (InterfaceDataTypeDouble)indy; - DPoint point = new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]); - DPointIcon icon = new Chart2DDPointIconText(""); - ((Chart2DDPointIconText)icon).setIcon(new Chart2DDPointIconPoint()); - point.setIcon(icon); - this.m_TopologySwarm.getFunctionArea().addDElement(point); - - //plot oldPos - if (!(indy.getData("oldPosition") == null)){ - double[] oldpos = (double[])indy.getData("oldPosition"); - point = new DPoint(oldpos[0], oldpos[1]); - icon = new Chart2DDPointIconText(""); - ((Chart2DDPointIconText)icon).setIcon(new Chart2DDPointIconCross()); - point.setIcon(icon); - this.m_TopologySwarm.getFunctionArea().addDElement(point); } - + } + + protected void plotSwarm(ParticleSubSwarmOptimization swarm, String text) { + for (int i = 0; i < swarm.getPopulation().size(); ++i) { + AbstractEAIndividual currentindy = swarm.getPopulation().getEAIndividual(i); + plotCircleForIndy(currentindy, text); + } + } + + /** + * @tested @param particleIndex + */ + protected void plotTraceIndy(int particleIndex) { + AbstractEAIndividual indy = getIndyByParticleIndex(new Integer(particleIndex)); + + // collect Information to be printed + String text = new String(); + double[] vel = (double[]) indy.getData("velocity"); //beware: curVel -> newPos -> plot (not curVel -> plot -> newPos) + String xv = String.format("%6.2f", vel[0]); + String yv = String.format("%6.2f", vel[1]); + text = xv + " " + yv; + + // mark indy and add information + plotCircleForIndy(indy, text); + } + + /** + * @tested plots the old position, new position, personal best position and + * neighborhood best position for a given individual + * @param indy + */ + protected void plotStatusForIndy(AbstractEAIndividual indy) { + //plot newPos + InterfaceDataTypeDouble tmpIndy1 = (InterfaceDataTypeDouble) indy; + DPoint point = new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]); + DPointIcon icon = new Chart2DDPointIconText(""); + ((Chart2DDPointIconText) icon).setIcon(new Chart2DDPointIconPoint()); + point.setIcon(icon); + this.m_TopologySwarm.getFunctionArea().addDElement(point); + + //plot oldPos + if (!(indy.getData("oldPosition") == null)) { + double[] oldpos = (double[]) indy.getData("oldPosition"); + point = new DPoint(oldpos[0], oldpos[1]); + icon = new Chart2DDPointIconText(""); + ((Chart2DDPointIconText) icon).setIcon(new Chart2DDPointIconCross()); + point.setIcon(icon); + this.m_TopologySwarm.getFunctionArea().addDElement(point); + } + //plot personalBestPos - double[] pbestpos = (double[])indy.getData("BestPosition"); - point = new DPoint(pbestpos[0], pbestpos[1]); - icon = new Chart2DDPointIconText(""); - ((Chart2DDPointIconText)icon).setIcon(new Chart2DDPointIconCircle()); + double[] pbestpos = (double[]) indy.getData("BestPosition"); + point = new DPoint(pbestpos[0], pbestpos[1]); + icon = new Chart2DDPointIconText(""); + ((Chart2DDPointIconText) icon).setIcon(new Chart2DDPointIconCircle()); point.setIcon(icon); this.m_TopologySwarm.getFunctionArea().addDElement(point); - + //plot neighbourBestPos - double[] neighbourBestPos = (double[])indy.getData("neighbourBestPos"); - point = new DPoint(neighbourBestPos[0], neighbourBestPos[1]); - icon = new Chart2DDPointIconText(""); - ((Chart2DDPointIconText)icon).setIcon(new Chart2DDPointIconContent()); + double[] neighbourBestPos = (double[]) indy.getData("neighbourBestPos"); + point = new DPoint(neighbourBestPos[0], neighbourBestPos[1]); + icon = new Chart2DDPointIconText(""); + ((Chart2DDPointIconText) icon).setIcon(new Chart2DDPointIconContent()); point.setIcon(icon); this.m_TopologySwarm.getFunctionArea().addDElement(point); - } - + } + // protected void saveCurrentPlotAsJPG(String filename){ // if (getDirForCurrentExperiment().equals("unset")) { // System.out.println("saveCurrentPlotAsJPG: no directory for output specified, please use setDirForCurrentExperiment first"); @@ -2091,203 +2134,212 @@ public class NichePSO implements InterfaceAdditionalPopulationInformer, Interfac // Thread.sleep(1000); // nichts l�schen vor speichern...synchrosleep // } catch (InterruptedException e) {} // } - - protected String getCurrentDateAsString(){ - SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd'_'HH.mm.ss'_'E"); - String date = formatter.format(new Date()); - return date; - } - - public static final GOParameters nichePSO(AbstractOptimizationProblem problem, long randSeed, InterfaceTerminator term) { - NichePSO npso = new NichePSO(); - npso.setMainSwarmSize(75); + protected String getCurrentDateAsString() { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd'_'HH.mm.ss'_'E"); + String date = formatter.format(new Date()); + return date; + } - return OptimizerFactory.makeParams(npso, 75, problem, randSeed, term); - } + public static final GOParameters nichePSO(AbstractOptimizationProblem problem, long randSeed, InterfaceTerminator term) { + NichePSO npso = new NichePSO(); + npso.setMainSwarmSize(75); - /** - * Create a Niche PSO with parameters as to Brits, Engelbrecht & Bergh: A Niching Particle Swarm Optimizer. SEAL 2002. - * Exeption: the swarm size is 200 by default, because 30 (of the orig. paper) seems way too low. - * - * The evaluation count is required currently due to the generation-dependent intertness decay used by the std. variant. - * To alter the terminator, use GOParameters.setTerminator(), and mind the intertness behavior of the NichePSO, - * which can be altered by using getMainSwarm().setInertnessAging(InterfaceParameteraging) - * - * @param problem - * @param randSeed - * @param evalCnt - * @return - */ - public static final GOParameters stdNPSO(AbstractOptimizationProblem problem, long randSeed, int evalCnt) { - return stdNPSO(null, problem, randSeed, evalCnt); - } - - public static final GOParameters starNPSO(AbstractOptimizationProblem problem, long randSeed, int evalCnt) { - return starNPSO(null, problem, randSeed, evalCnt); - } - - /** - * Set parameters as to Brits, Engelbrecht & Bergh: A Niching Particle Swarm Optimizer. SEAL 2002. - * Exeption: the swarm size is 100 by default, because 30 (of the orig. paper) seems way too low. - * - * @see #stdNPSO(AbstractOptimizationProblem, long, int) - * @param an already existing NichePSO instance or null to create a new one - * @param problem - * @param randSeed - * @param evalCnt - * @return - */ - public static final GOParameters stdNPSO(NichePSO npso, AbstractOptimizationProblem problem, long randSeed, int evalCnt) { - if (npso == null) { - npso = new NichePSO(); - } - int popSize = 100; - npso.setMainSwarmSize(popSize); + return OptimizerFactory.makeParams(npso, 75, problem, randSeed, term); + } + + /** + * Create a Niche PSO with parameters as to Brits, Engelbrecht & Bergh: A + * Niching Particle Swarm Optimizer. SEAL 2002. Exeption: the swarm size is + * 200 by default, because 30 (of the orig. paper) seems way too low. + * + * The evaluation count is required currently due to the + * generation-dependent intertness decay used by the std. variant. To alter + * the terminator, use GOParameters.setTerminator(), and mind the intertness + * behavior of the NichePSO, which can be altered by using + * getMainSwarm().setInertnessAging(InterfaceParameteraging) + * + * @param problem + * @param randSeed + * @param evalCnt + * @return + */ + public static final GOParameters stdNPSO(AbstractOptimizationProblem problem, long randSeed, int evalCnt) { + return stdNPSO(null, problem, randSeed, evalCnt); + } + + public static final GOParameters starNPSO(AbstractOptimizationProblem problem, long randSeed, int evalCnt) { + return starNPSO(null, problem, randSeed, evalCnt); + } + + /** + * Set parameters as to Brits, Engelbrecht & Bergh: A Niching Particle Swarm + * Optimizer. SEAL 2002. Exeption: the swarm size is 100 by default, because + * 30 (of the orig. paper) seems way too low. + * + * @see #stdNPSO(AbstractOptimizationProblem, long, int) + * @param an already existing NichePSO instance or null to create a new one + * @param problem + * @param randSeed + * @param evalCnt + * @return + */ + public static final GOParameters stdNPSO(NichePSO npso, AbstractOptimizationProblem problem, long randSeed, int evalCnt) { + if (npso == null) { + npso = new NichePSO(); + } + int popSize = 100; + npso.setMainSwarmSize(popSize); // double avgRange = Mathematics.getAvgRange(((InterfaceDataTypeDouble)problem.getIndividualTemplate()).getDoubleRange()); - // set strategies - npso.setDeactivationStrategy(new StandardDeactivationStrategy(0.00001)); - npso.setMergingStrategy(new StandardMergingStrategy(0.001)); - npso.setAbsorptionStrategy(new StandardAbsorptionStrategy()); - npso.setSubswarmCreationStrategy(new StandardSubswarmCreationStrategy(0.0001)); - - npso.setMaxAllowedSwarmRadius(0.0001); // formally limits the swarm radius of the subswarms - - // Parameter for the mainswarm - npso.getMainSwarmAlgoType().setSelectedTag("Inertness"); - npso.getMainSwarm().setPhi1(1.2); - npso.getMainSwarm().setPhi2(0); // by default no communication in the mainswarm - npso.SetMainSwarmTopologyTag(0); // this doesnt have any effect due to no communication - npso.setMainSwarmTopologyRange(0); - npso.mainSwarmAlgoType = 0; - npso.getMainSwarm().setParameterControl(new ParamAdaption[]{getDefaultInertnessAdaption()}); + // set strategies + npso.setDeactivationStrategy(new StandardDeactivationStrategy(0.00001)); + npso.setMergingStrategy(new StandardMergingStrategy(0.001)); + npso.setAbsorptionStrategy(new StandardAbsorptionStrategy()); + npso.setSubswarmCreationStrategy(new StandardSubswarmCreationStrategy(0.0001)); + + npso.setMaxAllowedSwarmRadius(0.0001); // formally limits the swarm radius of the subswarms + + // Parameter for the mainswarm + npso.getMainSwarmAlgoType().setSelectedTag("Inertness"); + npso.getMainSwarm().setPhi1(1.2); + npso.getMainSwarm().setPhi2(0); // by default no communication in the mainswarm + npso.SetMainSwarmTopologyTag(0); // this doesnt have any effect due to no communication + npso.setMainSwarmTopologyRange(0); + npso.mainSwarmAlgoType = 0; + npso.getMainSwarm().setParameterControl(new ParamAdaption[]{getDefaultInertnessAdaption()}); // npso.getMainSwarm().setSpeedLimit(avgRange/2.); // npso.getMainSwarm().setCheckSpeedLimit(true); - - // parameter for the subswarms - npso.getSubswarmOptimizerTemplate().setGcpso(true); - npso.getSubswarmOptimizerTemplate().setRho(0.1); // on 2D Problems empirically better than default value 1 + + // parameter for the subswarms + npso.getSubswarmOptimizerTemplate().setGcpso(true); + npso.getSubswarmOptimizerTemplate().setRho(0.1); // on 2D Problems empirically better than default value 1 // npso.getSubswarmOptimizerTemplate().setAlgoType(new SelectedTag("Constriction")); - npso.getSubswarmOptimizerTemplate().setAlgoType(npso.getSubswarmOptimizerTemplate().getAlgoType().setSelectedTag("Constriction")); // constriction - npso.getSubswarmOptimizerTemplate().setConstriction(2.05, 2.05); + npso.getSubswarmOptimizerTemplate().setAlgoType(npso.getSubswarmOptimizerTemplate().getAlgoType().setSelectedTag("Constriction")); // constriction + npso.getSubswarmOptimizerTemplate().setConstriction(2.05, 2.05); // npso.getSubswarmOptimizerTemplate().setInertnessAging(new LinearParameterAging(0.7, 0.2, evalCnt/(10*popSize))); // expect shorter - - return OptimizerFactory.makeParams(npso, popSize, problem, randSeed, new EvaluationTerminator(evalCnt)); - } - - /** - * Set parameters as to Brits, Engelbrecht & Bergh: A Niching Particle Swarm Optimizer. SEAL 2002. - * Exeption: the swarm size is 200 by default, because 30 (of the orig. paper) seems way too low. - * - * @see #stdNPSO(AbstractOptimizationProblem, long, int) - * @param an already existing NichePSO instance or null to create a new one - * @param problem - * @param randSeed - * @param evalCnt - * @return - */ - public static final GOParameters starNPSO(NichePSO npso, AbstractOptimizationProblem problem, long randSeed, int evalCnt) { - starNPSO(npso, evalCnt); - return OptimizerFactory.makeParams(npso, npso.getMainSwarmSize(), problem, randSeed, new EvaluationTerminator(evalCnt)); - } - - public static final NichePSO starNPSO(NichePSO npso, int evalCnt) { - if (npso == null) { - npso = new NichePSO(); - } - int popSize = 200; - npso.setMainSwarmSize(popSize); + + return OptimizerFactory.makeParams(npso, popSize, problem, randSeed, new EvaluationTerminator(evalCnt)); + } + + /** + * Set parameters as to Brits, Engelbrecht & Bergh: A Niching Particle Swarm + * Optimizer. SEAL 2002. Exeption: the swarm size is 200 by default, because + * 30 (of the orig. paper) seems way too low. + * + * @see #stdNPSO(AbstractOptimizationProblem, long, int) + * @param an already existing NichePSO instance or null to create a new one + * @param problem + * @param randSeed + * @param evalCnt + * @return + */ + public static final GOParameters starNPSO(NichePSO npso, AbstractOptimizationProblem problem, long randSeed, int evalCnt) { + starNPSO(npso, evalCnt); + return OptimizerFactory.makeParams(npso, npso.getMainSwarmSize(), problem, randSeed, new EvaluationTerminator(evalCnt)); + } + + public static final NichePSO starNPSO(NichePSO npso, int evalCnt) { + if (npso == null) { + npso = new NichePSO(); + } + int popSize = 200; + npso.setMainSwarmSize(popSize); // double avgRange = Mathematics.getAvgRange(((InterfaceDataTypeDouble)problem.getIndividualTemplate()).getDoubleRange()); - // set strategies - npso.setDeactivationStrategy(new StandardDeactivationStrategy()); - npso.setMergingStrategy(new ScatterMergingStrategy(0.001)); - npso.setAbsorptionStrategy(new EuclideanDiversityAbsorptionStrategy(0.1));// 0.1 used in "Enhancing the NichePSO" by Engelbrecht et al. - npso.setSubswarmCreationStrategy(new StandardSubswarmCreationStrategy(0.0001)); // from "Enhancing the NichePSO" by Engelbrecht et al. - - npso.setMaxAllowedSwarmRadius(0.0001); // formally limits the swarm radius of the subswarms - - // Parameter for the mainswarm - npso.setMainSwarmAlgoType(npso.getMainSwarm().getAlgoType().setSelectedTag("Inertness")); // constriction - npso.getMainSwarm().setPhi1(1.2); + // set strategies + npso.setDeactivationStrategy(new StandardDeactivationStrategy()); + npso.setMergingStrategy(new ScatterMergingStrategy(0.001)); + npso.setAbsorptionStrategy(new EuclideanDiversityAbsorptionStrategy(0.1));// 0.1 used in "Enhancing the NichePSO" by Engelbrecht et al. + npso.setSubswarmCreationStrategy(new StandardSubswarmCreationStrategy(0.0001)); // from "Enhancing the NichePSO" by Engelbrecht et al. + + npso.setMaxAllowedSwarmRadius(0.0001); // formally limits the swarm radius of the subswarms + + // Parameter for the mainswarm + npso.setMainSwarmAlgoType(npso.getMainSwarm().getAlgoType().setSelectedTag("Inertness")); // constriction + npso.getMainSwarm().setPhi1(1.2); // npso.SetMainSwarmPhi2(0); // by default no communication in the mainswarm - npso.SetMainSwarmTopologyTag(0); // this doesnt have any effect due to no communication - npso.setMainSwarmTopologyRange(0); - npso.mainSwarmAlgoType = 0; - npso.getMainSwarm().setParameterControl(new ParamAdaption[]{getDefaultInertnessAdaption()}); + npso.SetMainSwarmTopologyTag(0); // this doesnt have any effect due to no communication + npso.setMainSwarmTopologyRange(0); + npso.mainSwarmAlgoType = 0; + npso.getMainSwarm().setParameterControl(new ParamAdaption[]{getDefaultInertnessAdaption()}); // npso.setMainSwarmInertness(new LinearParameterAging(0.7, 0.2, evalCnt/popSize)); // npso.getMainSwarm().setSpeedLimit(avgRange/2.); // npso.getMainSwarm().setCheckSpeedLimit(true); - // parameters for the subswarms - npso.getSubswarmOptimizerTemplate().setGcpso(true); - npso.getSubswarmOptimizerTemplate().setRho(0.01); - npso.getSubswarmOptimizerTemplate().setAlgoType(new SelectedTag("Constriction")); + // parameters for the subswarms + npso.getSubswarmOptimizerTemplate().setGcpso(true); + npso.getSubswarmOptimizerTemplate().setRho(0.01); + npso.getSubswarmOptimizerTemplate().setAlgoType(new SelectedTag("Constriction")); - npso.getSubswarmOptimizerTemplate().setConstriction(2.05, 2.05); + npso.getSubswarmOptimizerTemplate().setConstriction(2.05, 2.05); // npso.getSubswarmOptimizerTemplate().setInertnessAging(new NoParameterAging(npso.getSubswarmOptimizerTemplate().getInertnessOrChi())); // System.out.println(BeanInspector.niceToString(npso)); - return npso; - } - + return npso; + } + @Override - public String[] getAdditionalDataHeader() { - return new String[]{"mainSwarmSize","numActSpec","avgSpecSize", "numArchived", "archivedMedCorr", "archivedMeanDist", "mainSwarmInertness"}; - } - + public String[] getAdditionalDataHeader() { + return new String[]{"mainSwarmSize", "numActSpec", "avgSpecSize", "numArchived", "archivedMedCorr", "archivedMeanDist", "mainSwarmInertness"}; + } + @Override - public String[] getAdditionalDataInfo() { - return new String[]{"Size of the main swarm of explorers", - "Number of sub-swarms currently active", - "Average sub-swarm size", - "The number of stored potential local optima", - "The median correlation of stored solutions", - "The mean distance of stored solutions", - "Current inertness of the main swarm"}; - } - + public String[] getAdditionalDataInfo() { + return new String[]{"Size of the main swarm of explorers", + "Number of sub-swarms currently active", + "Average sub-swarm size", + "The number of stored potential local optima", + "The median correlation of stored solutions", + "The mean distance of stored solutions", + "Current inertness of the main swarm"}; + } + @Override - public Object[] getAdditionalDataValue(PopulationInterface pop) { - int actSwarms = countActiveSubswarms(); - double avgSpSize = getAvgActiveSubSwarmSize(); - Population inactives = getSubswarmRepresentatives(true); - double medCor = inactives.getCorrelations()[3]; // median correlation of best indies of inactive subswarms - double meanDist = inactives.getPopulationMeasures()[0]; - return new Object[]{getMainSwarm().getPopulation().size(), - actSwarms, - avgSpSize, - getNumArchived(), - medCor, - meanDist, - getMainSwarm().getInertnessOrChi()}; - } - - /** - * Return the number of archived solutions, which is the number of inactive subswarms. - * @return - */ - protected int getNumArchived() { - return (getSubSwarms().size()-countActiveSubswarms()); - } - - /** - * This method is necessary to allow access from the Processor. - * @return - */ - public Object[] getParamControl() { - List ctrlbls = ParameterControlManager.listOfControllables(this); - ctrlbls.add(paramControl); - return ctrlbls.toArray(); - // this works - however differently than when returning a ParameterControlManager - } - - public ParamAdaption[] getParameterControl() { - return paramControl.getSingleAdapters(); - } - public void setParameterControl(ParamAdaption[] paramControl) { - this.paramControl.setSingleAdapters(paramControl); - } - public String parameterControlTipText() { - return "You may define dynamic paramter control strategies using the parameter name."; - } + public Object[] getAdditionalDataValue(PopulationInterface pop) { + int actSwarms = countActiveSubswarms(); + double avgSpSize = getAvgActiveSubSwarmSize(); + Population inactives = getSubswarmRepresentatives(true); + double medCor = inactives.getCorrelations()[3]; // median correlation of best indies of inactive subswarms + double meanDist = inactives.getPopulationMeasures()[0]; + return new Object[]{getMainSwarm().getPopulation().size(), + actSwarms, + avgSpSize, + getNumArchived(), + medCor, + meanDist, + getMainSwarm().getInertnessOrChi()}; + } + + /** + * Return the number of archived solutions, which is the number of inactive + * subswarms. + * + * @return + */ + protected int getNumArchived() { + return (getSubSwarms().size() - countActiveSubswarms()); + } + + /** + * This method is necessary to allow access from the Processor. + * + * @return + */ + public Object[] getParamControl() { + List ctrlbls = ParameterControlManager.listOfControllables(this); + ctrlbls.add(paramControl); + return ctrlbls.toArray(); + // this works - however differently than when returning a ParameterControlManager + } + + public ParamAdaption[] getParameterControl() { + return paramControl.getSingleAdapters(); + } + + public void setParameterControl(ParamAdaption[] paramControl) { + this.paramControl.setSingleAdapters(paramControl); + } + + public String parameterControlTipText() { + return "You may define dynamic paramter control strategies using the parameter name."; + } } \ No newline at end of file diff --git a/src/eva2/server/go/strategies/ParticleFilterOptimization.java b/src/eva2/server/go/strategies/ParticleFilterOptimization.java index ff3a28a6..792a4b7b 100644 --- a/src/eva2/server/go/strategies/ParticleFilterOptimization.java +++ b/src/eva2/server/go/strategies/ParticleFilterOptimization.java @@ -1,6 +1,5 @@ package eva2.server.go.strategies; - import eva2.gui.BeanInspector; import eva2.gui.GenericObjectEditor; import eva2.gui.Plot; @@ -22,38 +21,35 @@ import eva2.server.go.problems.InterfaceOptimizationProblem; /** * This is a Particle Filter implemented by Frank Senke, only some documentation * here and not completely checked whether this works on arbitrary problem - * instances. MK did some adaptations, this should work on real valued problems now. - * - * This is a implementation of Genetic Algorithms. - * Copyright: Copyright (c) 2003 - * Company: University of Tuebingen, Computer Architecture - * @author Felix Streichert - * @version: $Revision: 307 $ - * $Date: 2007-12-04 14:31:47 +0100 (Tue, 04 Dec 2007) $ - * $Author: mkron $ + * instances. MK did some adaptations, this should work on real valued problems + * now. + * + * This is a implementation of Genetic Algorithms. Copyright: Copyright (c) 2003 + * Company: University of Tuebingen, Computer Architecture + * + * @author Felix Streichert + * @version: $Revision: 307 $ $Date: 2007-12-04 14:31:47 +0100 (Tue, 04 Dec + * 2007) $ $Author: mkron $ */ - public class ParticleFilterOptimization implements InterfaceOptimizer, java.io.Serializable { /** - * Comment for serialVersionUID - */ - private static final long serialVersionUID = 1L; - private Population m_Population = new Population(); - private InterfaceOptimizationProblem m_Problem = new F1Problem(); - private InterfaceSelection m_ParentSelection = new SelectParticleWheel(0.5); + * Comment for + * serialVersionUID + */ + private static final long serialVersionUID = 1L; + private Population m_Population = new Population(); + private InterfaceOptimizationProblem m_Problem = new F1Problem(); + private InterfaceSelection m_ParentSelection = new SelectParticleWheel(0.5); //private boolean m_UseElitism = true; - - private String m_Identifier = ""; - private boolean withShow = false; - private double mutationSigma = 0.01; - private double randomImmigrationQuota = 0.05; - private double initialVelocity = 0.02; - private double rotationDeg = 20.; - private int popSize = 300; - - private int sleepTime = 0; - + private String m_Identifier = ""; + private boolean withShow = false; + private double mutationSigma = 0.01; + private double randomImmigrationQuota = 0.05; + private double initialVelocity = 0.02; + private double rotationDeg = 20.; + private int popSize = 300; + private int sleepTime = 0; transient private int indCount = 0; transient private InterfacePopulationChangedEventListener m_Listener; transient Plot myPlot = null; @@ -64,35 +60,35 @@ public class ParticleFilterOptimization implements InterfaceOptimizer, java.io.S setWithShow(true); } } - + public ParticleFilterOptimization(double vInit, double mute, double immiQuote, double rotDeg, double selScaling) { - mutationSigma = mute; - initialVelocity = vInit; - randomImmigrationQuota = immiQuote; - rotationDeg = rotDeg; - m_ParentSelection = new SelectParticleWheel(selScaling); + mutationSigma = mute; + initialVelocity = vInit; + randomImmigrationQuota = immiQuote; + rotationDeg = rotDeg; + m_ParentSelection = new SelectParticleWheel(selScaling); if (withShow) { setWithShow(true); } } - + public ParticleFilterOptimization(ParticleFilterOptimization a) { - this.m_Population = (Population)a.m_Population.clone(); - this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone(); - this.m_Identifier = a.m_Identifier; + this.m_Population = (Population) a.m_Population.clone(); + this.m_Problem = (InterfaceOptimizationProblem) a.m_Problem.clone(); + this.m_Identifier = a.m_Identifier; //this.m_Plague = a.m_Plague; //this.m_NumberOfPartners = a.m_NumberOfPartners; //this.m_UseElitism = a.m_UseElitism; - this.m_ParentSelection = (InterfaceSelection)a.m_ParentSelection.clone(); + this.m_ParentSelection = (InterfaceSelection) a.m_ParentSelection.clone(); if (a.withShow) { setWithShow(true); } } public void hideHideable() { - GenericObjectEditor.setHideProperty(this.getClass(), "population", true); + GenericObjectEditor.setHideProperty(this.getClass(), "population", true); } - + @Override public Object clone() { return (Object) new ParticleFilterOptimization(this); @@ -102,37 +98,40 @@ public class ParticleFilterOptimization implements InterfaceOptimizer, java.io.S public void init() { //System.out.println("popsize is " + m_Population.size()); //System.out.println("pops targ is " + m_Population.getPopulationSize()); - - if (initialVelocity <= 0.) { - (((AbstractOptimizationProblem)m_Problem).getIndividualTemplate()).setMutationOperator(new MutateESFixedStepSize(mutationSigma)); - } else { - (((AbstractOptimizationProblem)m_Problem).getIndividualTemplate()).setMutationOperator(new MutateESCorrVector(mutationSigma, initialVelocity, rotationDeg)); - } - m_Population.setTargetSize(popSize); + + if (initialVelocity <= 0.) { + (((AbstractOptimizationProblem) m_Problem).getIndividualTemplate()).setMutationOperator(new MutateESFixedStepSize(mutationSigma)); + } else { + (((AbstractOptimizationProblem) m_Problem).getIndividualTemplate()).setMutationOperator(new MutateESCorrVector(mutationSigma, initialVelocity, rotationDeg)); + } + m_Population.setTargetSize(popSize); this.m_Problem.initPopulation(this.m_Population); - + setWithShow(withShow); - this.evaluatePopulation(this.m_Population); + this.evaluatePopulation(this.m_Population); this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** This method will init the optimizer with a given population - * @param pop The initial population - * @param reset If true the population is reset. + /** + * This method will init the optimizer with a given population + * + * @param pop The initial population + * @param reset If true the population is reset. */ @Override public void initByPopulation(Population pop, boolean reset) { - this.m_Population = (Population)pop.clone(); + this.m_Population = (Population) pop.clone(); if (reset) { - this.m_Population.init(); + this.m_Population.init(); this.evaluatePopulation(this.m_Population); this.firePropertyChangedEvent(Population.nextGenerationPerformed); } } - /** This method will evaluate the current population using the - * given problem. + /** + * This method will evaluate the current population using the given problem. + * * @param population The population that is to be evaluated */ private Population evaluatePopulation(Population population) { @@ -141,66 +140,65 @@ public class ParticleFilterOptimization implements InterfaceOptimizer, java.io.S return population; } - /** - * This method will resample the given population using EA parent selection. - * + /** + * This method will resample the given population using EA parent selection. + * */ protected Population resample(Population pop) { Population parents; - boolean doImmigr=false; - + boolean doImmigr = false; + this.m_ParentSelection.prepareSelection(pop); - + // Generate a Population of Parents with Parantselectionmethod. // DONT forget cloning -> selection does only shallow copies! int targetSize = this.m_Population.getTargetSize(); - if (randomImmigrationQuota>0) { - if (randomImmigrationQuota>1.) { + if (randomImmigrationQuota > 0) { + if (randomImmigrationQuota > 1.) { System.err.println("Error, invalid immigration quota!"); + } else { + targetSize = (int) (this.m_Population.getTargetSize() * (1. - randomImmigrationQuota)); + targetSize = Math.max(1, targetSize); // guarantee at least one to be selected + if (targetSize < this.m_Population.getTargetSize()) { + doImmigr = true; + } } - else { - targetSize = (int)(this.m_Population.getTargetSize() * (1.-randomImmigrationQuota)); - targetSize = Math.max(1, targetSize); // guarantee at least one to be selected - if (targetSize < this.m_Population.getTargetSize()) { - doImmigr=true; - } - } } - parents = (Population)(this.m_ParentSelection.selectFrom(pop, targetSize)).clone(); - + parents = (Population) (this.m_ParentSelection.selectFrom(pop, targetSize)).clone(); + if (doImmigr) { - // add immigrants - AbstractEAIndividual immi; - int i; - for (i=0; (i+parents.getTargetSize()) 0 ) { - try { Thread.sleep(sleepTime); } catch(Exception e) {} + if (sleepTime > 0) { + try { + Thread.sleep(sleepTime); + } catch (Exception e) { + } } if (withShow) { clearPlot(); @@ -263,92 +263,102 @@ public class ParticleFilterOptimization implements InterfaceOptimizer, java.io.S if (TRACE) { System.out.println("Speed is " + BeanInspector.toString(ParticleSwarmOptimization.getPopulationVelSpeed(m_Population, 3, MutateESCorrVector.vectorKey, null, null)) + " popM " + BeanInspector.toString(m_Population.getPopulationMeasures(new EuclideanMetric()))); } - + m_Population = evaluatePopulation(nextGeneration); - + // collectStatistics(m_Population); - + this.firePropertyChangedEvent(Population.nextGenerationPerformed); - + } @Override public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { this.m_Listener = ea; } + @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - protected void firePropertyChangedEvent (String name) { + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } + + protected void firePropertyChangedEvent(String name) { if (this.m_Listener != null) { this.m_Listener.registerPopulationStateChanged(this, name); } } - /** This method will set the problem that is to be optimized + /** + * This method will set the problem that is to be optimized + * * @param problem */ @Override - public void setProblem (InterfaceOptimizationProblem problem) { + public void setProblem(InterfaceOptimizationProblem problem) { this.m_Problem = problem; - if (problem instanceof AbstractOptimizationProblem) { - ((AbstractOptimizationProblem)problem).informAboutOptimizer(this); - } + if (problem instanceof AbstractOptimizationProblem) { + ((AbstractOptimizationProblem) problem).informAboutOptimizer(this); + } } + @Override - public InterfaceOptimizationProblem getProblem () { + public InterfaceOptimizationProblem getProblem() { return this.m_Problem; } - /** This method will return a string describing all properties of the optimizer - * and the applied methods. + /** + * This method will return a string describing all properties of the + * optimizer and the applied methods. + * * @return A descriptive string */ @Override public String getStringRepresentation() { - StringBuilder strB=new StringBuilder(200); + StringBuilder strB = new StringBuilder(200); strB.append("Particle Filter:\nOptimization Problem: "); strB.append(this.m_Problem.getStringRepresentationForProblem(this)); strB.append("\n"); strB.append(this.m_Population.getStringRepresentation()); return strB.toString(); } - /** This method allows you to set an identifier for the algorithm - * @param name The indenifier + + /** + * This method allows you to set an identifier for the algorithm + * + * @param name The indenifier */ @Override - public void setIdentifier(String name) { + public void setIdentifier(String name) { this.m_Identifier = name; } - @Override - public String getIdentifier() { - return this.m_Identifier; - } - /** This method is required to free the memory on a RMIServer, - * but there is nothing to implement. - */ @Override - public void freeWilly() { - + public String getIdentifier() { + return this.m_Identifier; } -/********************************************************************************************************************** - * These are for GUI - */ - /** This method returns a global info string + + /** + * ******************************************************************************************************************** + * These are for GUI + */ + /** + * This method returns a global info string + * * @return description */ public static String globalInfo() { return "This is a Particle Filter Algorithm."; } - /** This method will return a naming String + + /** + * This method will return a naming String + * * @return The name of the algorithm */ @Override @@ -356,158 +366,171 @@ public class ParticleFilterOptimization implements InterfaceOptimizer, java.io.S return "PF"; } - /** Assuming that all optimizer will store thier data in a population - * we will allow acess to this population to query to current state - * of the optimizer. + /** + * Assuming that all optimizer will store thier data in a population we will + * allow acess to this population to query to current state of the + * optimizer. + * * @return The population of current solutions to a given problem. */ @Override public Population getPopulation() { return this.m_Population; } + @Override - public void setPopulation(Population pop){ + public void setPopulation(Population pop) { this.m_Population = pop; } + public String populationTipText() { return "Edit the properties of the population used."; } - + @Override public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(getPopulation()); + return new SolutionSet(getPopulation()); } - /** This method will set the selection method that is to be used + + /** + * This method will set the selection method that is to be used + * * @param selection */ public void setParentSelection(InterfaceSelection selection) { this.m_ParentSelection = selection; } + public InterfaceSelection getParentSelection() { return this.m_ParentSelection; } + public String parentSelectionTipText() { return "Choose a parent selection method."; } - /** - * @return the withShow - **/ - public boolean isWithShow() { - return withShow; - } + /** + * @return the withShow + * + */ + public boolean isWithShow() { + return withShow; + } - public Plot getPlot() { - return myPlot; - } - - protected void clearPlot() { - if (myPlot!=null) { - myPlot.clearAll(); - double[][] range = null; - if ((m_Population != null) && (m_Population.size() > 0)) { - range = ((InterfaceDataTypeDouble)this.m_Population.get(0)).getDoubleRange(); - } - if (range != null) { - myPlot.setCornerPoints(range, 0); - } - } - } - - /** - * @param withShow the withShow to set - **/ - public void setWithShow(boolean wShow) { - this.withShow = wShow; - if (!withShow) { - myPlot = null; + public Plot getPlot() { + return myPlot; + } + + protected void clearPlot() { + if (myPlot != null) { + myPlot.clearAll(); + double[][] range = null; + if ((m_Population != null) && (m_Population.size() > 0)) { + range = ((InterfaceDataTypeDouble) this.m_Population.get(0)).getDoubleRange(); } - else { - double[][] range; - if ((m_Population != null) && (m_Population.size() > 0)) { - range = ((InterfaceDataTypeDouble)this.m_Population.get(0)).getDoubleRange(); - } - else { - range = new double[2][]; - range[0] = new double[2]; - range[0][0] = 0; - range[0][1] = 0; - range[1] = range[0]; // this is evil - } - myPlot = new eva2.gui.Plot("PF", "x1", "x2", range[0], range[1]); - } - } + if (range != null) { + myPlot.setCornerPoints(range, 0); + } + } + } - /** - * @return the sleepTime - **/ - public int getSleepTime() { - return sleepTime; - } + /** + * @param withShow the withShow to set + * + */ + public void setWithShow(boolean wShow) { + this.withShow = wShow; + if (!withShow) { + myPlot = null; + } else { + double[][] range; + if ((m_Population != null) && (m_Population.size() > 0)) { + range = ((InterfaceDataTypeDouble) this.m_Population.get(0)).getDoubleRange(); + } else { + range = new double[2][]; + range[0] = new double[2]; + range[0][0] = 0; + range[0][1] = 0; + range[1] = range[0]; // this is evil + } + myPlot = new eva2.gui.Plot("PF", "x1", "x2", range[0], range[1]); + } + } - /** - * @param sleepTime the sleepTime to set - **/ - public void setSleepTime(int sleepTime) { - this.sleepTime = sleepTime; - } + /** + * @return the sleepTime + * + */ + public int getSleepTime() { + return sleepTime; + } - /** - * @return the mutationSigma - **/ - public double getMutationSigma() { - return mutationSigma; - } + /** + * @param sleepTime the sleepTime to set + * + */ + public void setSleepTime(int sleepTime) { + this.sleepTime = sleepTime; + } - /** - * @param mutationSigma the mutationSigma to set - **/ - public void setMutationSigma(double mutationSigma) { - this.mutationSigma = mutationSigma; - } - - public String mutationSigmaTipText() { - return "The (fixed) mutation step for the gaussian motion model"; - } + /** + * @return the mutationSigma + * + */ + public double getMutationSigma() { + return mutationSigma; + } - public double getRndImmigrQuota() { - return randomImmigrationQuota; - } + /** + * @param mutationSigma the mutationSigma to set + * + */ + public void setMutationSigma(double mutationSigma) { + this.mutationSigma = mutationSigma; + } - public void setRndImmigrQuota(double randomImmigrationQuota) { - this.randomImmigrationQuota = randomImmigrationQuota; - } - - public String rndImmigrQuotaTipText() { - return "The give ratio of the population will be reinitialized randomly in every iteration."; - } + public String mutationSigmaTipText() { + return "The (fixed) mutation step for the gaussian motion model"; + } - public double getInitialVelocity() { - return initialVelocity; - } + public double getRndImmigrQuota() { + return randomImmigrationQuota; + } - public void setInitialVelocity(double initialVelocity) { - this.initialVelocity = initialVelocity; - } - - public String initialVelocityTipText() { - return "If > 0, a linear motion model will be applied, otherwise the gaussian model"; - } + public void setRndImmigrQuota(double randomImmigrationQuota) { + this.randomImmigrationQuota = randomImmigrationQuota; + } - public double getRotationDeg() { - return rotationDeg; - } + public String rndImmigrQuotaTipText() { + return "The give ratio of the population will be reinitialized randomly in every iteration."; + } - public void setRotationDeg(double rotationDeg) { - this.rotationDeg = rotationDeg; - } + public double getInitialVelocity() { + return initialVelocity; + } - public int getPopSize() { - return popSize; - } + public void setInitialVelocity(double initialVelocity) { + this.initialVelocity = initialVelocity; + } - public void setPopSize(int popSize) { - this.popSize = popSize; - m_Population.setTargetSize(popSize); - } + public String initialVelocityTipText() { + return "If > 0, a linear motion model will be applied, otherwise the gaussian model"; + } + + public double getRotationDeg() { + return rotationDeg; + } + + public void setRotationDeg(double rotationDeg) { + this.rotationDeg = rotationDeg; + } + + public int getPopSize() { + return popSize; + } + + public void setPopSize(int popSize) { + this.popSize = popSize; + m_Population.setTargetSize(popSize); + } } diff --git a/src/eva2/server/go/strategies/ParticleSwarmOptimization.java b/src/eva2/server/go/strategies/ParticleSwarmOptimization.java index 443a5380..9b8b8ecc 100644 --- a/src/eva2/server/go/strategies/ParticleSwarmOptimization.java +++ b/src/eva2/server/go/strategies/ParticleSwarmOptimization.java @@ -1731,14 +1731,6 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se return this.m_Identifier; } - /** - * This method is required to free the memory on a RMIServer, but there is - * nothing to implement. - */ - @Override - public void freeWilly() { - } - /** * ******************************************************************************************************************** * These are for GUI @@ -2063,7 +2055,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se /** * @return true if swarm visualization is turned on - * + * */ public boolean isShow() { return m_Show; @@ -2071,7 +2063,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se /** * @param set swarm visualization (2D) - * + * */ public void setShow(boolean show) { m_Show = show; @@ -2086,7 +2078,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se /** * @return the checkSpeedLimit - * + * */ public boolean isCheckSpeedLimit() { return checkSpeedLimit; @@ -2094,7 +2086,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se /** * @param checkSpeedLimit the checkSpeedLimit to set - * + * */ public void setCheckSpeedLimit(boolean checkSpeedLimit) { this.checkSpeedLimit = checkSpeedLimit; @@ -2113,7 +2105,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // } /** * @return the sleepTime - * + * */ public int getSleepTime() { return sleepTime; @@ -2121,7 +2113,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se /** * @param sleepTime the sleepTime to set - * + * */ public void setSleepTime(int sleepTime) { this.sleepTime = sleepTime; diff --git a/src/eva2/server/go/strategies/PopulationBasedIncrementalLearning.java b/src/eva2/server/go/strategies/PopulationBasedIncrementalLearning.java index 5d5376bf..e42cd9de 100644 --- a/src/eva2/server/go/strategies/PopulationBasedIncrementalLearning.java +++ b/src/eva2/server/go/strategies/PopulationBasedIncrementalLearning.java @@ -13,50 +13,50 @@ import eva2.server.go.problems.AbstractOptimizationProblem; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; -/** Population based incremental learning in the PSM by Monmarche - * version with also allows to simulate ant systems due to the flexible - * update rule of V. But both are limited to binary genotypes. - * This is a simple implementation of Population Based Incremental Learning. - * - * Nicolas Monmarché , Eric Ramat , Guillaume Dromel , Mohamed Slimane , Gilles Venturini: - * On the similarities between AS, BSC and PBIL: toward the birth of a new meta-heuristic. - * TecReport 215. Univ. de Tours, 1999. - * - * Copyright: Copyright (c) 2003 - * Company: University of Tuebingen, Computer Architecture - * @author Felix Streichert - * @version: $Revision: 307 $ - * $Date: 2007-12-04 14:31:47 +0100 (Tue, 04 Dec 2007) $ - * $Author: mkron $ +/** + * Population based incremental learning in the PSM by Monmarche version with + * also allows to simulate ant systems due to the flexible update rule of V. But + * both are limited to binary genotypes. This is a simple implementation of + * Population Based Incremental Learning. + * + * Nicolas Monmarché , Eric Ramat , Guillaume Dromel , Mohamed Slimane , Gilles + * Venturini: On the similarities between AS, BSC and PBIL: toward the birth of + * a new meta-heuristic. TecReport 215. Univ. de Tours, 1999. + * + * Copyright: Copyright (c) 2003 Company: University of Tuebingen, Computer + * Architecture + * + * @author Felix Streichert + * @version: $Revision: 307 $ $Date: 2007-12-04 14:31:47 +0100 (Tue, 04 Dec + * 2007) $ $Author: mkron $ */ - public class PopulationBasedIncrementalLearning implements InterfaceOptimizer, java.io.Serializable { // These variables are necessary for the simple testcase - private InterfaceOptimizationProblem m_Problem = new B1Problem(); - private boolean m_UseElitism = true; - private InterfaceSelection m_SelectionOperator = new SelectBestIndividuals(); - transient private String m_Identifier = ""; + private InterfaceOptimizationProblem m_Problem = new B1Problem(); + private boolean m_UseElitism = true; + private InterfaceSelection m_SelectionOperator = new SelectBestIndividuals(); + transient private String m_Identifier = ""; transient private InterfacePopulationChangedEventListener m_Listener; - private Population m_Population = new PBILPopulation(); - private double m_LearningRate = 0.04; - private double m_MutationRate = 0.5; - private double m_MutateSigma = 0.01; - private int m_NumberOfPositiveSamples = 1; - private double[] m_initialProbabilities = ((PBILPopulation)m_Population).getProbabilityVector(); + private Population m_Population = new PBILPopulation(); + private double m_LearningRate = 0.04; + private double m_MutationRate = 0.5; + private double m_MutateSigma = 0.01; + private int m_NumberOfPositiveSamples = 1; + private double[] m_initialProbabilities = ((PBILPopulation) m_Population).getProbabilityVector(); public PopulationBasedIncrementalLearning() { } public PopulationBasedIncrementalLearning(PopulationBasedIncrementalLearning a) { - this.m_Population = (Population)a.m_Population.clone(); - this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone(); - this.m_LearningRate = a.m_LearningRate; - this.m_MutationRate = a.m_MutationRate; - this.m_MutateSigma = a.m_MutateSigma; - this.m_NumberOfPositiveSamples = a.m_NumberOfPositiveSamples; - this.m_UseElitism = a.m_UseElitism; - this.m_SelectionOperator = (InterfaceSelection)a.m_SelectionOperator.clone(); + this.m_Population = (Population) a.m_Population.clone(); + this.m_Problem = (InterfaceOptimizationProblem) a.m_Problem.clone(); + this.m_LearningRate = a.m_LearningRate; + this.m_MutationRate = a.m_MutationRate; + this.m_MutateSigma = a.m_MutateSigma; + this.m_NumberOfPositiveSamples = a.m_NumberOfPositiveSamples; + this.m_UseElitism = a.m_UseElitism; + this.m_SelectionOperator = (InterfaceSelection) a.m_SelectionOperator.clone(); } @Override @@ -67,10 +67,10 @@ public class PopulationBasedIncrementalLearning implements InterfaceOptimizer, j @Override public void init() { this.m_Problem.initPopulation(this.m_Population); - if ((m_initialProbabilities!=null) && (m_initialProbabilities.length==((PBILPopulation)m_Population).getProbabilityVector().length)) { - ((PBILPopulation)m_Population).setProbabilityVector(m_initialProbabilities); + if ((m_initialProbabilities != null) && (m_initialProbabilities.length == ((PBILPopulation) m_Population).getProbabilityVector().length)) { + ((PBILPopulation) m_Population).setProbabilityVector(m_initialProbabilities); } else { - if (m_initialProbabilities!=null) { + if (m_initialProbabilities != null) { System.err.println("Warning: initial probability vector doesnt match in length!"); } } @@ -78,27 +78,30 @@ public class PopulationBasedIncrementalLearning implements InterfaceOptimizer, j this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** This method will init the optimizer with a given population - * @param pop The initial population - * @param reset If true the population is reset. + /** + * This method will init the optimizer with a given population + * + * @param pop The initial population + * @param reset If true the population is reset. */ @Override public void initByPopulation(Population pop, boolean reset) { if (!(pop.getEAIndividual(0) instanceof InterfaceGAIndividual)) { - System.err.println("Error: PBIL only works with GAIndividuals!"); + System.err.println("Error: PBIL only works with GAIndividuals!"); } this.m_Population = new PBILPopulation(); - this.m_Population.addPopulation((Population)pop.clone()); + this.m_Population.addPopulation((Population) pop.clone()); if (reset) { - this.m_Population.init(); + this.m_Population.init(); this.evaluatePopulation(this.m_Population); } - ((PBILPopulation)this.m_Population).buildProbabilityVector(); + ((PBILPopulation) this.m_Population).buildProbabilityVector(); this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** This method will evaluate the current population using the - * given problem. + /** + * This method will evaluate the current population using the given problem. + * * @param population The population that is to be evaluated */ private void evaluatePopulation(Population population) { @@ -106,17 +109,18 @@ public class PopulationBasedIncrementalLearning implements InterfaceOptimizer, j population.incrGeneration(); } - /** This method will generate the offspring population from the - * given population of evaluated individuals. + /** + * This method will generate the offspring population from the given + * population of evaluated individuals. */ private Population generateChildren() { - PBILPopulation result = (PBILPopulation)this.m_Population.clone(); - Population examples; + PBILPopulation result = (PBILPopulation) this.m_Population.clone(); + Population examples; // this.m_NormationOperator.computeSelectionProbability(this.m_Population, "Fitness"); //System.out.println("Population:"+this.m_Population.getSolutionRepresentationFor()); this.m_SelectionOperator.prepareSelection(this.m_Population); - examples = this.m_SelectionOperator.selectFrom(this.m_Population, this.m_NumberOfPositiveSamples); + examples = this.m_SelectionOperator.selectFrom(this.m_Population, this.m_NumberOfPositiveSamples); //System.out.println("Parents:"+parents.getSolutionRepresentationFor()); result.learnFrom(examples, this.m_LearningRate); result.mutateProbabilityVector(this.m_MutationRate, this.m_MutateSigma); @@ -127,7 +131,7 @@ public class PopulationBasedIncrementalLearning implements InterfaceOptimizer, j @Override public void optimize() { Population nextGeneration; - AbstractEAIndividual elite; + AbstractEAIndividual elite; nextGeneration = this.generateChildren(); this.evaluatePopulation(nextGeneration); @@ -141,46 +145,55 @@ public class PopulationBasedIncrementalLearning implements InterfaceOptimizer, j this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** This method will set the problem that is to be optimized + /** + * This method will set the problem that is to be optimized + * * @param problem */ @Override - public void setProblem (InterfaceOptimizationProblem problem) { + public void setProblem(InterfaceOptimizationProblem problem) { this.m_Problem = problem; if (m_Problem instanceof AbstractOptimizationProblem) { - if (!(((AbstractOptimizationProblem)m_Problem).getIndividualTemplate() instanceof InterfaceGAIndividual)) { - System.err.println("Error: PBIL only works with GAIndividuals!"); - } + if (!(((AbstractOptimizationProblem) m_Problem).getIndividualTemplate() instanceof InterfaceGAIndividual)) { + System.err.println("Error: PBIL only works with GAIndividuals!"); + } } } + @Override - public InterfaceOptimizationProblem getProblem () { + public InterfaceOptimizationProblem getProblem() { return this.m_Problem; } + @Override public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { this.m_Listener = ea; } + @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - /** Something has changed + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } + + /** + * Something has changed */ - protected void firePropertyChangedEvent (String name) { + protected void firePropertyChangedEvent(String name) { if (this.m_Listener != null) { this.m_Listener.registerPopulationStateChanged(this, name); } } - /** This method will return a string describing all properties of the optimizer - * and the applied methods. + /** + * This method will return a string describing all properties of the + * optimizer and the applied methods. + * * @return A descriptive string */ @Override @@ -188,39 +201,42 @@ public class PopulationBasedIncrementalLearning implements InterfaceOptimizer, j String result = ""; result += "Population Based Incremental Learning:\n"; result += "Optimization Problem: "; - result += this.m_Problem.getStringRepresentationForProblem(this) +"\n"; + result += this.m_Problem.getStringRepresentationForProblem(this) + "\n"; result += this.m_Population.getStringRepresentation(); return result; } - /** This method allows you to set an identifier for the algorithm - * @param name The indenifier + + /** + * This method allows you to set an identifier for the algorithm + * + * @param name The indenifier */ @Override - public void setIdentifier(String name) { + public void setIdentifier(String name) { this.m_Identifier = name; } - @Override - public String getIdentifier() { - return this.m_Identifier; - } - /** This method is required to free the memory on a RMIServer, - * but there is nothing to implement. + @Override + public String getIdentifier() { + return this.m_Identifier; + } + + /** + * ******************************************************************************************************************** + * These are for GUI */ - @Override - public void freeWilly() { - - } -/********************************************************************************************************************** - * These are for GUI - */ - /** This method returns a global info string + /** + * This method returns a global info string + * * @return description */ public static String globalInfo() { return "The Population based incremental learning is based on a statistical distribution of bit positions. Please note: This optimizer requires a binary genotype!"; } - /** This method will return a naming String + + /** + * This method will return a naming String + * * @return The name of the algorithm */ @Override @@ -228,26 +244,30 @@ public class PopulationBasedIncrementalLearning implements InterfaceOptimizer, j return "PBIL"; } - /** Assuming that all optimizer will store thier data in a population - * we will allow acess to this population to query to current state - * of the optimizer. + /** + * Assuming that all optimizer will store thier data in a population we will + * allow acess to this population to query to current state of the + * optimizer. + * * @return The population of current solutions to a given problem. */ @Override public Population getPopulation() { return this.m_Population; } + @Override - public void setPopulation(Population pop){ + public void setPopulation(Population pop) { this.m_Population = pop; } + public String populationTipText() { return "Edit the properties of the PBIL population used."; } - + @Override public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(getPopulation()); + return new SolutionSet(getPopulation()); } // /** This method will set the normation method that is to be used. // * @param normation @@ -262,52 +282,66 @@ public class PopulationBasedIncrementalLearning implements InterfaceOptimizer, j // return "Select the normation method."; // } - /** This method will set the selection method that is to be used + /** + * This method will set the selection method that is to be used + * * @param selection */ public void setSelectionMethod(InterfaceSelection selection) { this.m_SelectionOperator = selection; } + public InterfaceSelection getSelectionMethod() { return this.m_SelectionOperator; } + public String selectionMethodTipText() { return "Choose a selection method."; } - /** This method will set the problem that is to be optimized + /** + * This method will set the problem that is to be optimized + * * @param elitism */ - public void setElitism (boolean elitism) { + public void setElitism(boolean elitism) { this.m_UseElitism = elitism; } + public boolean getElitism() { return this.m_UseElitism; } + public String elitismTipText() { return "Enable/disable elitism."; } - /** This method will set the learning rate for PBIL + /** + * This method will set the learning rate for PBIL + * * @param LearningRate */ - public void setLearningRate (double LearningRate) { + public void setLearningRate(double LearningRate) { this.m_LearningRate = LearningRate; if (this.m_LearningRate < 0) { this.m_LearningRate = 0; } } + public double getLearningRate() { return this.m_LearningRate; } + public String learningRateTipText() { return "The learing rate of PBIL."; } - /** This method will set the mutation rate for PBIL + /** + * This method will set the mutation rate for PBIL + * * @param m */ - public void setMutationRate (double m) { + public void setMutationRate(double m) { this.m_MutationRate = m; if (this.m_MutationRate < 0) { this.m_MutationRate = 0; @@ -315,51 +349,61 @@ public class PopulationBasedIncrementalLearning implements InterfaceOptimizer, j if (this.m_MutationRate > 1) { this.m_MutationRate = 1; } - } + } + public double getMutationRate() { return this.m_MutationRate; } + public String mutationRateTipText() { return "The mutation rate of PBIL."; } - /** This method will set the mutation sigma for PBIL + /** + * This method will set the mutation sigma for PBIL + * * @param m */ - public void setMutateSigma (double m) { + public void setMutateSigma(double m) { this.m_MutateSigma = m; if (this.m_MutateSigma < 0) { this.m_MutateSigma = 0; } } + public double getMutateSigma() { return this.m_MutateSigma; } + public String mutateSigmaTipText() { return "Set the sigma for the mutation of the probability vector."; } - /** This method will set the number of positive samples for PBIL + /** + * This method will set the number of positive samples for PBIL + * * @param PositiveSamples */ - public void setPositiveSamples (int PositiveSamples) { + public void setPositiveSamples(int PositiveSamples) { this.m_NumberOfPositiveSamples = PositiveSamples; if (this.m_NumberOfPositiveSamples < 1) { this.m_NumberOfPositiveSamples = 1; } } + public int getPositiveSamples() { return this.m_NumberOfPositiveSamples; } + public String positiveSamplesTipText() { return "The number of positive samples that update the PBIL vector."; } - public double[] getInitialProbabilities() { - return m_initialProbabilities; - } + public double[] getInitialProbabilities() { + return m_initialProbabilities; + } - public void setInitialProbabilities(double[] probabilities) { - m_initialProbabilities = probabilities; - } + public void setInitialProbabilities(double[] probabilities) { + m_initialProbabilities = probabilities; + } } \ No newline at end of file diff --git a/src/eva2/server/go/strategies/ScatterSearch.java b/src/eva2/server/go/strategies/ScatterSearch.java index 817baf1a..6031a80c 100644 --- a/src/eva2/server/go/strategies/ScatterSearch.java +++ b/src/eva2/server/go/strategies/ScatterSearch.java @@ -25,162 +25,164 @@ import eva2.tools.math.RNG; import java.util.ArrayList; /** - * A ScatterSearch implementation taken mainly from [1]. Unfortunately, some parameters as well as - * the local search method are not well defined in [1], so this implementation allows HC and Nelder-Mead - * as local search. If local search is activated, an additional filter is defined, meaning that only those - * individuals with a high quality fitness are further improved by local search. - * The threshold fitness is either defined relatively to the best/worst fitness values in the reference set - * or as an absolute value (in both cases only the first fitness criterion is regarded). - * + * A ScatterSearch implementation taken mainly from [1]. Unfortunately, some + * parameters as well as the local search method are not well defined in [1], so + * this implementation allows HC and Nelder-Mead as local search. If local + * search is activated, an additional filter is defined, meaning that only those + * individuals with a high quality fitness are further improved by local search. + * The threshold fitness is either defined relatively to the best/worst fitness + * values in the reference set or as an absolute value (in both cases only the + * first fitness criterion is regarded). + * * @author mkron * - * [1] M.Rodiguez-Fernandez, J.Egea, J.Banga: Novel metaheuristic for parameter estimation in nonlinear dynamic biological systems. - * BMC Bioinformatics 2006, 7:483. BioMed Central 2006. + * [1] M.Rodiguez-Fernandez, J.Egea, J.Banga: Novel metaheuristic for parameter + * estimation in nonlinear dynamic biological systems. BMC Bioinformatics 2006, + * 7:483. BioMed Central 2006. */ public class ScatterSearch implements InterfaceOptimizer, java.io.Serializable, InterfacePopulationChangedEventListener { - transient private InterfacePopulationChangedEventListener m_Listener = null; - private String m_Identifier = "ScatterSearch"; - private AbstractOptimizationProblem problem = new F1Problem(); - private Population oldRefSet, refSet = new Population(10); - private transient Population combinations = null; - private AbstractEAIndividual template = null; - private double[][] range = null; - private int refSetSize = 10; // default: 10 - private int poolSize = 100; // default: 10*refSetSize; - // splitting each dimension into intervals to do diverse initialization - private int intervals = 4; - private int localSearchSteps = 100; - private double localSearchFitnessFilter = 1.5; - private int probDim = -1; - private boolean firstTime = true; - private int lastImprovementCount = 0; - private SelectedTag localSearchMethod = new SelectedTag(1, "Hill-Climber", "Nelder-Mead"); - // simulate an EvA generational cycle - private int generationCycle = 50; - private int fitCrit = -1; - - protected boolean checkRange = true; - + + transient private InterfacePopulationChangedEventListener m_Listener = null; + private String m_Identifier = "ScatterSearch"; + private AbstractOptimizationProblem problem = new F1Problem(); + private Population oldRefSet, refSet = new Population(10); + private transient Population combinations = null; + private AbstractEAIndividual template = null; + private double[][] range = null; + private int refSetSize = 10; // default: 10 + private int poolSize = 100; // default: 10*refSetSize; + // splitting each dimension into intervals to do diverse initialization + private int intervals = 4; + private int localSearchSteps = 100; + private double localSearchFitnessFilter = 1.5; + private int probDim = -1; + private boolean firstTime = true; + private int lastImprovementCount = 0; + private SelectedTag localSearchMethod = new SelectedTag(1, "Hill-Climber", "Nelder-Mead"); + // simulate an EvA generational cycle + private int generationCycle = 50; + private int fitCrit = -1; + protected boolean checkRange = true; // private int lastLocalSearch = -1; // // nr of generations between local searches // protected int localSearchInterval = 10; - // below this threshold a local search will be performed + // below this threshold a local search will be performed // protected double fitThreshLocalSearch = 1000.; - protected boolean doLocalSearch = false; - private boolean relativeFitCriterion = false; - private double nelderMeadInitPerturbation = 0.01; - private double improvementEpsilon = 0.1; // minimal relative fitness improvement for a candidate to be taken over into the refset - private double minDiversityEpsilon = 0.0001; // minimal phenotypic distance for a candidate to be taken over into the refset + protected boolean doLocalSearch = false; + private boolean relativeFitCriterion = false; + private double nelderMeadInitPerturbation = 0.01; + private double improvementEpsilon = 0.1; // minimal relative fitness improvement for a candidate to be taken over into the refset + private double minDiversityEpsilon = 0.0001; // minimal phenotypic distance for a candidate to be taken over into the refset + private static boolean TRACE = false; - private static boolean TRACE = false; + public ScatterSearch() { + GenericObjectEditor.setHideProperty(this.getClass(), "population", true); + hideHideable(); + } - public ScatterSearch() { - GenericObjectEditor.setHideProperty(this.getClass(), "population", true); - hideHideable(); - } - - public ScatterSearch(ScatterSearch o) { - this.refSet = (Population)o.refSet.clone(); - this.problem = (AbstractOptimizationProblem)o.problem.clone(); - this.template = (AbstractEAIndividual)o.template.clone(); - this.range = ((InterfaceDataTypeDouble)template).getDoubleRange(); - this.refSetSize = o.refSetSize; - this.poolSize = o.poolSize; - this.intervals = o.intervals; - this.localSearchSteps = o.localSearchSteps; - this.localSearchFitnessFilter = o.localSearchFitnessFilter; - this.probDim = o.probDim; - this.firstTime = o.firstTime; - this.lastImprovementCount = o.lastImprovementCount; - } - - @Override - public Object clone() { - return new ScatterSearch(this); - } - - public void hideHideable() { - setLSShowProps(); - GenericObjectEditor.setHideProperty(this.getClass(), "population", true); - } + public ScatterSearch(ScatterSearch o) { + this.refSet = (Population) o.refSet.clone(); + this.problem = (AbstractOptimizationProblem) o.problem.clone(); + this.template = (AbstractEAIndividual) o.template.clone(); + this.range = ((InterfaceDataTypeDouble) template).getDoubleRange(); + this.refSetSize = o.refSetSize; + this.poolSize = o.poolSize; + this.intervals = o.intervals; + this.localSearchSteps = o.localSearchSteps; + this.localSearchFitnessFilter = o.localSearchFitnessFilter; + this.probDim = o.probDim; + this.firstTime = o.firstTime; + this.lastImprovementCount = o.lastImprovementCount; + } @Override - public void setProblem(InterfaceOptimizationProblem problem) { - this.problem = (AbstractOptimizationProblem)problem; - } + public Object clone() { + return new ScatterSearch(this); + } + + public void hideHideable() { + setLSShowProps(); + GenericObjectEditor.setHideProperty(this.getClass(), "population", true); + } @Override - public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(refSet); - } + public void setProblem(InterfaceOptimizationProblem problem) { + this.problem = (AbstractOptimizationProblem) problem; + } @Override - public Population getPopulation() { - return refSet; - } + public InterfaceSolutionSet getAllSolutions() { + return new SolutionSet(refSet); + } @Override - public void init() { - defaultInit(); - initRefSet(diversify()); - } + public Population getPopulation() { + return refSet; + } @Override - public void initByPopulation(Population pop, boolean reset) { - defaultInit(); - - initRefSet(diversify(pop)); - } - - /** - * Eval an initial population and extract the first refset. - * @param pop - */ - private void initRefSet(Population pop) { - problem.evaluate(pop); - if (TRACE) { - System.out.println("building ref set from pop with avg dist " + pop.getPopulationMeasures()[0]); - } - refSet = getRefSetFitBased(new Population(refSetSize), pop); - refSet.incrFunctionCallsBy(pop.size()); - if (TRACE) { - System.out.println("ref set size " + refSet.size() + " avg dist " + refSet.getPopulationMeasures()[0]); - } - refSet.addPopulationChangedEventListener(this); - refSet.setNotifyEvalInterval(generationCycle); - } + public void init() { + defaultInit(); + initRefSet(diversify()); + } - /** - * Do default initialization. - */ - private void defaultInit() { - firstTime=true; - refSet = null; - combinations = null; - template = problem.getIndividualTemplate(); - if (!(template instanceof InterfaceDataTypeDouble)) { - System.err.println("Requiring double data!"); + @Override + public void initByPopulation(Population pop, boolean reset) { + defaultInit(); + + initRefSet(diversify(pop)); + } + + /** + * Eval an initial population and extract the first refset. + * + * @param pop + */ + private void initRefSet(Population pop) { + problem.evaluate(pop); + if (TRACE) { + System.out.println("building ref set from pop with avg dist " + pop.getPopulationMeasures()[0]); + } + refSet = getRefSetFitBased(new Population(refSetSize), pop); + refSet.incrFunctionCallsBy(pop.size()); + if (TRACE) { + System.out.println("ref set size " + refSet.size() + " avg dist " + refSet.getPopulationMeasures()[0]); + } + refSet.addPopulationChangedEventListener(this); + refSet.setNotifyEvalInterval(generationCycle); + } + + /** + * Do default initialization. + */ + private void defaultInit() { + firstTime = true; + refSet = null; + combinations = null; + template = problem.getIndividualTemplate(); + if (!(template instanceof InterfaceDataTypeDouble)) { + System.err.println("Requiring double data!"); + } else { + Object dim = BeanInspector.callIfAvailable(problem, "getProblemDimension", null); + if (dim == null) { + System.err.println("Couldnt get problem dimension!"); } - else { - Object dim = BeanInspector.callIfAvailable(problem, "getProblemDimension", null); - if (dim==null) { - System.err.println("Couldnt get problem dimension!"); - } - probDim = (Integer)dim; - range = ((InterfaceDataTypeDouble)template).getDoubleRange(); - if (TRACE) { - System.out.println("Range is " + BeanInspector.toString(range)); - } - } - } - - /** Something has changed - */ - protected void firePropertyChangedEvent (String name) { - if (this.m_Listener != null) { - this.m_Listener.registerPopulationStateChanged(this, name); + probDim = (Integer) dim; + range = ((InterfaceDataTypeDouble) template).getDoubleRange(); + if (TRACE) { + System.out.println("Range is " + BeanInspector.toString(range)); } - } + } + } + + /** + * Something has changed + */ + protected void firePropertyChangedEvent(String name) { + if (this.m_Listener != null) { + this.m_Listener.registerPopulationStateChanged(this, name); + } + } // public double eval(double[] x) { // AbstractEAIndividual indy = (AbstractEAIndividual)template.clone(); @@ -188,830 +190,831 @@ public class ScatterSearch implements InterfaceOptimizer, java.io.Serializable, // problem.evaluate(indy); // return indy.getFitness(0); // } - @Override - public void registerPopulationStateChanged(Object source, String name) { - // The events of the interim hill climbing population will be caught here - if (name.compareTo(Population.funCallIntervalReached) == 0) { + public void registerPopulationStateChanged(Object source, String name) { + // The events of the interim hill climbing population will be caught here + if (name.compareTo(Population.funCallIntervalReached) == 0) { // if ((((Population)source).size() % 50) > 0) { // System.out.println("bla"); // } - // set funcalls to real value - refSet.SetFunctionCalls(((Population)source).getFunctionCalls()); - + // set funcalls to real value + refSet.SetFunctionCalls(((Population) source).getFunctionCalls()); + // System.out.println("FunCallIntervalReached at " + (((Population)source).getFunctionCalls())); - - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } - // do not react to NextGenerationPerformed - //else System.err.println("ERROR, event was " + name); - } + + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + } + // do not react to NextGenerationPerformed + //else System.err.println("ERROR, event was " + name); + } @Override - public void optimize() { - // Diversification - // Refset Formation - // L: Combination of refset elements - // if (localSolverCall) then - // if (pass filters) then compute local solvers - // refset update - // if (uncombined elements) then goto L - // if (!stop criterion) then - // refset regeneration - // goto L - if (!firstTime) { - if (lastImprovementCount == 0) { - refSet = regenerateRefSet(); - } - } - firstTime = false; + public void optimize() { + // Diversification + // Refset Formation + // L: Combination of refset elements + // if (localSolverCall) then + // if (pass filters) then compute local solvers + // refset update + // if (uncombined elements) then goto L + // if (!stop criterion) then + // refset regeneration + // goto L + if (!firstTime) { + if (lastImprovementCount == 0) { + refSet = regenerateRefSet(); + } + } + firstTime = false; - problem.evaluatePopulationStart(refSet); - int funCallsStart = refSet.getFunctionCalls(); - do { - if (combinations == null || combinations.size() == 0) { - if (TRACE) { - System.out.println("Improvements: " + lastImprovementCount); - System.out.println("---------- best: " + refSet.getBestEAIndividual().getFitness(0)); - } - combinations = generateCombinations(refSet); - oldRefSet = (Population) refSet.clone(); - lastImprovementCount = 0; - } - if (TRACE) { - System.out.println("No combinations: " + combinations.size()); - } - if (combinations.size()>0) { - updateRefSet(refSet, combinations, oldRefSet); - } - } while (refSet.getFunctionCalls()-funCallsStart < generationCycle); - problem.evaluatePopulationEnd(refSet); - - if (TRACE) { - System.out.println("Improvements: " + lastImprovementCount); - } + problem.evaluatePopulationStart(refSet); + int funCallsStart = refSet.getFunctionCalls(); + do { + if (combinations == null || combinations.size() == 0) { + if (TRACE) { + System.out.println("Improvements: " + lastImprovementCount); + System.out.println("---------- best: " + refSet.getBestEAIndividual().getFitness(0)); + } + combinations = generateCombinations(refSet); + oldRefSet = (Population) refSet.clone(); + lastImprovementCount = 0; + } + if (TRACE) { + System.out.println("No combinations: " + combinations.size()); + } + if (combinations.size() > 0) { + updateRefSet(refSet, combinations, oldRefSet); + } + } while (refSet.getFunctionCalls() - funCallsStart < generationCycle); + problem.evaluatePopulationEnd(refSet); - } + if (TRACE) { + System.out.println("Improvements: " + lastImprovementCount); + } - private boolean isDoLocalSolver(AbstractEAIndividual cand, Population refSet) { + } + + private boolean isDoLocalSolver(AbstractEAIndividual cand, Population refSet) { // if (lastLocalSearch + localSearchInterval < refSet.getGeneration()) { - if (doLocalSearch) { - // filter: only check those within 50% of the worst indy relative to the best. - if (relativeFitCriterion) { - double fitRange = refSet.getWorstFitness()[0] - refSet.getBestFitness()[0]; - return (cand.getFitness(0) < (refSet.getBestFitness()[0]+(fitRange*localSearchFitnessFilter))); - } else { - // absolute fitness criterion - return (cand.getFitness(0) < localSearchFitnessFilter); - } - } else { - return false; + if (doLocalSearch) { + // filter: only check those within 50% of the worst indy relative to the best. + if (relativeFitCriterion) { + double fitRange = refSet.getWorstFitness()[0] - refSet.getBestFitness()[0]; + return (cand.getFitness(0) < (refSet.getBestFitness()[0] + (fitRange * localSearchFitnessFilter))); + } else { + // absolute fitness criterion + return (cand.getFitness(0) < localSearchFitnessFilter); } - } + } else { + return false; + } + } - private Population regenerateRefSet() { - Population diversifiedPop = diversify(); - int keep = refSetSize/2; - Population newRefSet = refSet.cloneWithoutInds(); - if (TRACE) { - System.out.println("regen after " + refSet.getFunctionCalls() + ", best is " + refSet.getBestEAIndividual().getFitness(0)); + private Population regenerateRefSet() { + Population diversifiedPop = diversify(); + int keep = refSetSize / 2; + Population newRefSet = refSet.cloneWithoutInds(); + if (TRACE) { + System.out.println("regen after " + refSet.getFunctionCalls() + ", best is " + refSet.getBestEAIndividual().getFitness(0)); + } + + newRefSet.addAll(refSet.getBestNIndividuals(keep, fitCrit)); + + if (TRACE) { + System.out.println("keeping " + keep + " indies from former ref set, best is " + newRefSet.getBestEAIndividual().getFitness(0)); + } + + int h = newRefSet.size(); + ArrayList distVects = new ArrayList(); + for (int i = 1; i < h; i++) { + distVects.add(getDiffVect(newRefSet.getEAIndividual(0), newRefSet.getEAIndividual(i))); + } + + double maxSP = -1; + int sel = -1; + while (h < refSetSize) { + for (int i = 0; i < diversifiedPop.size(); i++) { + // the difference of cand and best is multiplied by each earlier difference from refSet indies + double[] vP = calcVectP(diversifiedPop.getEAIndividual(i), newRefSet.getEAIndividual(0), distVects); + double maxTmp = getMaxInVect(vP); + if ((i == 0) || (maxTmp < maxSP)) { + maxSP = maxTmp; + sel = i; + } + // selected the one with smallest maxSP! } + AbstractEAIndividual winner = diversifiedPop.getEAIndividual(sel); + // evaluate the new indy + problem.evaluate(winner); + // add it to the newRefSet, increase h + newRefSet.add(winner); + newRefSet.incrFunctionCalls(); + // newRefSet not sorted anymore? + h++; + // update distVects + distVects.add(getDiffVect(newRefSet.getEAIndividual(0), winner)); + // remove from pop. + diversifiedPop.remove(sel); + // redo the loop + } + return newRefSet; + } - newRefSet.addAll(refSet.getBestNIndividuals(keep, fitCrit)); - - if (TRACE) { - System.out.println("keeping " + keep + " indies from former ref set, best is " + newRefSet.getBestEAIndividual().getFitness(0)); + private double getMaxInVect(double[] vals) { + double dmax = vals[0]; + for (int j = 1; j < vals.length; j++) { + if (vals[j] > dmax) { + dmax = vals[j]; } - - int h=newRefSet.size(); - ArrayList distVects = new ArrayList(); - for (int i=1; i distVects) { + // p = (best - candidate)*transposed(M) + double[] diff = getDiffVect(best, candidate); + return multScalarTransposed(diff, distVects); + } - private double getMaxInVect(double[] vals) { - double dmax = vals[0]; - for (int j=1; j dmax) { - dmax = vals[j]; - } - } - return dmax; - } - - private double[] calcVectP(AbstractEAIndividual candidate, AbstractEAIndividual best, ArrayList distVects) { - // p = (best - candidate)*transposed(M) - double[] diff = getDiffVect(best, candidate); - return multScalarTransposed(diff, distVects); - } - - private double[] multScalarTransposed(double[] diff, ArrayList distVects) { - // d[0]*m[0][0], d[1]*m[0][1] etc. - double[] res = new double[distVects.size()]; - for (int i=0; i distVects) { + // d[0]*m[0][0], d[1]*m[0][1] etc. + double[] res = new double[distVects.size()]; + for (int i = 0; i < distVects.size(); i++) { res[i] = Mathematics.vvMult(diff, distVects.get(i)); } - return res; - } + return res; + } - private double[] getDiffVect(AbstractEAIndividual indy1, AbstractEAIndividual indy2) { - double[] v1 = ((InterfaceDataTypeDouble)indy1).getDoubleData(); - double[] v2 = ((InterfaceDataTypeDouble)indy2).getDoubleData(); - return Mathematics.vvSub(v1, v2); - } + private double[] getDiffVect(AbstractEAIndividual indy1, AbstractEAIndividual indy2) { + double[] v1 = ((InterfaceDataTypeDouble) indy1).getDoubleData(); + double[] v2 = ((InterfaceDataTypeDouble) indy2).getDoubleData(); + return Mathematics.vvSub(v1, v2); + } - /** - * Maybe replace the single worst indy in the refset by the best candidate, which may - * be locally optimized in a local search step. - * The best candidate is removed from the candidate set in any case. The candidate set - * may be cleared if all following individuals would never be taken over to the refset. - * - * @param refSet - * @param candidates - * @param oldRefSet only to be used as for phenotypic diversity measure - */ - private void updateRefSet(Population refSet, Population candidates, Population oldRefSet) { - int bestIndex = candidates.getIndexOfBestIndividualPrefFeasible(); - AbstractEAIndividual bestCand = candidates.getEAIndividual(bestIndex); - AbstractEAIndividual worstRef = refSet.getWorstEAIndividual(); + /** + * Maybe replace the single worst indy in the refset by the best candidate, + * which may be locally optimized in a local search step. The best candidate + * is removed from the candidate set in any case. The candidate set may be + * cleared if all following individuals would never be taken over to the + * refset. + * + * @param refSet + * @param candidates + * @param oldRefSet only to be used as for phenotypic diversity measure + */ + private void updateRefSet(Population refSet, Population candidates, Population oldRefSet) { + int bestIndex = candidates.getIndexOfBestIndividualPrefFeasible(); + AbstractEAIndividual bestCand = candidates.getEAIndividual(bestIndex); + AbstractEAIndividual worstRef = refSet.getWorstEAIndividual(); - if (TRACE) { - System.out.println("best cand: " + bestCand.getFitness(0)); - } - - if (isDoLocalSolver(bestCand, refSet)) { - Pair lsRet = localSolver(bestCand, localSearchSteps); - if ((Math.abs(lsRet.tail() - localSearchSteps)/localSearchSteps) > 0.05) { - System.err.println("Warning, more than 5% difference in local search step"); - } - bestCand = lsRet.head(); - refSet.incrFunctionCallsBy(lsRet.tail()); - if (TRACE) { - System.out.println("best cand after: " + bestCand.getFitness(0)); - } - } - - if (bestCand.isDominatingEqual(worstRef)) { - if (TRACE) { - System.out.println("cand is dominating worst ref!"); - } - if (diversityCriterionFulfilled(bestCand, refSet, oldRefSet)) { + if (TRACE) { + System.out.println("best cand: " + bestCand.getFitness(0)); + } + + if (isDoLocalSolver(bestCand, refSet)) { + Pair lsRet = localSolver(bestCand, localSearchSteps); + if ((Math.abs(lsRet.tail() - localSearchSteps) / localSearchSteps) > 0.05) { + System.err.println("Warning, more than 5% difference in local search step"); + } + bestCand = lsRet.head(); + refSet.incrFunctionCallsBy(lsRet.tail()); + if (TRACE) { + System.out.println("best cand after: " + bestCand.getFitness(0)); + } + } + + if (bestCand.isDominatingEqual(worstRef)) { + if (TRACE) { + System.out.println("cand is dominating worst ref!"); + } + if (diversityCriterionFulfilled(bestCand, refSet, oldRefSet)) { // System.out.println("diversity criterion is fulfilled! replacing fit " + worstRef.getFitness(0)); - int replIndex = refSet.indexOf(worstRef); - refSet.set(replIndex, bestCand); - lastImprovementCount++; - } else if (bestCand.isDominating(refSet.getBestEAIndividual())) { - // exception: always accept best solution found so far - int closestIndex = getClosestIndy(bestCand, refSet); + int replIndex = refSet.indexOf(worstRef); + refSet.set(replIndex, bestCand); + lastImprovementCount++; + } else if (bestCand.isDominating(refSet.getBestEAIndividual())) { + // exception: always accept best solution found so far + int closestIndex = getClosestIndy(bestCand, refSet); // if (TRACE) System.out.println("replacing due to best fit"); - refSet.set(closestIndex, bestCand); - lastImprovementCount++; - } + refSet.set(closestIndex, bestCand); + lastImprovementCount++; + } // System.out.println("Improvements: " + lastImprovementCount); - candidates.remove(bestIndex); - } else { - if (TRACE) { - System.out.println("cand is too bad!"); - } - // if the best candidate is worse and no local search is performed, all following will be worse - at least in the uni-criterial case - // so we can just clear the rest of the candidates - if (!doLocalSearch && (bestCand.getFitness().length == 1)) { - candidates.clear(); - } - else { - candidates.remove(bestIndex); - } - } - } + candidates.remove(bestIndex); + } else { + if (TRACE) { + System.out.println("cand is too bad!"); + } + // if the best candidate is worse and no local search is performed, all following will be worse - at least in the uni-criterial case + // so we can just clear the rest of the candidates + if (!doLocalSearch && (bestCand.getFitness().length == 1)) { + candidates.clear(); + } else { + candidates.remove(bestIndex); + } + } + } - private Pair localSolver(AbstractEAIndividual cand, int hcSteps) { - if (localSearchMethod.getSelectedTagID()==0) { - return localSolverHC(cand, hcSteps); - } - else { - return PostProcess.localSolverNMS(cand, hcSteps, nelderMeadInitPerturbation, problem); - } - } - - private Pair localSolverHC(AbstractEAIndividual cand, int hcSteps) { - // use HC for a start... + private Pair localSolver(AbstractEAIndividual cand, int hcSteps) { + if (localSearchMethod.getSelectedTagID() == 0) { + return localSolverHC(cand, hcSteps); + } else { + return PostProcess.localSolverNMS(cand, hcSteps, nelderMeadInitPerturbation, problem); + } + } + + private Pair localSolverHC(AbstractEAIndividual cand, int hcSteps) { + // use HC for a start... // double[] fitBefore = cand.getFitness(); - Population hcPop = new Population(1); - hcPop.add(cand); - int stepsDone = PostProcess.processWithHC(hcPop, problem, hcSteps); + Population hcPop = new Population(1); + hcPop.add(cand); + int stepsDone = PostProcess.processWithHC(hcPop, problem, hcSteps); // if (TRACE) { // System.out.println("local search result: from " + BeanInspector.toString(fitBefore) + " to " + BeanInspector.toString(hcPop.getEAIndividual(0).getFitness())); // } - return new Pair(hcPop.getEAIndividual(0), stepsDone); - } - - private int getClosestIndy(AbstractEAIndividual indy, Population refSet) { - double tmpDst, dist = PhenotypeMetric.dist(indy, refSet.getEAIndividual(0)); - int sel = 0; - for (int i=1; i(hcPop.getEAIndividual(0), stepsDone); + } - /** - * Check for both a genotype and phenotype diversity criterion which both must - * be fulfilled for a candidate to be accepted. - * - * @param cand - * @param popCompGeno - * @param popCompPheno - * @return - */ - private boolean diversityCriterionFulfilled(AbstractEAIndividual cand, Population popCompGeno, Population popComPheno) { - double minDist = PhenotypeMetric.dist(cand, popCompGeno.getEAIndividual(0)); - for (int i=1; i minDiversityEpsilon)); - - if (minDistFulfilled && (improvementEpsilon > 0)) { - boolean minImprovementFulfilled = (cand.getFitness(0) < ((1.-improvementEpsilon) * popComPheno.getBestEAIndividual().getFitness(0))); - return minImprovementFulfilled; - } else { - return minDistFulfilled; + private int getClosestIndy(AbstractEAIndividual indy, Population refSet) { + double tmpDst, dist = PhenotypeMetric.dist(indy, refSet.getEAIndividual(0)); + int sel = 0; + for (int i = 1; i < refSet.size(); i++) { + tmpDst = PhenotypeMetric.dist(indy, refSet.getEAIndividual(i)); + if (tmpDst < dist) { + tmpDst = dist; + sel = i; } - } - - /** - * Recombines the refset to new indies which are also evaluated. - * @param refSet - * @return - */ - private Population generateCombinations(Population refSet) { - // 3 pair types: better-better, better-worse, worse-worse (half of the pop); - Population combs = new Population(); - Population refSorted = refSet.getBestNIndividuals(refSet.size(), fitCrit); - int half = refSet.size()/2; - for (int i=0; i minDiversityEpsilon)); + + if (minDistFulfilled && (improvementEpsilon > 0)) { + boolean minImprovementFulfilled = (cand.getFitness(0) < ((1. - improvementEpsilon) * popComPheno.getBestEAIndividual().getFitness(0))); + return minImprovementFulfilled; + } else { + return minDistFulfilled; + } + } + + /** + * Recombines the refset to new indies which are also evaluated. + * + * @param refSet + * @return + */ + private Population generateCombinations(Population refSet) { + // 3 pair types: better-better, better-worse, worse-worse (half of the pop); + Population combs = new Population(); + Population refSorted = refSet.getBestNIndividuals(refSet.size(), fitCrit); + int half = refSet.size() / 2; + for (int i = 0; i < half - 1; i++) { // better-better + AbstractEAIndividual indy1 = refSorted.getEAIndividual(i); + for (int j = i + 1; j < half; j++) { +// if (TRACE) System.out.println("combi T bb, " + i+ "/" + j); + AbstractEAIndividual indy2 = refSorted.getEAIndividual(j); + combs.add(combineTypeOne(indy1, indy2)); + combs.add(combineTypeTwo(indy1, indy2)); + combs.add(combineTypeTwo(indy1, indy2)); + combs.add(combineTypeThree(indy1, indy2)); } - ((InterfaceDataTypeDouble)resIndy).SetDoubleGenotype(combi); - problem.evaluate(resIndy); - refSet.incrFunctionCalls(); - return resIndy; - } + } + + for (int i = 0; i < half; i++) { // better-worse + AbstractEAIndividual indy1 = refSorted.getEAIndividual(i); + for (int j = half; j < refSet.size(); j++) { +// if (TRACE) System.out.println("combi T bw, " + i+ "/" + j); + AbstractEAIndividual indy2 = refSorted.getEAIndividual(j); + combs.add(combineTypeOne(indy1, indy2)); + combs.add(combineTypeTwo(indy1, indy2)); + combs.add(combineTypeThree(indy1, indy2)); + } + } + + for (int i = half; i < refSet.size() - 1; i++) { // worse-worse + AbstractEAIndividual indy1 = refSorted.getEAIndividual(i); + for (int j = i + 1; j < refSet.size(); j++) { +// if (TRACE) System.out.println("combi T ww, " + i+ "/" + j); + AbstractEAIndividual indy2 = refSorted.getEAIndividual(j); + combs.add(combineTypeTwo(indy1, indy2)); + if (RNG.flipCoin(0.5)) { + combs.add(combineTypeOne(indy1, indy2)); + } else { + combs.add(combineTypeThree(indy1, indy2)); + } + } + } + + if (TRACE) { + System.out.println("created combinations " + combs.size() + " best is " + combs.getBestEAIndividual().getFitness(0)); + } + return combs; + } + + private AbstractEAIndividual combineTypeOne(AbstractEAIndividual indy1, AbstractEAIndividual indy2) { + return combine(indy1, indy2, true, false); + } + + private AbstractEAIndividual combineTypeTwo(AbstractEAIndividual indy1, AbstractEAIndividual indy2) { + return combine(indy1, indy2, true, true); + } + + private AbstractEAIndividual combineTypeThree(AbstractEAIndividual indy1, AbstractEAIndividual indy2) { + return combine(indy1, indy2, false, true); + } + + private AbstractEAIndividual combine(AbstractEAIndividual indy1, AbstractEAIndividual indy2, boolean bFirst, boolean bAdd) { + AbstractEAIndividual resIndy = (AbstractEAIndividual) indy1.clone(); + double[] v1 = ((InterfaceDataTypeDouble) indy1).getDoubleData(); + double[] v2 = ((InterfaceDataTypeDouble) indy2).getDoubleData(); + + double[] dVect = RNG.randomDoubleArray(0, 1, probDim); + for (int i = 0; i < probDim; i++) { + dVect[i] *= (v2[i] - v1[i]) / 2.; + } + double[] candidate = bFirst ? v1 : v2; + double[] combi = bAdd ? Mathematics.vvAdd(candidate, dVect) : Mathematics.vvSub(candidate, dVect); + if (checkRange) { + Mathematics.projectToRange(combi, range); + } + ((InterfaceDataTypeDouble) resIndy).SetDoubleGenotype(combi); + problem.evaluate(resIndy); + refSet.incrFunctionCalls(); + return resIndy; + } @Override - public void setPopulation(Population pop) { - refSet = pop; - } + public void setPopulation(Population pop) { + refSet = pop; + } - private Population getRefSetFitBased(Population curRefSet, Population divPop) { - int h=refSetSize/2; - curRefSet.addAll(divPop.getBestNIndividuals(h, fitCrit)); - Population rest = divPop.getWorstNIndividuals(refSetSize-h, fitCrit); - // contains worst indies - double[][] distances = new double[rest.size()][refSetSize]; + private Population getRefSetFitBased(Population curRefSet, Population divPop) { + int h = refSetSize / 2; + curRefSet.addAll(divPop.getBestNIndividuals(h, fitCrit)); + Population rest = divPop.getWorstNIndividuals(refSetSize - h, fitCrit); + // contains worst indies + double[][] distances = new double[rest.size()][refSetSize]; - for (int i=0; i highestMin) { - highestMin = dtmp; - sel = i; - } - } - return sel; - } - - private Population diversify() { - return diversify(new Population()); - } - - private Population diversify(Population pop) { - int[][] freq = new int[probDim][intervals]; - if (pop.size() > 0) { // count the interval appearances of already given individuals. - for (int k=0; k highestMin) { + highestMin = dtmp; + sel = i; + } + } + return sel; + } + + private Population diversify() { + return diversify(new Population()); + } + + private Population diversify(Population pop) { + int[][] freq = new int[probDim][intervals]; + if (pop.size() > 0) { // count the interval appearances of already given individuals. + for (int k = 0; k < pop.size(); k++) { + double[] params = ((InterfaceDataTypeDouble) pop.getEAIndividual(k)).getDoubleData(); + for (int j = 0; j < probDim; j++) { + for (int iv = 0; iv < intervals; iv++) { + if (isInRangeInterval(params[j], j, iv)) { + freq[j][iv]++; + } + } + } + } + } else { + // or start with diagonals + for (int i = 0; i < intervals; i++) { + pop.add(createDiagIndies(i)); + for (int j = 0; j < probDim; j++) { + freq[j][i] = 1; + } + } + } + + while (pop.size() < poolSize) { + pop.add(createDiverseIndy(freq)); + } + pop.setTargetSize(poolSize); + if (TRACE) { + System.out.println("created diverse pop size " + pop.size()); + } + return pop; + } + + private AbstractEAIndividual createDiverseIndy(int freq[][]) { + AbstractEAIndividual indy = (AbstractEAIndividual) template.clone(); + InterfaceDataTypeDouble dblIndy = (InterfaceDataTypeDouble) indy; + double[] genes = dblIndy.getDoubleData(); + + for (int i = 0; i < probDim; i++) { + int interv = selectInterv(i, freq); + genes[i] = randInRangeInterval(i, interv); + freq[i][interv]++; + } + + dblIndy.SetDoubleGenotype(genes); + return indy; + } + + private double getFreqDepProb(int dim, int interv, int freq[][]) { + double sum = 0; + for (int k = 0; k < intervals; k++) { + sum += (double) freq[dim][k]; + } + return freq[dim][interv] / sum; + } + + private int selectInterv(int dim, int freq[][]) { + double[] probs = new double[intervals]; + for (int i = 0; i < intervals; i++) { probs[i] = getFreqDepProb(dim, i, freq); } - double rnd = RNG.randomDouble(); - int sel = 0; - double sum = probs[0]; - while (sum < rnd) { - sel++; - sum+=probs[sel]; - } - if (sum >= 1.0000001) { - System.err.println("Check this: sum>=1 in selectInterv"); - } - return sel; - } + double rnd = RNG.randomDouble(); + int sel = 0; + double sum = probs[0]; + while (sum < rnd) { + sel++; + sum += probs[sel]; + } + if (sum >= 1.0000001) { + System.err.println("Check this: sum>=1 in selectInterv"); + } + return sel; + } - /** - * Create probDim individuals where each dimension is initialized within - * subinterval i for individual i. - * - * @param interval - * @return - */ - private AbstractEAIndividual createDiagIndies(int interval) { - AbstractEAIndividual indy = (AbstractEAIndividual)template.clone(); - InterfaceDataTypeDouble dblIndy = (InterfaceDataTypeDouble)indy; - double[] genes = dblIndy.getDoubleData(); - for (int i=0; i 0) { - ss.setDoLocalSearch(true); - ss.setLocalSearchSteps(localSearchSteps); - ss.setLocalSearchFitnessFilter(localSearchFitnessFilter); - } else { - ss.setDoLocalSearch(false); - } - Population pop = new Population(); - pop.setTargetSize(refSetSize); - pop.init(); - problem.initPopulation(pop); - ss.initByPopulation(pop, true); + public static final GOParameters standardSS( + AbstractOptimizationProblem problem) { + return specialSS(0, 0, 0.1, true, 10, problem, new EvaluationTerminator(10000)); + } - return OptimizerFactory.makeParams(ss, pop, problem, 0, term); - } + public static final GOParameters specialSS( + int localSearchSteps, double localSearchFitnessFilter, + double nmInitPerturb, boolean relativeFitCrit, + int refSetSize, + AbstractOptimizationProblem problem, InterfaceTerminator term) { + ScatterSearch ss = new ScatterSearch(); + problem.initProblem(); + ss.setProblem(problem); + ss.setRefSetSize(refSetSize); + ss.setNelderMeadInitPerturbation(nmInitPerturb); + ss.setLocalSearchRelativeFilter(relativeFitCrit); + if (localSearchSteps > 0) { + ss.setDoLocalSearch(true); + ss.setLocalSearchSteps(localSearchSteps); + ss.setLocalSearchFitnessFilter(localSearchFitnessFilter); + } else { + ss.setDoLocalSearch(false); + } + Population pop = new Population(); + pop.setTargetSize(refSetSize); + pop.init(); + problem.initPopulation(pop); + ss.initByPopulation(pop, true); - /** - * @return the relativeFitCriterion - */ - public boolean isLocalSearchRelativeFilter() { - return relativeFitCriterion; - } + return OptimizerFactory.makeParams(ss, pop, problem, 0, term); + } - /** - * @param relativeFitCriterion the relativeFitCriterion to set - */ - public void setLocalSearchRelativeFilter(boolean relativeFitCriterion) { - this.relativeFitCriterion = relativeFitCriterion; - } + /** + * @return the relativeFitCriterion + */ + public boolean isLocalSearchRelativeFilter() { + return relativeFitCriterion; + } - public String localSearchRelativeFilterTipText() { - return "If selected, local search will be triggered by relative fitness, else by absolute"; - } - - /** - * @return the nelderMeadInitPerturbation - */ - public double getNelderMeadInitPerturbation() { - return nelderMeadInitPerturbation; - } + /** + * @param relativeFitCriterion the relativeFitCriterion to set + */ + public void setLocalSearchRelativeFilter(boolean relativeFitCriterion) { + this.relativeFitCriterion = relativeFitCriterion; + } - /** - * @param nelderMeadInitPerturbation the nelderMeadInitPerturbation to set - */ - public void setNelderMeadInitPerturbation(double nelderMeadInitPerturbation) { - this.nelderMeadInitPerturbation = nelderMeadInitPerturbation; - } - - public String nelderMeadInitPerturbationTipText() { - return "The relative range of the initial perturbation for creating the initial Nelder-Mead-Simplex"; - } + public String localSearchRelativeFilterTipText() { + return "If selected, local search will be triggered by relative fitness, else by absolute"; + } - /** - * @return the localSearchMethod - */ - public SelectedTag getLocalSearchMethod() { - return localSearchMethod; - } + /** + * @return the nelderMeadInitPerturbation + */ + public double getNelderMeadInitPerturbation() { + return nelderMeadInitPerturbation; + } - /** - * @param localSearchMethod the localSearchMethod to set - */ - public void setLocalSearchMethod(SelectedTag localSearchMethod) { - this.localSearchMethod = localSearchMethod; - setLSShowProps(); - } + /** + * @param nelderMeadInitPerturbation the nelderMeadInitPerturbation to set + */ + public void setNelderMeadInitPerturbation(double nelderMeadInitPerturbation) { + this.nelderMeadInitPerturbation = nelderMeadInitPerturbation; + } - public String localSearchMethodTipText() { - return "The local search method to use"; - } - - /** - * @return the poolSize - */ - public int getPoolSize() { - return poolSize; - } + public String nelderMeadInitPerturbationTipText() { + return "The relative range of the initial perturbation for creating the initial Nelder-Mead-Simplex"; + } - /** - * @param poolSize the poolSize to set - */ - public void setPoolSize(int poolSize) { - this.poolSize = poolSize; - } - - public String poolSizeTipText() { - return "The number of individuals created in the diversification step"; - } + /** + * @return the localSearchMethod + */ + public SelectedTag getLocalSearchMethod() { + return localSearchMethod; + } - public double getImprovementEpsilon() { - return improvementEpsilon; - } - public void setImprovementEpsilon(double improvementEpsilon) { - this.improvementEpsilon = improvementEpsilon; - } - public String improvementEpsilonTipText() { - return "Minimal relative fitness improvement for a candidate to enter the refSet - set to zero to deactivate."; - } + /** + * @param localSearchMethod the localSearchMethod to set + */ + public void setLocalSearchMethod(SelectedTag localSearchMethod) { + this.localSearchMethod = localSearchMethod; + setLSShowProps(); + } - public double getMinDiversityEpsilon() { - return minDiversityEpsilon; - } - public void setMinDiversityEpsilon(double minDiversityEpsilon) { - this.minDiversityEpsilon = minDiversityEpsilon; - } - public String minDiversityEpsilonTipText() { - return "Minimal distance to other individuals in the refSet for a candidate to enter the refSet - set to zero to deactivate."; - } + public String localSearchMethodTipText() { + return "The local search method to use"; + } + + /** + * @return the poolSize + */ + public int getPoolSize() { + return poolSize; + } + + /** + * @param poolSize the poolSize to set + */ + public void setPoolSize(int poolSize) { + this.poolSize = poolSize; + } + + public String poolSizeTipText() { + return "The number of individuals created in the diversification step"; + } + + public double getImprovementEpsilon() { + return improvementEpsilon; + } + + public void setImprovementEpsilon(double improvementEpsilon) { + this.improvementEpsilon = improvementEpsilon; + } + + public String improvementEpsilonTipText() { + return "Minimal relative fitness improvement for a candidate to enter the refSet - set to zero to deactivate."; + } + + public double getMinDiversityEpsilon() { + return minDiversityEpsilon; + } + + public void setMinDiversityEpsilon(double minDiversityEpsilon) { + this.minDiversityEpsilon = minDiversityEpsilon; + } + + public String minDiversityEpsilonTipText() { + return "Minimal distance to other individuals in the refSet for a candidate to enter the refSet - set to zero to deactivate."; + } } diff --git a/src/eva2/server/go/strategies/SimulatedAnnealing.java b/src/eva2/server/go/strategies/SimulatedAnnealing.java index 26e7655a..aa86ea72 100644 --- a/src/eva2/server/go/strategies/SimulatedAnnealing.java +++ b/src/eva2/server/go/strategies/SimulatedAnnealing.java @@ -10,42 +10,40 @@ import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; import eva2.tools.math.RNG; -/** Simulated Annealing by Nelder and Mead, a simple yet efficient local search +/** + * Simulated Annealing by Nelder and Mead, a simple yet efficient local search * method. But to become less prone to premature convergence the cooling rate - * has to be tuned to the optimization problem at hand. Again the population size - * gives the number of multi-starts. - * Created by IntelliJ IDEA. - * User: streiche - * Date: 13.05.2004 - * Time: 10:30:26 - * To change this template use File | Settings | File Templates. + * has to be tuned to the optimization problem at hand. Again the population + * size gives the number of multi-starts. Created by IntelliJ IDEA. User: + * streiche Date: 13.05.2004 Time: 10:30:26 To change this template use File | + * Settings | File Templates. */ public class SimulatedAnnealing implements InterfaceOptimizer, java.io.Serializable { // These variables are necessary for the simple testcase - private InterfaceOptimizationProblem m_Problem = new B1Problem(); - private int m_MultiRuns = 100; - private int m_FitnessCalls = 100; - private int m_FitnessCallsNeeded = 0; - GAIndividualBinaryData m_Best, m_Test; - public double m_InitialTemperature = 2, m_CurrentTemperature; - public double m_Alpha = 0.9; + private InterfaceOptimizationProblem m_Problem = new B1Problem(); + private int m_MultiRuns = 100; + private int m_FitnessCalls = 100; + private int m_FitnessCallsNeeded = 0; + GAIndividualBinaryData m_Best, m_Test; + public double m_InitialTemperature = 2, m_CurrentTemperature; + public double m_Alpha = 0.9; // These variables are necessary for the more complex LectureGUI enviroment - transient private String m_Identifier = ""; + transient private String m_Identifier = ""; transient private InterfacePopulationChangedEventListener m_Listener; - private Population m_Population; + private Population m_Population; public SimulatedAnnealing() { this.m_Population = new Population(); this.m_Population.setTargetSize(10); } - + public SimulatedAnnealing(SimulatedAnnealing a) { - this.m_Population = (Population)a.m_Population.clone(); - this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone(); - this.m_InitialTemperature = a.m_InitialTemperature; - this.m_CurrentTemperature = a.m_CurrentTemperature; - this.m_Alpha = a.m_Alpha; + this.m_Population = (Population) a.m_Population.clone(); + this.m_Problem = (InterfaceOptimizationProblem) a.m_Problem.clone(); + this.m_InitialTemperature = a.m_InitialTemperature; + this.m_CurrentTemperature = a.m_CurrentTemperature; + this.m_Alpha = a.m_Alpha; } @Override @@ -53,7 +51,8 @@ public class SimulatedAnnealing implements InterfaceOptimizer, java.io.Serializa return (Object) new SimulatedAnnealing(this); } - /** This method will init the HillClimber + /** + * This method will init the HillClimber */ @Override public void init() { @@ -63,28 +62,31 @@ public class SimulatedAnnealing implements InterfaceOptimizer, java.io.Serializa this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** This method will init the optimizer with a given population - * @param pop The initial population - * @param reset If true the population is reset. + /** + * This method will init the optimizer with a given population + * + * @param pop The initial population + * @param reset If true the population is reset. */ @Override public void initByPopulation(Population pop, boolean reset) { - this.m_Population = (Population)pop.clone(); + this.m_Population = (Population) pop.clone(); this.m_CurrentTemperature = this.m_InitialTemperature; if (reset) { - this.m_Population.init(); + this.m_Population.init(); this.m_Problem.evaluate(this.m_Population); this.firePropertyChangedEvent(Population.nextGenerationPerformed); } } - /** This method will optimize + /** + * This method will optimize */ @Override public void optimize() { - AbstractEAIndividual indy; - Population original = (Population)this.m_Population.clone(); - double delta; + AbstractEAIndividual indy; + Population original = (Population) this.m_Population.clone(); + double delta; for (int i = 0; i < this.m_Population.size(); i++) { indy = ((AbstractEAIndividual) this.m_Population.get(i)); @@ -95,13 +97,13 @@ public class SimulatedAnnealing implements InterfaceOptimizer, java.io.Serializa } this.m_Problem.evaluate(this.m_Population); for (int i = 0; i < this.m_Population.size(); i++) { - if (((AbstractEAIndividual)original.get(i)).isDominatingDebConstraints(((AbstractEAIndividual)this.m_Population.get(i)))) { + if (((AbstractEAIndividual) original.get(i)).isDominatingDebConstraints(((AbstractEAIndividual) this.m_Population.get(i)))) { this.m_Population.remove(i); this.m_Population.add(i, original.get(i)); } else { - delta = this.calculateDelta(((AbstractEAIndividual)original.get(i)), ((AbstractEAIndividual)this.m_Population.get(i))); + delta = this.calculateDelta(((AbstractEAIndividual) original.get(i)), ((AbstractEAIndividual) this.m_Population.get(i))); //System.out.println("delta: " + delta); - if (Math.exp(-delta/this.m_CurrentTemperature) > RNG.randomInt(0,1)) { + if (Math.exp(-delta / this.m_CurrentTemperature) > RNG.randomInt(0, 1)) { this.m_Population.remove(i); this.m_Population.add(i, original.get(i)); } @@ -112,13 +114,15 @@ public class SimulatedAnnealing implements InterfaceOptimizer, java.io.Serializa this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** This method calculates the difference between the fitness values - * @param org The original - * @param mut The mutant + /** + * This method calculates the difference between the fitness values + * + * @param org The original + * @param mut The mutant */ private double calculateDelta(AbstractEAIndividual org, AbstractEAIndividual mut) { - double result = 0; - double[] fitOrg, fitMut; + double result = 0; + double[] fitOrg, fitMut; fitOrg = org.getFitness(); fitMut = mut.getFitness(); for (int i = 0; i < fitOrg.length; i++) { @@ -127,19 +131,23 @@ public class SimulatedAnnealing implements InterfaceOptimizer, java.io.Serializa return result; } - /** This method will set the problem that is to be optimized + /** + * This method will set the problem that is to be optimized + * * @param problem */ @Override - public void setProblem (InterfaceOptimizationProblem problem) { + public void setProblem(InterfaceOptimizationProblem problem) { this.m_Problem = problem; } + @Override - public InterfaceOptimizationProblem getProblem () { + public InterfaceOptimizationProblem getProblem() { return this.m_Problem; } - /** This method will init the HillClimber + /** + * This method will init the HillClimber */ public void defaultInit() { this.m_FitnessCallsNeeded = 0; @@ -147,24 +155,26 @@ public class SimulatedAnnealing implements InterfaceOptimizer, java.io.Serializa this.m_Best.defaultInit(m_Problem); } - /** This method will optimize + /** + * This method will optimize */ public void defaultOptimize() { for (int i = 0; i < m_FitnessCalls; i++) { - this.m_Test = (GAIndividualBinaryData)((this.m_Best).clone()); + this.m_Test = (GAIndividualBinaryData) ((this.m_Best).clone()); this.m_Test.defaultMutate(); if (this.m_Test.defaultEvaulateAsMiniBits() < this.m_Best.defaultEvaulateAsMiniBits()) { this.m_Best = this.m_Test; } this.m_FitnessCallsNeeded = i; if (this.m_Best.defaultEvaulateAsMiniBits() == 0) { - i = this.m_FitnessCalls +1; + i = this.m_FitnessCalls + 1; } } } - /** This main method will start a simple hillclimber. - * No arguments necessary. + /** + * This main method will start a simple hillclimber. No arguments necessary. + * * @param args */ public static void main(String[] args) { @@ -178,31 +188,35 @@ public class SimulatedAnnealing implements InterfaceOptimizer, java.io.Serializa } TmpMeanCalls /= program.m_MultiRuns; TmpMeanFitness /= program.m_MultiRuns; - System.out.println("("+program.m_MultiRuns+"/"+program.m_FitnessCalls+") Mean Fitness : " + TmpMeanFitness + " Mean Calls needed: " + TmpMeanCalls); + System.out.println("(" + program.m_MultiRuns + "/" + program.m_FitnessCalls + ") Mean Fitness : " + TmpMeanFitness + " Mean Calls needed: " + TmpMeanCalls); } @Override public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { this.m_Listener = ea; } + @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - protected void firePropertyChangedEvent (String name) { + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } + + protected void firePropertyChangedEvent(String name) { if (this.m_Listener != null) { this.m_Listener.registerPopulationStateChanged(this, name); } } - /** This method will return a string describing all properties of the optimizer - * and the applied methods. + /** + * This method will return a string describing all properties of the + * optimizer and the applied methods. + * * @return A descriptive string */ @Override @@ -210,96 +224,112 @@ public class SimulatedAnnealing implements InterfaceOptimizer, java.io.Serializa String result = ""; if (this.m_Population.size() > 1) { result += "Multi(" + this.m_Population.size() + ")-Start Hill Climbing:\n"; - } - else { + } else { result += "Simulated Annealing:\n"; } result += "Optimization Problem: "; - result += this.m_Problem.getStringRepresentationForProblem(this) +"\n"; + result += this.m_Problem.getStringRepresentationForProblem(this) + "\n"; result += this.m_Population.getStringRepresentation(); return result; } - /** This method allows you to set an identifier for the algorithm - * @param name The indenifier + + /** + * This method allows you to set an identifier for the algorithm + * + * @param name The indenifier */ @Override - public void setIdentifier(String name) { + public void setIdentifier(String name) { this.m_Identifier = name; } - @Override - public String getIdentifier() { - return this.m_Identifier; - } - /** This method is required to free the memory on a RMIServer, - * but there is nothing to implement. + @Override + public String getIdentifier() { + return this.m_Identifier; + } + + /** + * ******************************************************************************************************************** + * These are for GUI */ - @Override - public void freeWilly() { - - } -/********************************************************************************************************************** - * These are for GUI - */ - /** This method returns a global info string + /** + * This method returns a global info string + * * @return description */ public static String globalInfo() { return "The simulated annealing uses an additional cooling rate instead of a simple dominate criteria to accpect worse solutions by chance."; } - /** This method will return a naming String + + /** + * This method will return a naming String + * * @return The name of the algorithm */ @Override public String getName() { return "MS-SA"; } - /** Assuming that all optimizer will store thier data in a population - * we will allow acess to this population to query to current state - * of the optimizer. + + /** + * Assuming that all optimizer will store thier data in a population we will + * allow acess to this population to query to current state of the + * optimizer. + * * @return The population of current solutions to a given problem. */ @Override public Population getPopulation() { return this.m_Population; } + @Override - public void setPopulation(Population pop){ + public void setPopulation(Population pop) { this.m_Population = pop; } + public String populationTipText() { return "Change the number of best individuals stored (MS-SA))."; } - + @Override public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(getPopulation()); + return new SolutionSet(getPopulation()); } - /** Set the initial temperature + + /** + * Set the initial temperature + * * @return The initial temperature. */ public double getInitialTemperature() { return this.m_InitialTemperature; } - public void setInitialTemperature(double pop){ + + public void setInitialTemperature(double pop) { this.m_InitialTemperature = pop; } + public String initialTemperatureTipText() { return "Set the initial temperature."; } - /** Set alpha, which is used to degrade the temperaure + /** + * Set alpha, which is used to degrade the temperaure + * * @return The cooling rate. */ public double getAlpha() { return this.m_Alpha; } - public void setAlpha(double a){ + + public void setAlpha(double a) { this.m_Alpha = a; if (this.m_Alpha > 1) { this.m_Alpha = 1.0; } } + public String alphaTipText() { return "Set alpha, which is used to degrade the temperaure."; } diff --git a/src/eva2/server/go/strategies/SteadyStateGA.java b/src/eva2/server/go/strategies/SteadyStateGA.java index 5c9ce89b..b3831734 100644 --- a/src/eva2/server/go/strategies/SteadyStateGA.java +++ b/src/eva2/server/go/strategies/SteadyStateGA.java @@ -13,186 +13,200 @@ import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; -/** A simple implementation of the steady-state GA with variable - * replacement schemes. To reduce the logging effort population.size() - * optimization steps are performed each time optimize() is called. - * Created by IntelliJ IDEA. - * User: streiche - * Date: 19.07.2005 - * Time: 14:30:20 - * To change this template use File | Settings | File Templates. +/** + * A simple implementation of the steady-state GA with variable replacement + * schemes. To reduce the logging effort population.size() optimization steps + * are performed each time optimize() is called. Created by IntelliJ IDEA. User: + * streiche Date: 19.07.2005 Time: 14:30:20 To change this template use File | + * Settings | File Templates. */ public class SteadyStateGA implements InterfaceOptimizer, java.io.Serializable { - private Population m_Population = new Population(); - private InterfaceOptimizationProblem m_Problem = new B1Problem(); - private InterfaceSelection m_ParentSelection = new SelectTournament(); - private InterfaceSelection m_PartnerSelection = new SelectTournament(); - private InterfaceReplacement m_ReplacementSelection = new ReplaceWorst(); - private int m_NumberOfPartners = 1; + private Population m_Population = new Population(); + private InterfaceOptimizationProblem m_Problem = new B1Problem(); + private InterfaceSelection m_ParentSelection = new SelectTournament(); + private InterfaceSelection m_PartnerSelection = new SelectTournament(); + private InterfaceReplacement m_ReplacementSelection = new ReplaceWorst(); + private int m_NumberOfPartners = 1; + private String m_Identifier = ""; + transient private InterfacePopulationChangedEventListener m_Listener; - private String m_Identifier = ""; - transient private InterfacePopulationChangedEventListener m_Listener; + public SteadyStateGA() { + } - public SteadyStateGA() { - } - - public SteadyStateGA(SteadyStateGA a) { - this.m_Population = (Population)a.m_Population.clone(); - this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone(); - this.m_Identifier = a.m_Identifier; - this.m_NumberOfPartners = a.m_NumberOfPartners; - this.m_ParentSelection = (InterfaceSelection)a.m_ParentSelection.clone(); - this.m_PartnerSelection = (InterfaceSelection)a.m_PartnerSelection.clone(); - this.m_ReplacementSelection = (InterfaceReplacement)a.m_ReplacementSelection.clone(); - } + public SteadyStateGA(SteadyStateGA a) { + this.m_Population = (Population) a.m_Population.clone(); + this.m_Problem = (InterfaceOptimizationProblem) a.m_Problem.clone(); + this.m_Identifier = a.m_Identifier; + this.m_NumberOfPartners = a.m_NumberOfPartners; + this.m_ParentSelection = (InterfaceSelection) a.m_ParentSelection.clone(); + this.m_PartnerSelection = (InterfaceSelection) a.m_PartnerSelection.clone(); + this.m_ReplacementSelection = (InterfaceReplacement) a.m_ReplacementSelection.clone(); + } @Override - public Object clone() { - return (Object) new SteadyStateGA(this); - } + public Object clone() { + return (Object) new SteadyStateGA(this); + } @Override - public void init() { - this.m_Problem.initPopulation(this.m_Population); + public void init() { + this.m_Problem.initPopulation(this.m_Population); + this.evaluatePopulation(this.m_Population); + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + } + + /** + * This method will init the optimizer with a given population + * + * @param reset If true the population is reset. + */ + @Override + public void initByPopulation(Population pop, boolean reset) { + this.m_Population = (Population) pop.clone(); + if (reset) { + this.m_Population.init(); this.evaluatePopulation(this.m_Population); this.firePropertyChangedEvent(Population.nextGenerationPerformed); } + } - /** This method will init the optimizer with a given population - * @param reset If true the population is reset. - */ - @Override - public void initByPopulation(Population pop, boolean reset) { - this.m_Population = (Population)pop.clone(); - if (reset) { - this.m_Population.init(); - this.evaluatePopulation(this.m_Population); - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } - } + /** + * This method will evaluate the current population using the given problem. + * + * @param population The population that is to be evaluated + */ + private void evaluatePopulation(Population population) { + this.m_Problem.evaluate(population); + population.incrGeneration(); + } - /** This method will evaluate the current population using the - * given problem. - * @param population The population that is to be evaluated - */ - private void evaluatePopulation(Population population) { - this.m_Problem.evaluate(population); - population.incrGeneration(); + /** + * This method will assign fitness values to all individual in the current + * population. + * + * @param population The population that is to be evaluated + */ + private void defaultEvaluatePopulation(Population population) { + GAIndividualBinaryData tmpIndy; + for (int i = 0; i < population.size(); i++) { + tmpIndy = (GAIndividualBinaryData) population.get(i); + tmpIndy.SetFitness(0, tmpIndy.defaultEvaulateAsMiniBits()); + population.incrFunctionCalls(); } + population.incrGeneration(); + } - /** This method will assign fitness values to all individual in the - * current population. - * @param population The population that is to be evaluated - */ - private void defaultEvaluatePopulation(Population population) { - GAIndividualBinaryData tmpIndy; - for (int i = 0; i < population.size(); i++) { - tmpIndy = (GAIndividualBinaryData) population.get(i); - tmpIndy.SetFitness(0, tmpIndy.defaultEvaulateAsMiniBits()); - population.incrFunctionCalls(); - } - population.incrGeneration(); - } - - /** This method will generate the offspring population from the - * given population of evaluated individuals. - */ - private void generateChildren() { - this.m_ParentSelection.prepareSelection(this.m_Population); - this.m_PartnerSelection.prepareSelection(this.m_Population); - Population parents = this.m_ParentSelection.selectFrom(this.m_Population, 1); - AbstractEAIndividual mother = (AbstractEAIndividual)parents.get(0); - parents = this.m_PartnerSelection.findPartnerFor(mother, this.m_Population, this.m_NumberOfPartners); - AbstractEAIndividual[] offSprings = mother.mateWith(parents); - offSprings[0].mutate(); - this.m_Problem.evaluate(offSprings[0]); - this.m_ReplacementSelection.insertIndividual(offSprings[0], this.m_Population, parents); - } + /** + * This method will generate the offspring population from the given + * population of evaluated individuals. + */ + private void generateChildren() { + this.m_ParentSelection.prepareSelection(this.m_Population); + this.m_PartnerSelection.prepareSelection(this.m_Population); + Population parents = this.m_ParentSelection.selectFrom(this.m_Population, 1); + AbstractEAIndividual mother = (AbstractEAIndividual) parents.get(0); + parents = this.m_PartnerSelection.findPartnerFor(mother, this.m_Population, this.m_NumberOfPartners); + AbstractEAIndividual[] offSprings = mother.mateWith(parents); + offSprings[0].mutate(); + this.m_Problem.evaluate(offSprings[0]); + this.m_ReplacementSelection.insertIndividual(offSprings[0], this.m_Population, parents); + } @Override - public void optimize() { - for (int i = 0; i < this.m_Population.size(); i++) { - this.generateChildren(); - } - this.m_Population.incrFunctionCallsBy(this.m_Population.size()); - this.m_Population.incrGeneration(); - this.firePropertyChangedEvent(Population.nextGenerationPerformed); - } - @Override - public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { - this.m_Listener = ea; - } - @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - protected void firePropertyChangedEvent (String name) { - if (this.m_Listener != null) { - this.m_Listener.registerPopulationStateChanged(this, name); - } + public void optimize() { + for (int i = 0; i < this.m_Population.size(); i++) { + this.generateChildren(); } + this.m_Population.incrFunctionCallsBy(this.m_Population.size()); + this.m_Population.incrGeneration(); + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + } - /** This method will set the problem that is to be optimized - * @param problem - */ @Override - public void setProblem (InterfaceOptimizationProblem problem) { - this.m_Problem = problem; - } - @Override - public InterfaceOptimizationProblem getProblem () { - return this.m_Problem; - } + public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { + this.m_Listener = ea; + } - /** This method will return a string describing all properties of the optimizer - * and the applied methods. - * @return A descriptive string - */ @Override - public String getStringRepresentation() { - String result = ""; - result += "Genetic Algorithm:\n"; - result += "Optimization Problem: "; - result += this.m_Problem.getStringRepresentationForProblem(this) +"\n"; - result += this.m_Population.getStringRepresentation(); - return result; + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; } - /** This method allows you to set an identifier for the algorithm - * @param name The indenifier - */ - @Override - public void setIdentifier(String name) { - this.m_Identifier = name; - } - @Override - public String getIdentifier() { - return this.m_Identifier; - } - - /** This method is required to free the memory on a RMIServer, - * but there is nothing to implement. - */ - @Override - public void freeWilly() { + } + protected void firePropertyChangedEvent(String name) { + if (this.m_Listener != null) { + this.m_Listener.registerPopulationStateChanged(this, name); } - /********************************************************************************************************************** + } + + /** + * This method will set the problem that is to be optimized + * + * @param problem + */ + @Override + public void setProblem(InterfaceOptimizationProblem problem) { + this.m_Problem = problem; + } + + @Override + public InterfaceOptimizationProblem getProblem() { + return this.m_Problem; + } + + /** + * This method will return a string describing all properties of the + * optimizer and the applied methods. + * + * @return A descriptive string + */ + @Override + public String getStringRepresentation() { + String result = ""; + result += "Genetic Algorithm:\n"; + result += "Optimization Problem: "; + result += this.m_Problem.getStringRepresentationForProblem(this) + "\n"; + result += this.m_Population.getStringRepresentation(); + return result; + } + + /** + * This method allows you to set an identifier for the algorithm + * + * @param name The indenifier + */ + @Override + public void setIdentifier(String name) { + this.m_Identifier = name; + } + + @Override + public String getIdentifier() { + return this.m_Identifier; + } + + /** + * ******************************************************************************************************************** * These are for GUI */ - /** This method returns a global info string + /** + * This method returns a global info string + * * @return description */ public static String globalInfo() { return "This is a Steady-State Genetic Algorithm."; } - /** This method will return a naming String + + /** + * This method will return a naming String + * * @return The name of the algorithm */ @Override @@ -200,42 +214,53 @@ public class SteadyStateGA implements InterfaceOptimizer, java.io.Serializable { return "SS-GA"; } - /** Assuming that all optimizer will store thier data in a population - * we will allow acess to this population to query to current state - * of the optimizer. + /** + * Assuming that all optimizer will store thier data in a population we will + * allow acess to this population to query to current state of the + * optimizer. + * * @return The population of current solutions to a given problem. */ @Override public Population getPopulation() { return this.m_Population; } + @Override - public void setPopulation(Population pop){ + public void setPopulation(Population pop) { this.m_Population = pop; } + public String populationTipText() { return "Edit the properties of the population used."; } - + @Override public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(getPopulation()); + return new SolutionSet(getPopulation()); } - /** This method will set the parent selection method that is to be used + + /** + * This method will set the parent selection method that is to be used + * * @param selection */ public void setParentSelection(InterfaceSelection selection) { this.m_ParentSelection = selection; } + public InterfaceSelection getParentSelection() { return this.m_ParentSelection; } + public String parentSelectionTipText() { return "Choose a parent selection method."; } - /** This method will set the number of partners that are needed to create + /** + * This method will set the number of partners that are needed to create * offsprings by mating + * * @param partners */ public void setNumberOfPartners(int partners) { @@ -244,35 +269,46 @@ public class SteadyStateGA implements InterfaceOptimizer, java.io.Serializable { } this.m_NumberOfPartners = partners; } + public int getNumberOfPartners() { return this.m_NumberOfPartners; } + public String numberOfPartnersTipText() { return "The number of mating partners needed to create offsprings."; } - /** Choose a selection method for selecting recombination partners for given parents - * @param selection - */ + /** + * Choose a selection method for selecting recombination partners for given + * parents + * + * @param selection + */ public void setPartnerSelection(InterfaceSelection selection) { this.m_PartnerSelection = selection; } + public InterfaceSelection getPartnerSelection() { return this.m_PartnerSelection; } + public String partnerSelectionTipText() { return "Choose a selection method for selecting recombination partners for given parents."; } - /** Choose a replacement strategy + /** + * Choose a replacement strategy + * * @param selection */ public void setReplacementSelection(InterfaceReplacement selection) { this.m_ReplacementSelection = selection; } + public InterfaceReplacement getReplacementSelection() { return this.m_ReplacementSelection; } + public String replacementSelectionTipText() { return "Choose a replacement strategy."; } diff --git a/src/eva2/server/go/strategies/ThresholdAlgorithm.java b/src/eva2/server/go/strategies/ThresholdAlgorithm.java index 9cc5a855..44cabbbb 100644 --- a/src/eva2/server/go/strategies/ThresholdAlgorithm.java +++ b/src/eva2/server/go/strategies/ThresholdAlgorithm.java @@ -9,28 +9,25 @@ import eva2.server.go.populations.SolutionSet; import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; -/** Threshold accepting algorithm simliar strategy as the flood - * algorithm, similar problems. - * Created by IntelliJ IDEA. - * User: streiche - * Date: 01.10.2004 - * Time: 13:35:49 - * To change this template use File | Settings | File Templates. +/** + * Threshold accepting algorithm simliar strategy as the flood algorithm, + * similar problems. Created by IntelliJ IDEA. User: streiche Date: 01.10.2004 + * Time: 13:35:49 To change this template use File | Settings | File Templates. */ public class ThresholdAlgorithm implements InterfaceOptimizer, java.io.Serializable { // These variables are necessary for the simple testcase - private InterfaceOptimizationProblem m_Problem = new B1Problem(); - private int m_MultiRuns = 100; - private int m_FitnessCalls = 100; - private int m_FitnessCallsNeeded = 0; - GAIndividualBinaryData m_Best, m_Test; - public double m_InitialT = 2, m_CurrentT; - public double m_Alpha = 0.9; + private InterfaceOptimizationProblem m_Problem = new B1Problem(); + private int m_MultiRuns = 100; + private int m_FitnessCalls = 100; + private int m_FitnessCallsNeeded = 0; + GAIndividualBinaryData m_Best, m_Test; + public double m_InitialT = 2, m_CurrentT; + public double m_Alpha = 0.9; // These variables are necessary for the more complex LectureGUI enviroment - transient private String m_Identifier = ""; + transient private String m_Identifier = ""; transient private InterfacePopulationChangedEventListener m_Listener; - private Population m_Population; + private Population m_Population; public ThresholdAlgorithm() { this.m_Population = new Population(); @@ -38,11 +35,11 @@ public class ThresholdAlgorithm implements InterfaceOptimizer, java.io.Serializa } public ThresholdAlgorithm(ThresholdAlgorithm a) { - this.m_Population = (Population)a.m_Population.clone(); - this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone(); - this.m_InitialT = a.m_InitialT; - this.m_CurrentT = a.m_CurrentT; - this.m_Alpha = a.m_Alpha; + this.m_Population = (Population) a.m_Population.clone(); + this.m_Problem = (InterfaceOptimizationProblem) a.m_Problem.clone(); + this.m_InitialT = a.m_InitialT; + this.m_CurrentT = a.m_CurrentT; + this.m_Alpha = a.m_Alpha; } @Override @@ -50,7 +47,8 @@ public class ThresholdAlgorithm implements InterfaceOptimizer, java.io.Serializa return (Object) new ThresholdAlgorithm(this); } - /** This method will init the HillClimber + /** + * This method will init the HillClimber */ @Override public void init() { @@ -60,28 +58,31 @@ public class ThresholdAlgorithm implements InterfaceOptimizer, java.io.Serializa this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** This method will init the optimizer with a given population - * @param pop The initial population - * @param reset If true the population is reset. + /** + * This method will init the optimizer with a given population + * + * @param pop The initial population + * @param reset If true the population is reset. */ @Override public void initByPopulation(Population pop, boolean reset) { - this.m_Population = (Population)pop.clone(); + this.m_Population = (Population) pop.clone(); this.m_CurrentT = this.m_InitialT; if (reset) { - this.m_Population.init(); + this.m_Population.init(); this.m_Problem.evaluate(this.m_Population); this.firePropertyChangedEvent(Population.nextGenerationPerformed); } } - /** This method will optimize + /** + * This method will optimize */ @Override public void optimize() { - AbstractEAIndividual indy; - Population original = (Population)this.m_Population.clone(); - double delta; + AbstractEAIndividual indy; + Population original = (Population) this.m_Population.clone(); + double delta; for (int i = 0; i < this.m_Population.size(); i++) { indy = ((AbstractEAIndividual) this.m_Population.get(i)); @@ -92,7 +93,7 @@ public class ThresholdAlgorithm implements InterfaceOptimizer, java.io.Serializa } this.m_Problem.evaluate(this.m_Population); for (int i = 0; i < this.m_Population.size(); i++) { - delta = this.calculateDelta(((AbstractEAIndividual)original.get(i)), ((AbstractEAIndividual)this.m_Population.get(i))); + delta = this.calculateDelta(((AbstractEAIndividual) original.get(i)), ((AbstractEAIndividual) this.m_Population.get(i))); if (delta < this.m_CurrentT) { this.m_Population.remove(i); this.m_Population.add(i, original.get(i)); @@ -103,13 +104,15 @@ public class ThresholdAlgorithm implements InterfaceOptimizer, java.io.Serializa this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** This method calculates the difference between the fitness values - * @param org The original - * @param mut The mutant + /** + * This method calculates the difference between the fitness values + * + * @param org The original + * @param mut The mutant */ private double calculateDelta(AbstractEAIndividual org, AbstractEAIndividual mut) { - double result = 0; - double[] fitOrg, fitMut; + double result = 0; + double[] fitOrg, fitMut; fitOrg = org.getFitness(); fitMut = mut.getFitness(); for (int i = 0; i < fitOrg.length; i++) { @@ -118,19 +121,23 @@ public class ThresholdAlgorithm implements InterfaceOptimizer, java.io.Serializa return result; } - /** This method will set the problem that is to be optimized + /** + * This method will set the problem that is to be optimized + * * @param problem */ @Override - public void setProblem (InterfaceOptimizationProblem problem) { + public void setProblem(InterfaceOptimizationProblem problem) { this.m_Problem = problem; } + @Override - public InterfaceOptimizationProblem getProblem () { + public InterfaceOptimizationProblem getProblem() { return this.m_Problem; } - /** This method will init the HillClimber + /** + * This method will init the HillClimber */ public void defaultInit() { this.m_FitnessCallsNeeded = 0; @@ -138,24 +145,26 @@ public class ThresholdAlgorithm implements InterfaceOptimizer, java.io.Serializa this.m_Best.defaultInit(m_Problem); } - /** This method will optimize + /** + * This method will optimize */ public void defaultOptimize() { for (int i = 0; i < m_FitnessCalls; i++) { - this.m_Test = (GAIndividualBinaryData)((this.m_Best).clone()); + this.m_Test = (GAIndividualBinaryData) ((this.m_Best).clone()); this.m_Test.defaultMutate(); if (this.m_Test.defaultEvaulateAsMiniBits() < this.m_Best.defaultEvaulateAsMiniBits()) { this.m_Best = this.m_Test; } this.m_FitnessCallsNeeded = i; if (this.m_Best.defaultEvaulateAsMiniBits() == 0) { - i = this.m_FitnessCalls +1; + i = this.m_FitnessCalls + 1; } } } - /** This main method will start a simple hillclimber. - * No arguments necessary. + /** + * This main method will start a simple hillclimber. No arguments necessary. + * * @param args */ public static void main(String[] args) { @@ -169,30 +178,35 @@ public class ThresholdAlgorithm implements InterfaceOptimizer, java.io.Serializa } TmpMeanCalls /= program.m_MultiRuns; TmpMeanFitness /= program.m_MultiRuns; - System.out.println("("+program.m_MultiRuns+"/"+program.m_FitnessCalls+") Mean Fitness : " + TmpMeanFitness + " Mean Calls needed: " + TmpMeanCalls); + System.out.println("(" + program.m_MultiRuns + "/" + program.m_FitnessCalls + ") Mean Fitness : " + TmpMeanFitness + " Mean Calls needed: " + TmpMeanCalls); } + @Override public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { this.m_Listener = ea; } + @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - protected void firePropertyChangedEvent (String name) { + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } + + protected void firePropertyChangedEvent(String name) { if (this.m_Listener != null) { this.m_Listener.registerPopulationStateChanged(this, name); } } - /** This method will return a string describing all properties of the optimizer - * and the applied methods. + /** + * This method will return a string describing all properties of the + * optimizer and the applied methods. + * * @return A descriptive string */ @Override @@ -200,96 +214,112 @@ public class ThresholdAlgorithm implements InterfaceOptimizer, java.io.Serializa String result = ""; if (this.m_Population.size() > 1) { result += "Multi(" + this.m_Population.size() + ")-Start Hill Climbing:\n"; - } - else { + } else { result += "Threshold Algorithm:\n"; } result += "Optimization Problem: "; - result += this.m_Problem.getStringRepresentationForProblem(this) +"\n"; + result += this.m_Problem.getStringRepresentationForProblem(this) + "\n"; result += this.m_Population.getStringRepresentation(); return result; } - /** This method allows you to set an identifier for the algorithm - * @param name The indenifier + + /** + * This method allows you to set an identifier for the algorithm + * + * @param name The indenifier */ @Override - public void setIdentifier(String name) { + public void setIdentifier(String name) { this.m_Identifier = name; } - @Override - public String getIdentifier() { - return this.m_Identifier; - } - /** This method is required to free the memory on a RMIServer, - * but there is nothing to implement. - */ @Override - public void freeWilly() { - + public String getIdentifier() { + return this.m_Identifier; } -/********************************************************************************************************************** - * These are for GUI - */ - /** This method returns a global info string + + /** + * ******************************************************************************************************************** + * These are for GUI + */ + /** + * This method returns a global info string + * * @return description */ public static String globalInfo() { return "The threshold algorithm uses an declining threshold to accpect new solutions."; } - /** This method will return a naming String + + /** + * This method will return a naming String + * * @return The name of the algorithm */ @Override public String getName() { return "MS-TA"; } - /** Assuming that all optimizer will store thier data in a population - * we will allow acess to this population to query to current state - * of the optimizer. + + /** + * Assuming that all optimizer will store thier data in a population we will + * allow acess to this population to query to current state of the + * optimizer. + * * @return The population of current solutions to a given problem. */ @Override public Population getPopulation() { return this.m_Population; } + @Override - public void setPopulation(Population pop){ + public void setPopulation(Population pop) { this.m_Population = pop; } + public String populationTipText() { return "Change the number of best individuals stored (MS-TA)."; } - + @Override public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(getPopulation()); + return new SolutionSet(getPopulation()); } - /** Set the initial threshold + + /** + * Set the initial threshold + * * @return The initial temperature. */ public double getInitialT() { return this.m_InitialT; } - public void setInitialT(double pop){ + + public void setInitialT(double pop) { this.m_InitialT = pop; } + public String initialTTipText() { return "Set the initial threshold."; } - /** Set alpha, which is used to degrade the threshold + /** + * Set alpha, which is used to degrade the threshold + * * @return The initial temperature. */ public double getAlpha() { return this.m_Alpha; } - public void setAlpha(double a){ + + public void setAlpha(double a) { this.m_Alpha = a; if (this.m_Alpha > 1) { this.m_Alpha = 1.0; } } + public String alphaTipText() { return "Set alpha, which is used to degrade the threshold."; } diff --git a/src/eva2/server/go/strategies/Tribes.java b/src/eva2/server/go/strategies/Tribes.java index 62604d8d..6b7dccc3 100644 --- a/src/eva2/server/go/strategies/Tribes.java +++ b/src/eva2/server/go/strategies/Tribes.java @@ -17,213 +17,205 @@ import eva2.server.go.strategies.tribes.TribesSwarm; import java.util.Iterator; import java.util.List; - /** * This is the TRIBES algorithm, an adaptive, parameter-less PSO implementation. - * I (MK) ported M.Clerc's java version 2006-02 21 and added the original notes below. - * I had to do some modifications for the EvA framework, namely: - * - minor adaptations allover the code to fit into the framework - * - the objective value parameter must now be set within the GUI for each problem by hand (EvA doesnt assume to know an objective beforehand) - * - discrete search spaces are not directly supported any more (no "granularity") - * - the benchmark-collection is gone, it might be included into the EvA benchmark set in the future, though - * - fixed two bugs (SunnySpell link generation, findWorst method) - * - fixed bugs in the CEC 2005 benchmarks (see the corresponding class) - * - I widely kept the original comments, except for places I changed the code so much that they might mislead - * - thats all, I think + * I (MK) ported M.Clerc's java version 2006-02 21 and added the original notes + * below. I had to do some modifications for the EvA framework, namely: - minor + * adaptations allover the code to fit into the framework - the objective value + * parameter must now be set within the GUI for each problem by hand (EvA doesnt + * assume to know an objective beforehand) - discrete search spaces are not + * directly supported any more (no "granularity") - the benchmark-collection is + * gone, it might be included into the EvA benchmark set in the future, though - + * fixed two bugs (SunnySpell link generation, findWorst method) - fixed bugs in + * the CEC 2005 benchmarks (see the corresponding class) - I widely kept the + * original comments, except for places I changed the code so much that they + * might mislead - thats all, I think * - * I could produce similar results as Clerc's on Rosenbrock and Griewank, (in his book on p. 148), - * I couldnt reproduce the 100% success rate on Ackley, though. + * I could produce similar results as Clerc's on Rosenbrock and Griewank, (in + * his book on p. 148), I couldnt reproduce the 100% success rate on Ackley, + * though. * * @author Maurice Clerc, Marcel Kronfeld * @date 2007-09-13 * * Original notes: * @version 2006-02 21 - * @author Maurice.Clerc@WriteMe.com - * {@link http://mauriceclerc.net} + * @author Maurice.Clerc@WriteMe.com {@link http://mauriceclerc.net} * {@link http://clerc.maurice.free.fr/pso/} * */ /* Last updates (M.Clerc) -2006-02-21 Added a repelling option (see variable "repel" in Tribes). Not very convincing -2006-01-03 Fixed a bug in maxIsolated (the memory was not well updated after improvement) - Also the same bug in "swarm" and "tribe". Thanks to Yann Cooreen. - Fortunately it was apparently without incidence -2005-12-26 Added items ALL for benchmarks 1 and 2, so that you can launch the whole - benchmark ... and have a cup of tea! -2005-12-26 Fixed a bug. When you launched several optimisations (almost) on the same time - result were not all the same (synchronisation problems) - So you had to launch each problem one at a time. + 2006-02-21 Added a repelling option (see variable "repel" in Tribes). Not very convincing + 2006-01-03 Fixed a bug in maxIsolated (the memory was not well updated after improvement) + Also the same bug in "swarm" and "tribe". Thanks to Yann Cooreen. + Fortunately it was apparently without incidence + 2005-12-26 Added items ALL for benchmarks 1 and 2, so that you can launch the whole + benchmark ... and have a cup of tea! + 2005-12-26 Fixed a bug. When you launched several optimisations (almost) on the same time + result were not all the same (synchronisation problems) + So you had to launch each problem one at a time. Now it is done automatically. Even if you launch a problem before than the previous one is finished, in fact this second one is waiting the end of the other. 2005-12-25 Removed bias in favor of strategy 5 2005-12-25 Added a new way to generate the new tribe: - the first particle in the biggest no man's land, and the other "around" - A bit less efficient at the beginning (i.e. for small number of - evaluations, but also a bit _more_ efficient after that. - See adaptSwarm, hardcoded parameter gMode. + the first particle in the biggest no man's land, and the other "around" + A bit less efficient at the beginning (i.e. for small number of + evaluations, but also a bit _more_ efficient after that. + See adaptSwarm, hardcoded parameter gMode. 2005-12-25 Added some test options (repulsion) for TO DO 2005-12-23 items - Not convincing for the moment + Not convincing for the moment 2005-12-22 There was a mistake in memory management. Basically, I had written - something like f2[]=f1[] for some vectors. In Java, it does _not_ make - a copy of f1, but f2 and f1 are the same object (if f1 if modified later - so is f2). The right way is a loop on components. Results are now a bit - better. + something like f2[]=f1[] for some vectors. In Java, it does _not_ make + a copy of f1, but f2 and f1 are the same object (if f1 if modified later + so is f2). The right way is a loop on components. Results are now a bit + better. 2005-12-21 Added strategy 7, mixture of velocity+hyperspheres. Not convincing 2005-12-15 Non-multiobjective non-penalty approach for constrained problems. - When a constraint is not satisfied, the particle simply goes back. - See g01.txt for data example. Not convincing at all... + When a constraint is not satisfied, the particle simply goes back. + See g01.txt for data example. Not convincing at all... 2005-12-11 24 constrained problems (CEC 2006 benchmark - http://www.ntu.edu.sg/home5/lian0012/cec2006/) - seen as multiobjective problems (means you have to run a given problem - several times, and to choose "manually" the best solution: all constraints - equal to zero and minimum fitness. See synthSave.txt file + http://www.ntu.edu.sg/home5/lian0012/cec2006/) + seen as multiobjective problems (means you have to run a given problem + several times, and to choose "manually" the best solution: all constraints + equal to zero and minimum fitness. See synthSave.txt file 2005-12-07 Multiobjective 2005-11-30 "Blind" move for very good particles, with a probability Tribes.blind - (? Not very convincing) + (? Not very convincing) 2005-11-25 Modified the way velocity is initialized (note that velocity is simply - not used for some strategies, anyway). It is now less arbitrary. - See explorer.generateExplorer() + not used for some strategies, anyway). It is now less arbitrary. + See explorer.generateExplorer() 2005-11-24 Queen (don't seem to be very useful, though) 2005-11-24 More benchmark problems (1 to 11, now) 2005-11-24 Partly rewritten in a more modular way (easier to update). - Note that it implies it is also a bit slower... + Note that it implies it is also a bit slower... 2005-11-21 Strategy 5 with adaptive confidence coefficients 2005-11-21 keepIn option. If "false" the particle is not kept in the search space - (an artifical fitness is computed, with a penalty) + (an artifical fitness is computed, with a penalty) */ /* --- TO DO 2006-02-23 Local search (say Newton-Raphson) from time to time around shamans 2005-12-11 Automatically "clean up" the result file for multiobjective problems - (as in the C version) + (as in the C version) 2005-11-27 Local search for the shamans, for example pseudo-gradient method 2005-11-25 Regular initialisation (cf. tesselation). Not really useful as long as - the initial number of particles is very low. + the initial number of particles is very low. 2005-11-22 possibility to define a list of values on any dimension (needed, for example - for "Compression spring" problem) (Cf. C version of Tribes) + for "Compression spring" problem) (Cf. C version of Tribes) */ /* TO TRY 2005-12-26 min(x1*x2-N) pour N entier donné et x1, x2 entiers 2005-12-26 Un billard arrondi est chaotique, au contraire d'un rectangulaire. - Que se passe-t-il pour les confinements si l'espace de recherche - n'est plus un hyperparallélépipède ? + Que se passe-t-il pour les confinements si l'espace de recherche + n'est plus un hyperparallélépipède ? 2005-12-26 Analyse harmonique. Vibrations de l'espace, des particules. - Décomposition de Fourier au fur et à mesure de l'échantillonnage => - description de plus en plus fine du paysage => estimations des zéros + Décomposition de Fourier au fur et à mesure de l'échantillonnage => + description de plus en plus fine du paysage => estimations des zéros 2005-12-25 Utiliser (cycliquement ?) une liste de nombres aléatoires - de plus en plus courte + de plus en plus courte 2005-12-23 WORK IN PROGRESS. Seriously modify the algorithm: - - when generation is needed, generate one particle for the current tribe - and one for the new tribe (?) - - remove migration - - maybe remove "delete particle" part + - when generation is needed, generate one particle for the current tribe + and one for the new tribe (?) + - remove migration + - maybe remove "delete particle" part - 2005-12-23 - use links between tribes for _repulsion_ : - DONE as TEST. Not convincing. Maybe try some other rules + 2005-12-23 - use links between tribes for _repulsion_ : + DONE as TEST. Not convincing. Maybe try some other rules 2005-11-25 See if LS-CMA-ES (Hansen) could be sometimes used 2005-11-21. Check if it is possible to easily find just the _value_ of the - global minimum (not the position). "Chinese shadow" method? + global minimum (not the position). "Chinese shadow" method? */ - public class Tribes implements InterfaceOptimizer, java.io.Serializable { - public static final boolean TRACE = false; + public static final boolean TRACE = false; + protected String m_Identifier = "TRIBES"; + transient private InterfacePopulationChangedEventListener m_Listener = null; + protected AbstractOptimizationProblem m_problem; + protected Population population; + public static int maxExplorerNb = 200; + public static int maxMemoryNb = 300; + public static int maxTribeNb = 300; + public static int[] strategies = new int[10]; // Just for information + public static int[] status = new int[9]; // Just for information + public static boolean testBC = false; // TODO project to EvA2 + public static int adaptOption = 2; + public static double blind = 0; // 0.5 //"Blind" move for very good particles, with a probability Tribes.blind + public static boolean repel = false; // If 1, use a "repelling" strategy (see moveExplorer() ) + private boolean checkConstraints = true; + private static final long serialVersionUID = 1L; + TribesSwarm swarm = null; + private int iter; + protected double objectiveFirstDim = 0.; + protected double[][] range, initRange; + protected int notifyGenChangedEvery = 10; + protected int problemDim; + protected int adaptThreshold, adaptMax, adapt; + protected int informOption; /* For the best informant. + -1 => really the best + 1 => the best according to a pseudo-gradient method + */ - protected String m_Identifier = "TRIBES"; - transient private InterfacePopulationChangedEventListener m_Listener = null; - protected AbstractOptimizationProblem m_problem; - protected Population population; - - public static int maxExplorerNb = 200; - public static int maxMemoryNb = 300; - public static int maxTribeNb = 300; - - public static int[] strategies = new int[10]; // Just for information - public static int[] status = new int[9]; // Just for information - - public static boolean testBC = false; // TODO project to EvA2 - public static int adaptOption = 2; - public static double blind=0; // 0.5 //"Blind" move for very good particles, with a probability Tribes.blind - public static boolean repel=false; // If 1, use a "repelling" strategy (see moveExplorer() ) - private boolean checkConstraints=true; - - private static final long serialVersionUID = 1L; - - TribesSwarm swarm = null; - private int iter; - protected double objectiveFirstDim = 0.; - protected double[][] range, initRange; - protected int notifyGenChangedEvery = 10; - - protected int problemDim; - protected int adaptThreshold, adaptMax, adapt; - protected int informOption; /* For the best informant. - -1 => really the best - 1 => the best according to a pseudo-gradient method - */ - protected int initExplorerNb=3; // Number of explorers at the very beginning - // use full range (0) or subspace (1) for init options 0 and 1 - protected int rangeInitType=1; - - private boolean m_Show = false; - transient protected eva2.gui.Plot m_Plot = null; + protected int initExplorerNb = 3; // Number of explorers at the very beginning + // use full range (0) or subspace (1) for init options 0 and 1 + protected int rangeInitType = 1; + private boolean m_Show = false; + transient protected eva2.gui.Plot m_Plot = null; // private int useAnchors = 0; // use anchors to detect environment changes? @Override - public Object clone() { - return new Tribes(this); - } + public Object clone() { + return new Tribes(this); + } - public Tribes() { - hideHideable(); - } + public Tribes() { + hideHideable(); + } - public Tribes(Tribes other) { - this.setProblem(other.getProblem()); - iter = other.iter; - setObjectiveFirstDim(other.getObjectiveFirstDim()); - setDimension(other.range.length); - setNotifyGenChangedEvery(other.getNotifyGenChangedEvery()); - range = other.range.clone(); - problemDim = other.problemDim; - adaptThreshold = other.adaptThreshold; - adaptMax = other.adaptMax; - adapt = other.adapt; - informOption = other.informOption; - swarm = other.swarm.clone(); - initExplorerNb = other.initExplorerNb; - rangeInitType = other.rangeInitType; - population = new Population(1); - hideHideable(); - } + public Tribes(Tribes other) { + this.setProblem(other.getProblem()); + iter = other.iter; + setObjectiveFirstDim(other.getObjectiveFirstDim()); + setDimension(other.range.length); + setNotifyGenChangedEvery(other.getNotifyGenChangedEvery()); + range = other.range.clone(); + problemDim = other.problemDim; + adaptThreshold = other.adaptThreshold; + adaptMax = other.adaptMax; + adapt = other.adapt; + informOption = other.informOption; + swarm = other.swarm.clone(); + initExplorerNb = other.initExplorerNb; + rangeInitType = other.rangeInitType; + population = new Population(1); + hideHideable(); + } @Override - public void setProblem(InterfaceOptimizationProblem problem) { + public void setProblem(InterfaceOptimizationProblem problem) { // System.out.println("TRIBES.SetProblem()"); - m_problem = (AbstractOptimizationProblem)problem; - range = null; - if (problem instanceof InterfaceHasInitRange) { - initRange = (double[][])((InterfaceHasInitRange)problem).getInitRange(); - } - Population pop = new Population(1); - problem.initPopulation(pop); - setPopulation(pop); - } + m_problem = (AbstractOptimizationProblem) problem; + range = null; + if (problem instanceof InterfaceHasInitRange) { + initRange = (double[][]) ((InterfaceHasInitRange) problem).getInitRange(); + } + Population pop = new Population(1); + problem.initPopulation(pop); + setPopulation(pop); + } @Override - public void init() { + public void init() { // System.out.println("TRIBES.init()"); - // Generate a swarm - swarm = new TribesSwarm(this, range, initRange); // TODO initRange is hard coded equal to problem range - //swarm.generateSwarm(initExplorerNb, initType, m_problem); + // Generate a swarm + swarm = new TribesSwarm(this, range, initRange); // TODO initRange is hard coded equal to problem range + //swarm.generateSwarm(initExplorerNb, initType, m_problem); - // swarm.displaySwarm(swarm,out); - // print("\n Best after init: "+swarm.Best.position.fitness,out); + // swarm.displaySwarm(swarm,out); + // print("\n Best after init: "+swarm.Best.position.fitness,out); iter = 0; adapt = 0; @@ -236,578 +228,492 @@ public class Tribes implements InterfaceOptimizer, java.io.Serializable { population.clear(); population.addAll(swarm.toPopulation()); population.init(); // necessary to allow for multi-runs - + if (m_Show) { - show(); - } + show(); + } - } + } - /** - * As TRIBES manages an own structured set of particles (the list of Tribes containing explorers - * and memories), the setPopulation method is only telling Tribes the range - * of the indiviuals in the beginning of the run, the individuals will be discarded. - */ + /** + * As TRIBES manages an own structured set of particles (the list of Tribes + * containing explorers and memories), the setPopulation method is only + * telling Tribes the range of the indiviuals in the beginning of the run, + * the individuals will be discarded. + */ @Override - public void initByPopulation(Population pop, boolean reset) { - setPopulation(pop); - } + public void initByPopulation(Population pop, boolean reset) { + setPopulation(pop); + } + + public AbstractEAIndividual getBestInd() { + TribesPosition bestMemPos = swarm.getBestMemory().getPos(); + AbstractEAIndividual bestExp = population.getBestEAIndividual(); + if (bestMemPos.firstIsBetter(bestMemPos.getFitness(), bestExp.getFitness())) { + AbstractEAIndividual indy = (AbstractEAIndividual) bestExp.clone(); + indy.setFitness(bestMemPos.getFitness()); + ((InterfaceDataTypeDouble) indy).SetDoubleGenotype(bestMemPos.getPos()); + return indy; + } else { + return bestExp; + } + } - public AbstractEAIndividual getBestInd() { - TribesPosition bestMemPos = swarm.getBestMemory().getPos(); - AbstractEAIndividual bestExp = population.getBestEAIndividual(); - if (bestMemPos.firstIsBetter(bestMemPos.getFitness(), bestExp.getFitness())) { - AbstractEAIndividual indy = (AbstractEAIndividual)bestExp.clone(); - indy.setFitness(bestMemPos.getFitness()); - ((InterfaceDataTypeDouble)indy).SetDoubleGenotype(bestMemPos.getPos()); - return indy; - } else { - return bestExp; - } - } - @Override - public void optimize() { - - int initOption = 0; - if (iter == 0) { // first iteration! - if (initRange == null) { - rangeInitType = 0; - } else { - rangeInitType = 1; // 1 means in initRange for a start - } - //* initOption Options: 0 - random, 1 - on the bounds, 2 - sunny spell, 3 - around a center - //* rangeInitType for options 0,1: 1 means use initRange, 0 use default range - swarm.generateSwarm(initExplorerNb, initOption, rangeInitType, m_problem); - } - iter++; + public void optimize() { - m_problem.evaluatePopulationStart(population); - swarm.setSwarmSize(); - // swarm.Best.positionPrev = swarm.Best.position; - - swarm.moveSwarm(range, new TribesParam(), informOption, m_problem); //*** HERE IT MOVES and EVALUATES - //public void moveSwarm(double[][] range, int fitnessSize, TribesParam pb, TribesSwarm swarm, - // int informOption, AbstractOptimizationProblem prob) { - - if (Tribes.adaptOption != 0) { // perform adaption - if (Tribes.adaptOption == 1) { // Just reinitialize the swarm - adaptThreshold = iter - adapt; - // adaptMax=swarmSize; - adaptMax = swarm.linkNb(swarm); - if (adaptThreshold >= adaptMax) { - if (swarm.getBestMemory().getPrevPos().getTotalError() <= - swarm.getBestMemory().getPos().getTotalError()) { - adapt = iter; // Memorize at which iteration adaptation occurs - - for (int i = 0; i < swarm.getTribeCnt(); i++) { - swarm.reinitTribe(i, rangeInitType, m_problem); - } - } - } - } else // if(swarm.Best.positionPrev.getTotalError()<=swarm.Best.position.getTotalError()) - { - // Structural adaptations - - adaptThreshold = iter - adapt; - // adaptMax=swarmSize; - adaptMax = swarm.linkNb(swarm); - - if (adaptThreshold >= adaptMax) { - adapt = iter; // Memorize at which iteration adaptation occurs - swarm.adaptSwarm(rangeInitType, m_problem); // Re´alise l'adaptation - } - } - } - population.clear(); - population.addAll(swarm.toPopulation()); - if (m_Show) { - plotAll(population); + int initOption = 0; + if (iter == 0) { // first iteration! + if (initRange == null) { + rangeInitType = 0; + } else { + rangeInitType = 1; // 1 means in initRange for a start } - m_problem.evaluatePopulationEnd(population); - -// this.population.incrFunctionCallsby(evals); - this.population.incrGeneration(); - //this.firePropertyChangedEvent("NextGenerationPerformed"); // This is now done implicitely, as after every evaluation, addEvals is called - - if (TRACE) { - System.out.println("loop finished after " + population.getFunctionCalls() + " evaluations"); - //for (int i=0; i epsMax) { - epsMax = eps[run]; - } - } - - // Mean values - epsMean = 0; - evalMean = 0; - for (run = 0; run < pb.maxRun; run++) { - epsMean = epsMean + eps[run]; - evalMean = evalMean + evalNb[run]; - } - - epsMean = epsMean / pb.maxRun; - evalMean = evalMean / pb.maxRun; - print("\nStatuses ", displayPb); - for (n = 1; n < 10; n++) { - print("\n" + n + " " + Tribes.status[n - 1] + " times", - displayPb); - } - print("\nStrategies ", displayPb); - for (n = 1; n < 10; n++) { - print("\n" + n + " " + Tribes.strategies[n - 1] + " times", - displayPb); - } - print("\nMIN BEST TOTAL_ERROR " + epsMin, displayPb); - print("\nMEAN BEST TOTAL_ERROR " + epsMean, displayPb); - print("\nMEAN EVAL. NUMBER " + evalMean, displayPb); - print("\n SUCCESS RATE " + (double) successNb / pb.maxRun, - displayPb); - - save("\nMIN BEST TOTAL_ERROR " + epsMin, synthSave); - save("\nMEAN BEST TOTAL_ERROR " + epsMean, synthSave); - save("\nMEAN EVAL. NUMBER " + evalMean, synthSave); - save("\n SUCCESS RATE " + (double) successNb / pb.maxRun, synthSave); - - save("\n-1", runSave); // Special value for the end of the file. Used for graphics - - } // End of search() - - public double[] solve(param pb, int initExplorerNb, PrintStream runSave, PrintStream synthSave) { - int adapt, adaptMax; - int adaptThreshold; - int d, D = pb.H.Dimension; - int evalF; - int iter; - int n; - boolean stop; - double[] temp = new double[3]; - int informOption; -// For the best informant. -// -1 => really the best -// 1 => the best according to a pseudo-gradient method - - // -----------INIT START - // Generate a swarm - evalF=0; - swarm swarm = new swarm(); - evalF=swarm.generateSwarm(pb, initExplorerNb, pb.initType, displayPb,evalF); - - // swarm.displaySwarm(swarm,out); - // print("\n Best after init: "+swarm.Best.position.fitness,out); - - // Move the swarm as long as the stop criterion is false - iter = 0; - adapt = 0; - stop = false; - informOption = -1; -// Hard coded option -// -1 = absolute best informant -// 1 = relative (pseudo-gradient) best informant. For "niching" -// See also moveExplorer, which can be modified in order to avoid this parameter -// - // -----------INIT END - - - // -----------OPTIMIZE START - iterations:while (!stop) { - - swarm.size = swarm.swarmSize(swarm); - iter++; - // swarm.Best.positionPrev = swarm.Best.position; - - evalF=swarm.moveSwarm(pb, swarm, informOption, displayPb, evalF); //*** HERE IT MOVES - -// Some display each time there is "enough" improvement -// fduring the process - - double enough = 0.005; - if ((1 - enough) * swarm.Best.positionPrev.totalError > - swarm.Best.position.totalError) { - print("\nIter. " + iter, displayPb); - print(" Eval. " + evalF, displayPb); - print(" totalError " + swarm.Best.position.totalError, - displayPb); - print(" " + swarm.size + " particles", displayPb); - } -// Save run info - save("\n" + iter + " " + evalF + " " + - swarm.Best.position.totalError + " " + swarm.size, runSave); - - // Evaluate the stop criterion - stop = evalF >= pb.maxEval || - pb.accuracy > swarm.Best.position.totalError; - - if (Tribes.adaptOption == 0) { - continue iterations; - } + swarm.moveSwarm(range, new TribesParam(), informOption, m_problem); //*** HERE IT MOVES and EVALUATES + //public void moveSwarm(double[][] range, int fitnessSize, TribesParam pb, TribesSwarm swarm, + // int informOption, AbstractOptimizationProblem prob) { + if (Tribes.adaptOption != 0) { // perform adaption if (Tribes.adaptOption == 1) { // Just reinitialize the swarm adaptThreshold = iter - adapt; // adaptMax=swarmSize; adaptMax = swarm.linkNb(swarm); if (adaptThreshold >= adaptMax) { - if (swarm.Best.positionPrev.totalError <= - swarm.Best.position.totalError) { + if (swarm.getBestMemory().getPrevPos().getTotalError() + <= swarm.getBestMemory().getPos().getTotalError()) { adapt = iter; // Memorize at which iteration adaptation occurs - for (n = 0; n < swarm.tribeNb; n++) { - evalF=swarm.tribes[n].reinitTribe(pb,evalF); + for (int i = 0; i < swarm.getTribeCnt(); i++) { + swarm.reinitTribe(i, rangeInitType, m_problem); } } } - continue iterations; - } - - // if(swarm.Best.positionPrev.totalError<=swarm.Best.position.totalError) + } else // if(swarm.Best.positionPrev.getTotalError()<=swarm.Best.position.getTotalError()) { // Structural adaptations - //swarmSize = swarm.swarmSize(swarm); - -// print("\nSwarm size (explorers): " + swarmSize,out); -// print(" Tribes: (explorers/memories) ",out); -// for (n = 0; n < swarm.tribeNumber; n++) { -// print(swarm.tribes[n].explorerNb + "/" + -// swarm.tribes[n].memoryNb + " ",out); -// } -// -// On "laisse le temps" à chaque tribu de bouger avant éventuelle adaptation -// La règle est empirique et peut être modifiée -// - adaptThreshold = iter - adapt; // adaptMax=swarmSize; adaptMax = swarm.linkNb(swarm); if (adaptThreshold >= adaptMax) { adapt = iter; // Memorize at which iteration adaptation occurs - evalF=swarm.adaptSwarm(pb, Tribes.adaptOption, swarm, - displayPb,evalF); // Réalise l'adaptation - -// Modifie la recherche de la meilleure informatrice -// normale (la "vraie" meilleure) ou dépendant d'un pseudo-gradient -// (cf. informExplorer) -// - // informOption=-informOption; + swarm.adaptSwarm(rangeInitType, m_problem); // Re´alise l'adaptation } -// print("\n Nb of tribes: " + swarm.tribeNumber + -// "\n Particles/tribe:",out); -// for (n = 0; n < swarm.tribeNumber; n++) { -// print(swarm.tribes[n].explorerNb + " ",out); -// } -// -// print("\n Statuses :"); -// for (n = 0; n < swarm.tribeNumber; n++) { -// print(swarm.tribes[n].status + " ",out); -// } - - } - // -----------OPTIMIZE END } - - // Result of the run - print("\nBest: eval.= " + evalF + "\n", displayPb); - swarm.Best.displayMemory(displayPb); - - save(" " + iter + " " + evalF+ " ", synthSave); - - for (d = 0; d < pb.fitnessSize; d++) { - save(swarm.Best.position.fitness[d] + " ", synthSave); + population.clear(); + population.addAll(swarm.toPopulation()); + if (m_Show) { + plotAll(population); } + m_problem.evaluatePopulationEnd(population); - for (d = 0; d < D; d++) { - save(" " + swarm.Best.position.x[d], synthSave); +// this.population.incrFunctionCallsby(evals); + this.population.incrGeneration(); + //this.firePropertyChangedEvent("NextGenerationPerformed"); // This is now done implicitely, as after every evaluation, addEvals is called + + if (TRACE) { + System.out.println("loop finished after " + population.getFunctionCalls() + " evaluations"); + //for (int i=0; i + * epsMax) { epsMax = eps[run]; } } + * + * // Mean values epsMean = 0; evalMean = 0; for (run = 0; run < pb.maxRun; + * run++) { epsMean = epsMean + eps[run]; evalMean = evalMean + evalNb[run]; + * } + * + * epsMean = epsMean / pb.maxRun; evalMean = evalMean / pb.maxRun; + * print("\nStatuses ", displayPb); for (n = 1; n < 10; n++) { print("\n" + + * n + " " + Tribes.status[n - 1] + " times", displayPb); } + * print("\nStrategies ", displayPb); for (n = 1; n < 10; n++) { print("\n" + * + n + " " + Tribes.strategies[n - 1] + " times", displayPb); } + * print("\nMIN BEST TOTAL_ERROR " + epsMin, displayPb); print("\nMEAN BEST + * TOTAL_ERROR " + epsMean, displayPb); print("\nMEAN EVAL. NUMBER " + + * evalMean, displayPb); print("\n SUCCESS RATE " + (double) successNb / + * pb.maxRun, displayPb); + * + * save("\nMIN BEST TOTAL_ERROR " + epsMin, synthSave); save("\nMEAN BEST + * TOTAL_ERROR " + epsMean, synthSave); save("\nMEAN EVAL. NUMBER " + + * evalMean, synthSave); save("\n SUCCESS RATE " + (double) successNb / + * pb.maxRun, synthSave); + * + * save("\n-1", runSave); // Special value for the end of the file. Used for + * graphics + * + * } // End of search() + * + * public double[] solve(param pb, int initExplorerNb, PrintStream runSave, + * PrintStream synthSave) { int adapt, adaptMax; int adaptThreshold; int d, + * D = pb.H.Dimension; int evalF; int iter; int n; boolean stop; double[] + * temp = new double[3]; int informOption; // For the best informant. // -1 + * => really the best // 1 => the best according to a pseudo-gradient method + * + * // -----------INIT START // Generate a swarm evalF=0; swarm swarm = new + * swarm(); evalF=swarm.generateSwarm(pb, initExplorerNb, pb.initType, + * displayPb,evalF); + * + * // swarm.displaySwarm(swarm,out); // print("\n Best after init: + * "+swarm.Best.position.fitness,out); + * + * // Move the swarm as long as the stop criterion is false iter = 0; adapt + * = 0; stop = false; informOption = -1; // Hard coded option // -1 = + * absolute best informant // 1 = relative (pseudo-gradient) best informant. + * For "niching" // See also moveExplorer, which can be modified in order to + * avoid this parameter // // -----------INIT END + * + * + * // -----------OPTIMIZE START iterations:while (!stop) { + * + * swarm.size = swarm.swarmSize(swarm); iter++; // swarm.Best.positionPrev = + * swarm.Best.position; + * + * evalF=swarm.moveSwarm(pb, swarm, informOption, displayPb, evalF); //*** + * HERE IT MOVES + * + * // Some display each time there is "enough" improvement // fduring the + * process + * + * double enough = 0.005; if ((1 - enough) * + * swarm.Best.positionPrev.totalError > swarm.Best.position.totalError) { + * print("\nIter. " + iter, displayPb); print(" Eval. " + evalF, displayPb); + * print(" totalError " + swarm.Best.position.totalError, displayPb); + * print(" " + swarm.size + " particles", displayPb); } // Save run info + * save("\n" + iter + " " + evalF + " " + swarm.Best.position.totalError + " + * " + swarm.size, runSave); + * + * // Evaluate the stop criterion stop = evalF >= pb.maxEval || pb.accuracy + * > swarm.Best.position.totalError; + * + * if (Tribes.adaptOption == 0) { continue iterations; } + * + * if (Tribes.adaptOption == 1) { // Just reinitialize the swarm + * adaptThreshold = iter - adapt; // adaptMax=swarmSize; adaptMax = + * swarm.linkNb(swarm); if (adaptThreshold >= adaptMax) { if + * (swarm.Best.positionPrev.totalError <= swarm.Best.position.totalError) { + * adapt = iter; // Memorize at which iteration adaptation occurs + * + * for (n = 0; n < swarm.tribeNb; n++) { + * evalF=swarm.tribes[n].reinitTribe(pb,evalF); } } } continue iterations; } + * + * // if(swarm.Best.positionPrev.totalError<=swarm.Best.position.totalError) + * { // Structural adaptations + * + * //swarmSize = swarm.swarmSize(swarm); + * + * // print("\nSwarm size (explorers): " + swarmSize,out); // print(" + * Tribes: (explorers/memories) ",out); // for (n = 0; n < + * swarm.tribeNumber; n++) { // print(swarm.tribes[n].explorerNb + "/" + // + * swarm.tribes[n].memoryNb + " ",out); // } // // On "laisse le temps" à + * chaque tribu de bouger avant éventuelle adaptation // La règle est + * empirique et peut être modifiée // + * + * adaptThreshold = iter - adapt; // adaptMax=swarmSize; adaptMax = + * swarm.linkNb(swarm); + * + * if (adaptThreshold >= adaptMax) { adapt = iter; // Memorize at which + * iteration adaptation occurs evalF=swarm.adaptSwarm(pb, + * Tribes.adaptOption, swarm, displayPb,evalF); // Réalise l'adaptation + * + * // Modifie la recherche de la meilleure informatrice // normale (la + * "vraie" meilleure) ou dépendant d'un pseudo-gradient // (cf. + * informExplorer) // // informOption=-informOption; } // print("\n Nb of + * tribes: " + swarm.tribeNumber + // "\n Particles/tribe:",out); // for (n + * = 0; n < swarm.tribeNumber; n++) { // print(swarm.tribes[n].explorerNb + + * " ",out); // } // // print("\n Statuses :"); // for (n = 0; n < + * swarm.tribeNumber; n++) { // print(swarm.tribes[n].status + " ",out); // + * } + * + * + * } + * // -----------OPTIMIZE END } + * + * // Result of the run print("\nBest: eval.= " + evalF + "\n", displayPb); + * swarm.Best.displayMemory(displayPb); + * + * save(" " + iter + " " + evalF+ " ", synthSave); + * + * for (d = 0; d < pb.fitnessSize; d++) { + * save(swarm.Best.position.fitness[d] + " ", synthSave); } + * + * for (d = 0; d < D; d++) { save(" " + swarm.Best.position.x[d], + * synthSave); } + * + * // Prepare return temp[0] = swarm.Best.position.totalError; temp[1] = + * evalF; if (evalF < pb.maxEval) { temp[2] = 1; } else { temp[2] = 0; } + * + * return temp; } + * + */ + /** + * Population will be hidden. + */ + public void hideHideable() { + GenericObjectEditor.setShowProperty(getClass(), "population", false); + } + + /** + * As TRIBES manages an own structured set of particles (the list of Tribes + * containing explorers and memories), the setPopulation method is only + * telling Tribes the range of the indiviuals in the beginning of the run, + * the individuals will be discarded. + */ @Override - public Population getPopulation() { - return population; - } - - /** - * Return a SolutionSet of TribesExplorers (AbstractEAIndividuals) of which some where - * memory particles, thus the returned population is larger than the current population. - * - * @return a population of possible solutions. - */ + public void setPopulation(Population pop) { + if (pop == null) { + return; + } + population = pop; + if (population.get(0) instanceof InterfaceDataTypeDouble) { + range = ((InterfaceDataTypeDouble) population.get(0)).getDoubleRange(); + setDimension(range.length); + } else { + System.err.println("warning, TRIBES requires InterfaceESIndidivual instead of " + population.get(0).getClass() + ". Couldnt correctly init the problem range."); + } + } + + private void setDimension(int length) { + problemDim = length; + init(); + } + + public int getProblemDim() { + return problemDim; + } + + /** + * Be aware that TRIBES uses two kinds of particles: explorers and memories. + * As memories are inactive in that they dont search the problem space + * directly, they are not included in the returned population. This, + * however, means that the best found solution might not be inluded as well + * at several if not most stages of the search. + */ + @Override + public Population getPopulation() { + return population; + } + + /** + * Return a SolutionSet of TribesExplorers (AbstractEAIndividuals) of which + * some where memory particles, thus the returned population is larger than + * the current population. + * + * @return a population of possible solutions. + */ @Override public InterfaceSolutionSet getAllSolutions() { - // return population and memories? - Population all = (Population)population.clone(); - List mems = swarm.collectMem(); - for (Iterator iterator = mems.iterator(); iterator.hasNext();) { - TribesPosition tp = iterator.next(); - all.add(positionToExplorer(tp)); - } - all.SetFunctionCalls(population.getFunctionCalls()); - all.setGenerationTo(population.getGeneration()); - //all.addPopulation(pop); - return new SolutionSet(population, all); + // return population and memories? + Population all = (Population) population.clone(); + List mems = swarm.collectMem(); + for (Iterator iterator = mems.iterator(); iterator.hasNext();) { + TribesPosition tp = iterator.next(); + all.add(positionToExplorer(tp)); + } + all.SetFunctionCalls(population.getFunctionCalls()); + all.setGenerationTo(population.getGeneration()); + //all.addPopulation(pop); + return new SolutionSet(population, all); } - + protected TribesExplorer positionToExplorer(TribesPosition pos) { - TribesExplorer tmp = (TribesExplorer)population.get(0); - if (tmp == null) { + TribesExplorer tmp = (TribesExplorer) population.get(0); + if (tmp == null) { System.err.println("Error in Tribes::positionToExplorer!"); } - TribesExplorer indy = tmp.clone(); - indy.clearPosVel(); - indy.SetDoubleGenotype(pos.getPos()); - indy.setFitness(pos.getFitness()); - return indy; + TribesExplorer indy = tmp.clone(); + indy.clearPosVel(); + indy.SetDoubleGenotype(pos.getPos()); + indy.setFitness(pos.getFitness()); + return indy; } - - /** This method allows you to add the LectureGUI as listener to the Optimizer - * @param ea - */ - @Override - public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { - this.m_Listener = ea; - } - @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - protected void firePropertyChangedEvent(String name) { - if (this.m_Listener != null) { - this.m_Listener.registerPopulationStateChanged(this, name); - } - } - public boolean notifyAfter(int evals) { - return (evals % notifyGenChangedEvery) == 0; - } + /** + * This method allows you to add the LectureGUI as listener to the Optimizer + * + * @param ea + */ + @Override + public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { + this.m_Listener = ea; + } @Override - public void freeWilly() {} + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } + + protected void firePropertyChangedEvent(String name) { + if (this.m_Listener != null) { + this.m_Listener.registerPopulationStateChanged(this, name); + } + } + + public boolean notifyAfter(int evals) { + return (evals % notifyGenChangedEvery) == 0; + } @Override - public void setIdentifier(String name) { - this.m_Identifier = name; - } - @Override - public String getIdentifier() { - return m_Identifier; - } + public void setIdentifier(String name) { + this.m_Identifier = name; + } @Override - public String getName() { - return "TRIBES"; - } + public String getIdentifier() { + return m_Identifier; + } @Override - public InterfaceOptimizationProblem getProblem() { - return m_problem; - } + public String getName() { + return "TRIBES"; + } @Override - public String getStringRepresentation() { - return globalInfo(); - } - - public static String globalInfo() { - return "TRIBES: a parameter free PSO implementation by Maurice Clerc."; - } + public InterfaceOptimizationProblem getProblem() { + return m_problem; + } - public void incEvalCnt() { - population.incrFunctionCalls(); - if (notifyAfter(population.getFunctionCalls())) { + @Override + public String getStringRepresentation() { + return globalInfo(); + } + + public static String globalInfo() { + return "TRIBES: a parameter free PSO implementation by Maurice Clerc."; + } + + public void incEvalCnt() { + population.incrFunctionCalls(); + if (notifyAfter(population.getFunctionCalls())) { // System.out.println("Notifying after " + population.getFunctionCalls()); - firePropertyChangedEvent(Population.nextGenerationPerformed); - } - } + firePropertyChangedEvent(Population.nextGenerationPerformed); + } + } - public double getObjectiveFirstDim() { - return objectiveFirstDim; - } + public double getObjectiveFirstDim() { + return objectiveFirstDim; + } - public void setObjectiveFirstDim(double objectiveFirstDim) { - this.objectiveFirstDim = objectiveFirstDim; - } + public void setObjectiveFirstDim(double objectiveFirstDim) { + this.objectiveFirstDim = objectiveFirstDim; + } - public String objectiveFirstDimTipText() { - return "TRIBES uses an error approximation based on the minimum objective value in the first dimension depending on the problem"; - } + public String objectiveFirstDimTipText() { + return "TRIBES uses an error approximation based on the minimum objective value in the first dimension depending on the problem"; + } - public int getNotifyGenChangedEvery() { - return notifyGenChangedEvery; - } + public int getNotifyGenChangedEvery() { + return notifyGenChangedEvery; + } - public void setNotifyGenChangedEvery(int notifyGenChangedEvery) { - this.notifyGenChangedEvery = notifyGenChangedEvery; - } + public void setNotifyGenChangedEvery(int notifyGenChangedEvery) { + this.notifyGenChangedEvery = notifyGenChangedEvery; + } - public String notifyGenChangedEveryTipText() { - return "Mainly for the GUI: plot fitness every n evaluations"; - } + public String notifyGenChangedEveryTipText() { + return "Mainly for the GUI: plot fitness every n evaluations"; + } - public boolean isCheckConstraints() { - return checkConstraints; - } + public boolean isCheckConstraints() { + return checkConstraints; + } - public void setCheckConstraints(boolean checkConstraints) { - this.checkConstraints = checkConstraints; - } + public void setCheckConstraints(boolean checkConstraints) { + this.checkConstraints = checkConstraints; + } - // TODO + // TODO // /** // * @return the useAnchor // */ @@ -821,21 +727,20 @@ public class Tribes implements InterfaceOptimizer, java.io.Serializable { // public void setUseAnchor(boolean useAnchor) { // this.useAnchor = useAnchor; // } + /** + * @return the m_Show + */ + public boolean isShow() { + return m_Show; + } - /** - * @return the m_Show - */ - public boolean isShow() { - return m_Show; - } - - /** - * @param show the m_Show to set - */ - public void setShow(boolean show) { - m_Show = show; - if (!show) { - m_Plot = null; - } - } + /** + * @param show the m_Show to set + */ + public void setShow(boolean show) { + m_Show = show; + if (!show) { + m_Plot = null; + } + } } diff --git a/src/eva2/server/go/strategies/WingedMultiObjectiveEA.java b/src/eva2/server/go/strategies/WingedMultiObjectiveEA.java index 619ea188..9d2b8291 100644 --- a/src/eva2/server/go/strategies/WingedMultiObjectiveEA.java +++ b/src/eva2/server/go/strategies/WingedMultiObjectiveEA.java @@ -11,46 +11,43 @@ import eva2.server.go.problems.AbstractMultiObjectiveOptimizationProblem; import eva2.server.go.problems.FM0Problem; import eva2.server.go.problems.InterfaceOptimizationProblem; -/** The winged MOEA was a nice idea, which didn't really work out. - * Here a standard MOEA is assisted by n additional local searchers, each - * optimizing just one objective. The idea was that these local optimizers - * would span the search space and would allow the MOEA to converge faster. - * But in the end the performance of this algorithm strongly depends on the - * optimization problem. - * Created by IntelliJ IDEA. - * User: streiche - * Date: 16.02.2005 - * Time: 16:34:22 - * To change this template use File | Settings | File Templates. +/** + * The winged MOEA was a nice idea, which didn't really work out. Here a + * standard MOEA is assisted by n additional local searchers, each optimizing + * just one objective. The idea was that these local optimizers would span the + * search space and would allow the MOEA to converge faster. But in the end the + * performance of this algorithm strongly depends on the optimization problem. + * Created by IntelliJ IDEA. User: streiche Date: 16.02.2005 Time: 16:34:22 To + * change this template use File | Settings | File Templates. */ public class WingedMultiObjectiveEA implements InterfaceOptimizer, java.io.Serializable { - private InterfaceOptimizer m_MOOptimizer = new MultiObjectiveEA(); - private InterfaceOptimizer m_SOOptimizer = new GeneticAlgorithm(); - private InterfaceOptimizer[] m_SOOptimizers; - private Population m_Population = new Population(); - private int m_MigrationRate = 5; - private int m_OutputDimension = 2; - private int m_NumberOfLocalOptimizers = 2; - private InterfaceOptimizationProblem m_Problem = new FM0Problem(); - private String m_Identifier = ""; + private InterfaceOptimizer m_MOOptimizer = new MultiObjectiveEA(); + private InterfaceOptimizer m_SOOptimizer = new GeneticAlgorithm(); + private InterfaceOptimizer[] m_SOOptimizers; + private Population m_Population = new Population(); + private int m_MigrationRate = 5; + private int m_OutputDimension = 2; + private int m_NumberOfLocalOptimizers = 2; + private InterfaceOptimizationProblem m_Problem = new FM0Problem(); + private String m_Identifier = ""; transient private InterfacePopulationChangedEventListener m_Listener; public WingedMultiObjectiveEA() { } public WingedMultiObjectiveEA(WingedMultiObjectiveEA a) { - this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone(); - this.m_MOOptimizer = (InterfaceOptimizer)a.m_MOOptimizer.clone(); - this.m_SOOptimizer = (InterfaceOptimizer)a.m_SOOptimizer.clone(); + this.m_Problem = (InterfaceOptimizationProblem) a.m_Problem.clone(); + this.m_MOOptimizer = (InterfaceOptimizer) a.m_MOOptimizer.clone(); + this.m_SOOptimizer = (InterfaceOptimizer) a.m_SOOptimizer.clone(); if (a.m_SOOptimizers != null) { this.m_SOOptimizers = new InterfaceOptimizer[a.m_SOOptimizers.length]; for (int i = 0; i < this.m_SOOptimizers.length; i++) { - this.m_SOOptimizers[i] = (InterfaceOptimizer)a.m_SOOptimizers[i].clone(); + this.m_SOOptimizers[i] = (InterfaceOptimizer) a.m_SOOptimizers[i].clone(); } } - this.m_MigrationRate = a.m_MigrationRate; - this.m_Population = (Population)a.m_Population.clone(); + this.m_MigrationRate = a.m_MigrationRate; + this.m_Population = (Population) a.m_Population.clone(); } @Override @@ -61,18 +58,18 @@ public class WingedMultiObjectiveEA implements InterfaceOptimizer, java.io.Seria @Override public void init() { if (this.m_Problem instanceof AbstractMultiObjectiveOptimizationProblem) { - AbstractMultiObjectiveOptimizationProblem tmpProb = (AbstractMultiObjectiveOptimizationProblem)this.m_Problem; - AbstractMultiObjectiveOptimizationProblem tmpP; - MOSOWeightedFitness tmpWF; - PropertyDoubleArray tmpDA; - int dim = this.m_OutputDimension; - double[] weights; + AbstractMultiObjectiveOptimizationProblem tmpProb = (AbstractMultiObjectiveOptimizationProblem) this.m_Problem; + AbstractMultiObjectiveOptimizationProblem tmpP; + MOSOWeightedFitness tmpWF; + PropertyDoubleArray tmpDA; + int dim = this.m_OutputDimension; + double[] weights; // dim = tmpProb.getOutputDimension(); - this.m_MOOptimizer.setProblem((InterfaceOptimizationProblem)this.m_Problem.clone()); + this.m_MOOptimizer.setProblem((InterfaceOptimizationProblem) this.m_Problem.clone()); this.m_MOOptimizer.init(); this.m_SOOptimizers = new InterfaceOptimizer[dim]; for (int i = 0; i < dim; i++) { - tmpP = (AbstractMultiObjectiveOptimizationProblem)this.m_Problem.clone(); + tmpP = (AbstractMultiObjectiveOptimizationProblem) this.m_Problem.clone(); weights = new double[dim]; for (int j = 0; j < dim; j++) { weights[j] = 0; @@ -82,7 +79,7 @@ public class WingedMultiObjectiveEA implements InterfaceOptimizer, java.io.Seria tmpWF = new MOSOWeightedFitness(); tmpWF.setWeights(tmpDA); tmpP.setMOSOConverter(tmpWF); - this.m_SOOptimizers[i] = (InterfaceOptimizer)this.m_SOOptimizer.clone(); + this.m_SOOptimizers[i] = (InterfaceOptimizer) this.m_SOOptimizer.clone(); this.m_SOOptimizers[i].setProblem(tmpP); this.m_SOOptimizers[i].init(); } @@ -94,26 +91,27 @@ public class WingedMultiObjectiveEA implements InterfaceOptimizer, java.io.Seria this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - - /** This method will init the optimizer with a given population - * @param pop The initial population - * @param reset If true the population is reset. + /** + * This method will init the optimizer with a given population + * + * @param pop The initial population + * @param reset If true the population is reset. */ @Override public void initByPopulation(Population pop, boolean reset) { if (this.m_Problem instanceof AbstractMultiObjectiveOptimizationProblem) { - AbstractMultiObjectiveOptimizationProblem tmpProb = (AbstractMultiObjectiveOptimizationProblem)this.m_Problem; - AbstractMultiObjectiveOptimizationProblem tmpP; - MOSOWeightedFitness tmpWF; - PropertyDoubleArray tmpDA; - int dim = 2; - double[] weights; + AbstractMultiObjectiveOptimizationProblem tmpProb = (AbstractMultiObjectiveOptimizationProblem) this.m_Problem; + AbstractMultiObjectiveOptimizationProblem tmpP; + MOSOWeightedFitness tmpWF; + PropertyDoubleArray tmpDA; + int dim = 2; + double[] weights; // dim = tmpProb.getOutputDimension(); - this.m_MOOptimizer.setProblem((InterfaceOptimizationProblem)this.m_Problem.clone()); + this.m_MOOptimizer.setProblem((InterfaceOptimizationProblem) this.m_Problem.clone()); this.m_MOOptimizer.initByPopulation(pop, reset); this.m_SOOptimizers = new InterfaceOptimizer[dim]; for (int i = 0; i < dim; i++) { - tmpP = (AbstractMultiObjectiveOptimizationProblem)this.m_Problem.clone(); + tmpP = (AbstractMultiObjectiveOptimizationProblem) this.m_Problem.clone(); weights = new double[dim]; for (int j = 0; j < dim; j++) { weights[j] = 0; @@ -123,7 +121,7 @@ public class WingedMultiObjectiveEA implements InterfaceOptimizer, java.io.Seria tmpWF = new MOSOWeightedFitness(); tmpWF.setWeights(tmpDA); tmpP.setMOSOConverter(tmpWF); - this.m_SOOptimizers[i] = (InterfaceOptimizer)this.m_SOOptimizer.clone(); + this.m_SOOptimizers[i] = (InterfaceOptimizer) this.m_SOOptimizer.clone(); this.m_SOOptimizers[i].setProblem(tmpP); this.m_SOOptimizers[i].initByPopulation(pop, reset); } @@ -135,7 +133,8 @@ public class WingedMultiObjectiveEA implements InterfaceOptimizer, java.io.Seria this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** The optimize method will compute a 'improved' and evaluated population + /** + * The optimize method will compute a 'improved' and evaluated population */ @Override public void optimize() { @@ -154,8 +153,8 @@ public class WingedMultiObjectiveEA implements InterfaceOptimizer, java.io.Seria this.firePropertyChangedEvent(Population.nextGenerationPerformed); } - /** This method will manage comunication between the - * islands + /** + * This method will manage comunication between the islands */ private void communicate() { int oldFunctionCalls; @@ -163,11 +162,11 @@ public class WingedMultiObjectiveEA implements InterfaceOptimizer, java.io.Seria this.m_Population.SetFunctionCalls(0); Population pop; // first collect all the data - pop = (Population)this.m_MOOptimizer.getPopulation().clone(); + pop = (Population) this.m_MOOptimizer.getPopulation().clone(); this.m_Population.addPopulation(pop); this.m_Population.incrFunctionCallsBy(pop.getFunctionCalls()); for (int i = 0; i < this.m_SOOptimizers.length; i++) { - pop = (Population)this.m_SOOptimizers[i].getPopulation().clone(); + pop = (Population) this.m_SOOptimizers[i].getPopulation().clone(); this.m_Population.addPopulation(pop); this.m_Population.incrFunctionCallsBy(pop.getFunctionCalls()); } @@ -180,75 +179,86 @@ public class WingedMultiObjectiveEA implements InterfaceOptimizer, java.io.Seria this.migrate(); } - /** This method implements the migration between the optimzers + /** + * This method implements the migration between the optimzers * */ private void migrate() { AbstractEAIndividual[] bestIndys = new AbstractEAIndividual[this.m_OutputDimension]; - double tmpF1, tmpF2; + double tmpF1, tmpF2; // for each dimension find the best for (int i = 0; i < this.m_OutputDimension; i++) { - bestIndys[i] = (AbstractEAIndividual)((AbstractEAIndividual)this.m_Population.get(0)).clone(); + bestIndys[i] = (AbstractEAIndividual) ((AbstractEAIndividual) this.m_Population.get(0)).clone(); tmpF1 = bestIndys[i].getFitness(i); // for each individual find the best for (int j = 0; j < this.m_Population.size(); j++) { - if (((AbstractEAIndividual)this.m_Population.get(j)).getFitness(i) < tmpF1) { - bestIndys[i] = (AbstractEAIndividual)((AbstractEAIndividual)this.m_Population.get(j)).clone(); - tmpF1 = bestIndys[i].getFitness(i); - } + if (((AbstractEAIndividual) this.m_Population.get(j)).getFitness(i) < tmpF1) { + bestIndys[i] = (AbstractEAIndividual) ((AbstractEAIndividual) this.m_Population.get(j)).clone(); + tmpF1 = bestIndys[i].getFitness(i); + } } } // now perform the migration AbstractEAIndividual tmpIndy; for (int i = 0; i < this.m_OutputDimension; i++) { - tmpIndy = (AbstractEAIndividual)bestIndys[i].clone(); + tmpIndy = (AbstractEAIndividual) bestIndys[i].clone(); this.m_MOOptimizer.getProblem().evaluate(tmpIndy); this.m_MOOptimizer.getPopulation().set(i, tmpIndy); - tmpIndy = (AbstractEAIndividual)bestIndys[i].clone(); + tmpIndy = (AbstractEAIndividual) bestIndys[i].clone(); this.m_SOOptimizers[i].getProblem().evaluate(tmpIndy); this.m_SOOptimizers[i].getPopulation().set(0, bestIndys[i]); } } - /** This method allows you to add the LectureGUI as listener to the Optimizer + /** + * This method allows you to add the LectureGUI as listener to the Optimizer + * * @param ea */ @Override public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { this.m_Listener = ea; } + @Override - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else { - return false; - } - } - /** Something has changed + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } + + /** + * Something has changed */ - protected void firePropertyChangedEvent (String name) { + protected void firePropertyChangedEvent(String name) { if (this.m_Listener != null) { this.m_Listener.registerPopulationStateChanged(this, name); } } - /** This method will set the problem that is to be optimized + /** + * This method will set the problem that is to be optimized + * * @param problem */ @Override - public void setProblem (InterfaceOptimizationProblem problem) { + public void setProblem(InterfaceOptimizationProblem problem) { this.m_Problem = problem; } + @Override - public InterfaceOptimizationProblem getProblem () { + public InterfaceOptimizationProblem getProblem() { return this.m_Problem; } - /** This method will return a string describing all properties of the optimizer - * and the applied methods. + /** + * This method will return a string describing all properties of the + * optimizer and the applied methods. + * * @return A descriptive string */ @Override @@ -256,39 +266,42 @@ public class WingedMultiObjectiveEA implements InterfaceOptimizer, java.io.Seria String result = ""; result += "EMO:\n"; result += "Optimization Problem: "; - result += this.m_Problem.getStringRepresentationForProblem(this) +"\n"; + result += this.m_Problem.getStringRepresentationForProblem(this) + "\n"; result += this.m_Population.getStringRepresentation(); return result; } - /** This method allows you to set an identifier for the algorithm - * @param name The indenifier + + /** + * This method allows you to set an identifier for the algorithm + * + * @param name The indenifier */ @Override - public void setIdentifier(String name) { + public void setIdentifier(String name) { this.m_Identifier = name; } - @Override - public String getIdentifier() { - return this.m_Identifier; - } - /** This method is required to free the memory on a RMIServer, - * but there is nothing to implement. - */ @Override - public void freeWilly() { - + public String getIdentifier() { + return this.m_Identifier; } -/********************************************************************************************************************** - * These are for GUI - */ - /** This method returns a global info string + + /** + * ******************************************************************************************************************** + * These are for GUI + */ + /** + * This method returns a global info string + * * @return description */ public static String globalInfo() { return "This is Evolutionary Multi-Criteria Optimization Algorithm hybridized with Local Searchers to span the Pareto-Front."; } - /** This method will return a naming String + + /** + * This method will return a naming String + * * @return The name of the algorithm */ @Override @@ -296,62 +309,79 @@ public class WingedMultiObjectiveEA implements InterfaceOptimizer, java.io.Seria return "EMO-LS"; } - /** Assuming that all optimizer will store their data in a population - * we will allow access to this population to query to current state - * of the optimizer. + /** + * Assuming that all optimizer will store their data in a population we will + * allow access to this population to query to current state of the + * optimizer. + * * @return The population of current solutions to a given problem. */ @Override public Population getPopulation() { return this.m_Population; } + @Override - public void setPopulation(Population pop){ + public void setPopulation(Population pop) { this.m_Population = pop; } + public String populationTipText() { return "(Defunct)"; } - + @Override public InterfaceSolutionSet getAllSolutions() { - return new SolutionSet(getPopulation()); + return new SolutionSet(getPopulation()); } - /** This method allows you to set/get the optimizing technique to use. + + /** + * This method allows you to set/get the optimizing technique to use. + * * @return The current optimizing method */ public InterfaceOptimizer getMOOptimizer() { return this.m_MOOptimizer; } - public void setMOOptimizer(InterfaceOptimizer b){ + + public void setMOOptimizer(InterfaceOptimizer b) { this.m_MOOptimizer = b; } + public String mOOptimizerTipText() { return "Choose a population based optimizing technique to use."; } - /** This method allows you to set/get the optimizing technique to use. + /** + * This method allows you to set/get the optimizing technique to use. + * * @return The current optimizing method */ public InterfaceOptimizer getSOOptimizer() { return this.m_SOOptimizer; } - public void setSOOptimizer(InterfaceOptimizer b){ + + public void setSOOptimizer(InterfaceOptimizer b) { this.m_SOOptimizer = b; } + public String sOOptimizerTipText() { return "Choose a population based optimizing technique to use."; } - /** This method allows you to set/get the archiving strategy to use. + /** + * This method allows you to set/get the archiving strategy to use. + * * @return The current optimizing method */ public int getMigrationRate() { return this.m_MigrationRate; } - public void setMigrationRate(int b){ + + public void setMigrationRate(int b) { this.m_MigrationRate = b; } + public String migrationRateTipText() { return "Choose a proper migration rate."; }