From 83cd026722fc497d724efb0e3222d0fef1b01607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Dr=C3=A4ger?= Date: Wed, 26 Mar 2008 16:05:37 +0000 Subject: [PATCH] OptimizerFactory now contains several new methods. --- src/javaeva/OptimizerFactory.java | 1154 +++++++++++------ .../crossover/CrossoverGADefault.java | 216 +-- .../go/strategies/MemeticAlgorithm.java | 616 +++++---- 3 files changed, 1214 insertions(+), 772 deletions(-) diff --git a/src/javaeva/OptimizerFactory.java b/src/javaeva/OptimizerFactory.java index 48b8de41..97176811 100644 --- a/src/javaeva/OptimizerFactory.java +++ b/src/javaeva/OptimizerFactory.java @@ -5,6 +5,7 @@ import java.util.Vector; import javaeva.gui.BeanInspector; import javaeva.server.go.IndividualInterface; +import javaeva.server.go.InterfacePopulationChangedEventListener; import javaeva.server.go.InterfaceTerminator; import javaeva.server.go.individuals.AbstractEAIndividual; import javaeva.server.go.individuals.InterfaceDataTypeBinary; @@ -12,10 +13,16 @@ import javaeva.server.go.individuals.InterfaceDataTypeDouble; import javaeva.server.go.individuals.InterfaceESIndividual; import javaeva.server.go.operators.cluster.ClusteringDensityBased; import javaeva.server.go.operators.crossover.CrossoverESDefault; +import javaeva.server.go.operators.crossover.InterfaceCrossover; +import javaeva.server.go.operators.crossover.NoCrossover; +import javaeva.server.go.operators.mutation.InterfaceMutation; import javaeva.server.go.operators.mutation.MutateESCovarianceMartixAdaption; +import javaeva.server.go.operators.mutation.MutateESFixedStepSize; import javaeva.server.go.operators.mutation.MutateESGlobal; +import javaeva.server.go.operators.mutation.NoMutation; import javaeva.server.go.operators.postprocess.InterfacePostProcessParams; import javaeva.server.go.operators.postprocess.PostProcessParams; +import javaeva.server.go.operators.selection.InterfaceSelection; import javaeva.server.go.operators.terminators.CombinedTerminator; import javaeva.server.go.operators.terminators.EvaluationTerminator; import javaeva.server.go.operators.terminators.FitnessConvergenceTerminator; @@ -26,18 +33,21 @@ import javaeva.server.go.strategies.ClusteringHillClimbing; import javaeva.server.go.strategies.DifferentialEvolution; import javaeva.server.go.strategies.EvolutionStrategies; import javaeva.server.go.strategies.GeneticAlgorithm; +import javaeva.server.go.strategies.GradientDescentAlgorithm; import javaeva.server.go.strategies.HillClimbing; import javaeva.server.go.strategies.InterfaceOptimizer; import javaeva.server.go.strategies.MonteCarloSearch; import javaeva.server.go.strategies.ParticleSwarmOptimization; +import javaeva.server.go.strategies.SimulatedAnnealing; import javaeva.server.go.strategies.Tribes; import javaeva.server.modules.GOParameters; +import javaeva.tools.SelectedTag; /** * The OptimizerFactory allows quickly creating some optimizers without thinking much * about parameters. You can access a runnable Optimization thread and directly start it, * or access its fully prepared GOParameter instance, change some parameters, and start it then. - * + * * @author mkron * */ @@ -53,307 +63,32 @@ public class OptimizerFactory { public final static int HILLCL = 8; public final static int CBN_ES = 9; public final static int CL_HILLCL = 10; - + public final static int defaultFitCalls = 10000; public final static int randSeed = 0; - + private static OptimizerRunnable lastRunnable = null; - + /** - * Return a simple String showing the accessible optimizers. For external access." - * - * @return a String listing the accessible optimizers + * The topologies for the PSO algorithm. Contains + * */ - public static String showOptimizers() { - return "1: Standard ES \n2: CMA-ES \n3: GA \n4: PSO \n5: DE \n6: Tribes \n7: Random (Monte Carlo) " + - "\n8: Hill-Climbing \n9: Cluster-based niching ES \n10: Clustering Hill-Climbing"; - } - - /** - * The default Terminator finishes after n fitness calls, the default n is returned here. - * @return the default number of fitness call done before termination - */ - public static int getDefaultFitCalls() { - return defaultFitCalls; - } - - /** - * Create a runnable optimization Runnable and directly start it in an own thread. The Runnable - * will notify waiting threads and set the isFinished flag when the optimization is complete. - * If the optType is invalid, null will be returned. - * - * @param optType - * @param problem - * @param outputFilePrefix - * @return - */ - public static OptimizerRunnable optimizeInThread(final int optType, AbstractOptimizationProblem problem, String outputFilePrefix) { - OptimizerRunnable runnable = getOptRunnable(optType, problem, outputFilePrefix); - if (runnable != null) new Thread(runnable).start(); - return runnable; - } - - // TODO hier weiter kommentieren - public static OptimizerRunnable optimize(final int optType, AbstractOptimizationProblem problem, String outputFilePrefix) { - return optimize(getOptRunnable(optType, problem, outputFilePrefix)); - } - - public static OptimizerRunnable optimize(OptimizerRunnable runnable) { - if (runnable != null) { - new Thread(runnable).run(); - lastRunnable = runnable; - return runnable; - } else return null; - } - - public static String terminatedBecause() { - if (lastRunnable != null) return lastRunnable.terminatedBecause(); - else return null; - } - - public static int lastEvalsPerformed() { - if (lastRunnable != null) return lastRunnable.getProgress(); - else return -1; - } - -/////////////////////////////// Optimize a given parameter instance - public static BitSet optimizeToBinary(GOParameters params, String outputFilePrefix) { - OptimizerRunnable runnable = optimize(new OptimizerRunnable(params, outputFilePrefix)); - return runnable.getBinarySolution(); - } - - public static double[] optimizeToDouble(GOParameters params, String outputFilePrefix) { - OptimizerRunnable runnable = optimize(new OptimizerRunnable(params, outputFilePrefix)); - return runnable.getDoubleSolution(); - } - - public static IndividualInterface optimizeToInd(GOParameters params, String outputFilePrefix) { - OptimizerRunnable runnable = optimize(new OptimizerRunnable(params, outputFilePrefix)); - return runnable.getResult(); - } - - public static Population optimizeToPop(GOParameters params, String outputFilePrefix) { - OptimizerRunnable runnable = optimize(new OptimizerRunnable(params, outputFilePrefix)); - return runnable.getSolutionSet(); - } - -/////////////////////////////// Optimize a given runnable - public static BitSet optimizeToBinary(OptimizerRunnable runnable) { - optimize(runnable); - if (runnable != null) return runnable.getBinarySolution(); - else return null; - } - - public static double[] optimizeToDouble(OptimizerRunnable runnable) { - optimize(runnable); - if (runnable != null) return runnable.getDoubleSolution(); - else return null; - } - - public static IndividualInterface optimizeToInd(OptimizerRunnable runnable) { - optimize(runnable); - if (runnable != null) return runnable.getResult(); - else return null; - } - - public static Population optimizeToPop(OptimizerRunnable runnable) { - optimize(runnable); - if (runnable != null) return runnable.getSolutionSet(); - else return null; - } - -/////////////////////////////// Optimize using a default strategy - public static BitSet optimizeToBinary(final int optType, AbstractOptimizationProblem problem, String outputFilePrefix) { - OptimizerRunnable runnable = optimize(optType, problem, outputFilePrefix); - if (runnable != null) return runnable.getBinarySolution(); - else return null; - } - - public static double[] optimizeToDouble(final int optType, AbstractOptimizationProblem problem, String outputFilePrefix) { - OptimizerRunnable runnable = optimize(optType, problem, outputFilePrefix); - if (runnable != null) return runnable.getDoubleSolution(); - else return null; - } - - public static IndividualInterface optimizeToInd(final int optType, AbstractOptimizationProblem problem, String outputFilePrefix) { - OptimizerRunnable runnable = optimize(optType, problem, outputFilePrefix); - if (runnable != null) return runnable.getResult(); - else return null; - } - - public static Population optimizeToPop(final int optType, AbstractOptimizationProblem problem, String outputFilePrefix) { - OptimizerRunnable runnable = optimize(optType, problem, outputFilePrefix); - if (runnable != null) return runnable.getSolutionSet(); - else return null; - } - -///////////////////////////// post processing - public static Vector postProcessIndVec(OptimizerRunnable runnable, int steps, double sigma, int nBest) { - return postProcessIndVec(runnable, new PostProcessParams(steps, sigma, nBest)); - } - - public static Vector postProcessIndVec(int steps, double sigma, int nBest) { - return (lastRunnable != null) ? postProcessIndVec(lastRunnable, new PostProcessParams(steps, sigma, nBest)) : null; - } - - public static Vector postProcessIndVec(InterfacePostProcessParams ppp) { - return (lastRunnable != null) ? postProcessIndVec(lastRunnable, ppp) : null; - } - - public static Vector postProcessIndVec(OptimizerRunnable runnable, InterfacePostProcessParams ppp) { - Population resPop = postProcess(runnable, ppp); - Vector ret = new Vector(resPop.size()); - for (Object o : resPop) { - if (o instanceof AbstractEAIndividual) { - AbstractEAIndividual indy = (AbstractEAIndividual)o; - ret.add(indy); - } - } - return ret; - } - - public static Vector postProcessBinVec(InterfacePostProcessParams ppp) { - return (lastRunnable != null) ? postProcessBinVec(lastRunnable, ppp) : null; - } - - public static Vector postProcessBinVec(OptimizerRunnable runnable, InterfacePostProcessParams ppp) { - Population resPop = postProcess(runnable, ppp); - Vector ret = new Vector(resPop.size()); - for (Object o : resPop) { - if (o instanceof InterfaceDataTypeBinary) { - InterfaceDataTypeBinary indy = (InterfaceDataTypeBinary)o; - ret.add(indy.getBinaryData()); - } - } - return ret; - } + public static SelectedTag topology = new SelectedTag("Linear", "Grid", + "Star", "Multi-Swarm", "Tree", "HPSO", + "Random"); - public static Vector postProcessBinVec(int steps, double sigma, int nBest) { - return (lastRunnable != null) ? postProcessBinVec(lastRunnable, new PostProcessParams(steps, sigma, nBest)) : null; - } - - public static Vector postProcessBinVec(OptimizerRunnable runnable, int steps, double sigma, int nBest) { - return postProcessBinVec(runnable, new PostProcessParams(steps, sigma, nBest)); - } - - public static Vector postProcessDblVec(InterfacePostProcessParams ppp) { - if (lastRunnable != null) return postProcessDblVec(lastRunnable, ppp); - else return null; - } - - public static Vector postProcessDblVec(OptimizerRunnable runnable, InterfacePostProcessParams ppp) { - Population resPop = postProcess(runnable, ppp); - Vector ret = new Vector(resPop.size()); - for (Object o : resPop) { - if (o instanceof InterfaceDataTypeDouble) { - InterfaceDataTypeDouble indy = (InterfaceDataTypeDouble)o; - ret.add(indy.getDoubleData()); - } - } - return ret; - } - - public static Vector postProcessDblVec(int steps, double sigma, int nBest) { - return (lastRunnable == null) ? null : postProcessDblVec(lastRunnable, new PostProcessParams(steps, sigma, nBest)); - } - - public static Vector postProcessDblVec(OptimizerRunnable runnable, int steps, double sigma, int nBest) { - return postProcessDblVec(runnable, new PostProcessParams(steps, sigma, nBest)); - } - - public static Population postProcess(int steps, double sigma, int nBest) { - return (lastRunnable == null) ? null : postProcess(lastRunnable, new PostProcessParams(steps, sigma, nBest)); - } - - public static Population postProcess(OptimizerRunnable runnable, int steps, double sigma, int nBest) { - PostProcessParams ppp = new PostProcessParams(steps, sigma, nBest); - return postProcess(runnable, ppp); - } - - public static Population postProcess(InterfacePostProcessParams ppp) { - return (lastRunnable == null) ? null : postProcess(lastRunnable, ppp); - } - - public static Population postProcess(OptimizerRunnable runnable, InterfacePostProcessParams ppp) { - runnable.setDoRestart(true); - runnable.setDoPostProcessOnly(true); - runnable.setPostProcessingParams(ppp); - runnable.run(); // this run will not set the lastRunnable - postProcessing starts always anew - return runnable.getSolutionSet(); - } - -///////////////////////////// constructing a default OptimizerRunnable - public static OptimizerRunnable getOptRunnable(final int optType, AbstractOptimizationProblem problem, String outputFilePrefix) { - return getOptRunnable(optType, problem, defaultFitCalls, outputFilePrefix); - } - - public static OptimizerRunnable getOptRunnable(final int optType, AbstractOptimizationProblem problem, int fitCalls, String outputFilePrefix) { - OptimizerRunnable opt = null; - switch (optType) { - case STD_ES: - opt = new OptimizerRunnable(standardES(problem), outputFilePrefix); - break; - case CMA_ES: - opt = new OptimizerRunnable(cmaES(problem), outputFilePrefix); - break; - case STD_GA: - opt = new OptimizerRunnable(standardGA(problem), outputFilePrefix); - break; - case PSO: - opt = new OptimizerRunnable(standardPSO(problem), outputFilePrefix); - break; - case DE: - opt = new OptimizerRunnable(standardDE(problem), outputFilePrefix); - break; - case TRIBES: - opt = new OptimizerRunnable(tribes(problem), outputFilePrefix); - break; - case RANDOM: - opt = new OptimizerRunnable(monteCarlo(problem), outputFilePrefix); - break; - case HILLCL: - opt = new OptimizerRunnable(hillClimbing(problem), outputFilePrefix); - break; - case CBN_ES: - opt = new OptimizerRunnable(cbnES(problem), outputFilePrefix); - break; - case CL_HILLCL: - opt = new OptimizerRunnable(clusteringHillClimbing(problem), outputFilePrefix); - break; - default: - System.err.println("Error: optimizer type " + optType + " is unknown!"); - return null; - } - if (fitCalls != defaultFitCalls) opt.getGOParams().setTerminator(new EvaluationTerminator(fitCalls)); - return opt; - } - -///////////////////////////// Termination criteria - public static InterfaceTerminator defaultTerminator() { - if (term == null) term = new EvaluationTerminator(defaultFitCalls); - return term; - } - - public static void setEvaluationTerminator(int maxEvals) { - setTerminator(new EvaluationTerminator(maxEvals)); - } - - public static void setFitnessConvergenceTerminator(double fitThresh) { - setTerminator(new FitnessConvergenceTerminator(fitThresh, 100, true, true)); - } - - public static void setTerminator(InterfaceTerminator term) { - OptimizerFactory.term = term; - } - - public static InterfaceTerminator getTerminator() { - return OptimizerFactory.term; - } - /** * Add an InterfaceTerminator to any new optimizer in a boolean combination. The old and the given * terminator will be combined as in (TOld && TNew) if bAnd is true, and as in (TOld || TNew) if bAnd - * is false. + * is false. * @param newTerm a new InterfaceTerminator instance * @param bAnd indicate the boolean combination */ @@ -361,127 +96,7 @@ public class OptimizerFactory { if (OptimizerFactory.term == null) OptimizerFactory.term = term; else setTerminator(new CombinedTerminator(OptimizerFactory.term, newTerm, bAnd)); } - -///////////////////////// Creating default strategies - public static GOParameters makeParams(InterfaceOptimizer opt, Population pop, AbstractOptimizationProblem problem, long seed, InterfaceTerminator term) { - GOParameters params = new GOParameters(); - params.setProblem(problem); - opt.SetProblem(problem); - opt.setPopulation(pop); - params.setOptimizer(opt); - params.setTerminator(term); - params.setSeed(seed); - return params; - } - - public static GOParameters standardES(AbstractOptimizationProblem problem) { - EvolutionStrategies es = new EvolutionStrategies(); - es.setMu(15); - es.setLambda(50); - es.setPlusStrategy(false); - - AbstractEAIndividual indy = problem.getIndividualTemplate(); - - if ((indy != null) && (indy instanceof InterfaceESIndividual)) { - // Set CMA operator for mutation - indy.setMutationOperator(new MutateESGlobal()); - indy.setCrossoverOperator(new CrossoverESDefault()); - } else { - System.err.println("Error, standard ES is implemented for ES individuals only (requires double data types)"); - return null; - } - - Population pop = new Population(); - pop.setPopulationSize(es.getLambda()); - - return makeParams(es, pop, problem, randSeed, defaultTerminator()); - } - - public static GOParameters cmaES(AbstractOptimizationProblem problem) { - EvolutionStrategies es = new EvolutionStrategies(); - es.setMu(15); - es.setLambda(50); - es.setPlusStrategy(false); - - // TODO improve this by adding getEAIndividual to AbstractEAIndividual? - Object maybeTemplate = BeanInspector.callIfAvailable(problem, "getEAIndividual", null); - if ((maybeTemplate != null) && (maybeTemplate instanceof InterfaceESIndividual)) { - // Set CMA operator for mutation - AbstractEAIndividual indy = (AbstractEAIndividual)maybeTemplate; - MutateESCovarianceMartixAdaption cmaMut = new MutateESCovarianceMartixAdaption(); - cmaMut.setCheckConstraints(true); - indy.setMutationOperator(cmaMut); - indy.setCrossoverOperator(new CrossoverESDefault()); - } else { - System.err.println("Error, CMA-ES is implemented for ES individuals only (requires double data types)"); - return null; - } - - Population pop = new Population(); - pop.setPopulationSize(es.getLambda()); - - return makeParams(es, pop, problem, randSeed, defaultTerminator()); - } - - public static GOParameters standardPSO(AbstractOptimizationProblem problem) { - ParticleSwarmOptimization pso = new ParticleSwarmOptimization(); - Population pop = new Population(); - pop.setPopulationSize(30); - pso.setPopulation(pop); - pso.setPhiValues(2.05, 2.05); - pso.getTopology().setSelectedTag("Grid"); - return makeParams(pso, pop, problem, randSeed, defaultTerminator()); - } - - public static GOParameters standardDE(AbstractOptimizationProblem problem) { - DifferentialEvolution de = new DifferentialEvolution(); - Population pop = new Population(); - pop.setPopulationSize(50); - de.setPopulation(pop); - de.getDEType().setSelectedTag(1); // this sets current-to-best - de.setF(0.8); - de.setK(0.6); - de.setLambda(0.6); - de.setMt(0.05); - - return makeParams(de, pop, problem, randSeed, defaultTerminator()); - } - - public static GOParameters standardGA(AbstractOptimizationProblem problem) { - GeneticAlgorithm ga = new GeneticAlgorithm(); - Population pop = new Population(); - pop.setPopulationSize(100); - ga.setPopulation(pop); - ga.setElitism(true); - return makeParams(ga, pop, problem, randSeed, defaultTerminator()); - } - - public static GOParameters tribes(AbstractOptimizationProblem problem) { - Tribes tr = new Tribes(); - Population pop = new Population(); - pop.setPopulationSize(1); // only for init - problem.initPopulation(pop); - return makeParams(tr, pop, problem, randSeed, defaultTerminator()); - } - - public static GOParameters hillClimbing(AbstractOptimizationProblem problem) { - HillClimbing hc = new HillClimbing(); - hc.SetProblem(problem); - Population pop = new Population(); - pop.setPopulationSize(50); - problem.initPopulation(pop); - return makeParams(hc, pop, problem, randSeed, defaultTerminator()); - } - - public static GOParameters monteCarlo(AbstractOptimizationProblem problem) { - MonteCarloSearch mc = new MonteCarloSearch(); - Population pop = new Population(); - pop.setPopulationSize(50); - problem.initPopulation(pop); - return makeParams(mc, pop, problem, randSeed, defaultTerminator()); - } - public static GOParameters cbnES(AbstractOptimizationProblem problem) { ClusterBasedNichingEA cbn = new ClusterBasedNichingEA(); EvolutionStrategies es = new EvolutionStrategies(); @@ -493,14 +108,14 @@ public class OptimizerFactory { cbn.setConvergenceCA((ClusteringDensityBased)clustering.clone()); cbn.setDifferentationCA(clustering); cbn.setShowCycle(0); // dont do graphical output - + Population pop = new Population(); pop.setPopulationSize(100); problem.initPopulation(pop); - + return makeParams(cbn, pop, problem, randSeed, defaultTerminator()); } - + public static GOParameters clusteringHillClimbing(AbstractOptimizationProblem problem) { ClusteringHillClimbing chc = new ClusteringHillClimbing(); chc.SetProblem(problem); @@ -516,4 +131,711 @@ public class OptimizerFactory { chc.setSigmaClust(0.05); return makeParams(chc, pop, problem, randSeed, defaultTerminator()); } + + public static GOParameters cmaES(AbstractOptimizationProblem problem) { + EvolutionStrategies es = new EvolutionStrategies(); + es.setMu(15); + es.setLambda(50); + es.setPlusStrategy(false); + + // TODO improve this by adding getEAIndividual to AbstractEAIndividual? + Object maybeTemplate = BeanInspector.callIfAvailable(problem, "getEAIndividual", null); + if ((maybeTemplate != null) && (maybeTemplate instanceof InterfaceESIndividual)) { + // Set CMA operator for mutation + AbstractEAIndividual indy = (AbstractEAIndividual)maybeTemplate; + MutateESCovarianceMartixAdaption cmaMut = new MutateESCovarianceMartixAdaption(); + cmaMut.setCheckConstraints(true); + indy.setMutationOperator(cmaMut); + indy.setCrossoverOperator(new CrossoverESDefault()); + } else { + System.err.println("Error, CMA-ES is implemented for ES individuals only (requires double data types)"); + return null; + } + + Population pop = new Population(); + pop.setPopulationSize(es.getLambda()); + + return makeParams(es, pop, problem, randSeed, defaultTerminator()); + } + + /** + * This method optimizes the given problem using differential evolution. + * + * @param problem + * @param popsize + * @param f + * @param k + * @param lambda + * @param listener + * @return An optimization algorithm that performs differential evolution. + */ + public static final DifferentialEvolution createDifferentialEvolution( + AbstractOptimizationProblem problem, int popsize, double f, + double lambda, double k, InterfacePopulationChangedEventListener listener) { + + problem.initProblem(); + + AbstractEAIndividual tmpIndi = problem.getIndividualTemplate(); + tmpIndi.setCrossoverOperator(new NoCrossover()); + tmpIndi.setCrossoverProbability(0.0); + tmpIndi.setMutationOperator(new NoMutation()); + tmpIndi.setMutationProbability(0.0); + + DifferentialEvolution de = new DifferentialEvolution(); + de.SetProblem(problem); + de.getPopulation().setPopulationSize(popsize); + de.getDEType().setSelectedTag(1); + de.setF(f); + de.setK(k); + de.setLambda(lambda); + de.addPopulationChangedEventListener(listener); + de.init(); + + listener.registerPopulationStateChanged(de.getPopulation(), ""); + + return de; + } + + /** + * This method performs the optimization using an Evolution strategy. + * + * @param mu + * @param lambda + * @param plus + * @param mutationoperator + * @param pm + * @param crossoveroperator + * @param pc + * @param selection + * @param problem + * @param listener + * @return An optimization algorithm that employes an evolution strategy. + */ + public static final EvolutionStrategies createEvolutionStrategy(int mu, + int lambda, boolean plus, InterfaceMutation mutationoperator, double pm, + InterfaceCrossover crossoveroperator, double pc, + InterfaceSelection selection, AbstractOptimizationProblem problem, + InterfacePopulationChangedEventListener listener) { + + problem.initProblem(); + // RandomNumberGenerator.setRandomSeed(100); + + AbstractEAIndividual tmpIndi = problem.getIndividualTemplate(); + tmpIndi.setMutationOperator(mutationoperator); + tmpIndi.setMutationProbability(pm);// */ // 1/tmpIndi.size() + tmpIndi.setCrossoverOperator(crossoveroperator); + tmpIndi.setCrossoverProbability(pc);// */ // 0.95 + + EvolutionStrategies es = new EvolutionStrategies(); + es.addPopulationChangedEventListener(listener); + es.setParentSelection(selection); + es.setPartnerSelection(selection); + es.setEnvironmentSelection(selection); + es.setGenerationStrategy(mu, lambda, plus); // comma strategy + es.SetProblem(problem); + es.init(); + + listener.registerPopulationStateChanged(es.getPopulation(), ""); + + return es; + } + +/** + * This method performs a Genetic Algorithm. + * + * @param mut + * @param pm + * @param cross + * @param pc + * @param select + * @param popsize + * @param problem + * @param listener + * @return An optimization algorithm that employes an genetic algorithm. + */ + public static final GeneticAlgorithm createGeneticAlgorithm( + InterfaceMutation mut, double pm, InterfaceCrossover cross, double pc, + InterfaceSelection select, int popsize, + AbstractOptimizationProblem problem, + InterfacePopulationChangedEventListener listener) { + + problem.initProblem(); + + AbstractEAIndividual tmpIndi = problem.getIndividualTemplate(); + tmpIndi.setCrossoverOperator(cross); + tmpIndi.setCrossoverProbability(pc); + tmpIndi.setMutationOperator(mut); + tmpIndi.setMutationProbability(pm); + + GeneticAlgorithm ga = new GeneticAlgorithm(); + ga.SetProblem(problem); + ga.getPopulation().setPopulationSize(popsize); + ga.setParentSelection(select); + ga.setPartnerSelection(select); + ga.addPopulationChangedEventListener(listener); + ga.init(); + + listener.registerPopulationStateChanged(ga.getPopulation(), ""); + + return ga; + } + + /** + * This starts a Gradient Descent. + * + * @param problem + * @return An optimization algorithm that performs gradient descent. + */ + public static final GradientDescentAlgorithm createGradientDescent( + AbstractOptimizationProblem problem) { + + System.err.println("Currently not implemented!"); + + problem.initProblem(); + + AbstractEAIndividual tmpIndi = problem.getIndividualTemplate(); + tmpIndi.setCrossoverOperator(new NoCrossover()); + tmpIndi.setCrossoverProbability(0.0); + + GradientDescentAlgorithm gd = new GradientDescentAlgorithm(); + + // TODO implement! + + return gd; + } + + /** + * This method performs a Hill Climber algorithm. + * + * @param pop + * The size of the population + * @param problem + * The problem to be optimized + * @param listener + * @return An optimization procedure that performes hill climbing. + */ + public static final HillClimbing createHillClimber(int pop, + AbstractOptimizationProblem problem, + InterfacePopulationChangedEventListener listener) { + + problem.initProblem(); + + MutateESFixedStepSize mutator = new MutateESFixedStepSize(); + mutator.setSigma(0.2); // mutations step size + AbstractEAIndividual tmpIndi = problem.getIndividualTemplate(); + tmpIndi.setMutationOperator(mutator); + tmpIndi.setMutationProbability(1.0); + tmpIndi.setCrossoverOperator(new NoCrossover()); + tmpIndi.setCrossoverProbability(0); + + HillClimbing hc = new HillClimbing(); + // System.out.println(hc.getStringRepresentation()); + hc.getPopulation().setPopulationSize(pop); + hc.addPopulationChangedEventListener(listener); + hc.SetProblem(problem); + hc.init(); + + listener.registerPopulationStateChanged(hc.getPopulation(), ""); + + return hc; + } + +/** + * This method performs a Monte Carlo Search with the given number of + * fitnesscalls. + * + * @param problem + * @param listener + * @return An optimization procedure that performes the random walk. + */ + public static final MonteCarloSearch createMonteCarlo( + AbstractOptimizationProblem problem, + InterfacePopulationChangedEventListener listener) { + problem.initProblem(); + + AbstractEAIndividual tmpIndi = problem.getIndividualTemplate(); + tmpIndi.setMutationOperator(new NoMutation()); + tmpIndi.setMutationProbability(0); + tmpIndi.setCrossoverOperator(new NoCrossover()); + tmpIndi.setCrossoverProbability(0); + + MonteCarloSearch mc = new MonteCarloSearch(); + mc.addPopulationChangedEventListener(listener); + mc.SetProblem(problem); + mc.init(); + + listener.registerPopulationStateChanged(mc.getPopulation(), ""); + + return mc; + } + + /** + * This method performs a particle swarm optimization. + * + * @param problem + * @param mut + * @param popsize + * @param phi1 + * @param phi2 + * @param k + * @param listener + * @param topology + * @return An optimization algorithm that performs particle swarm + * optimization. + */ + public static final ParticleSwarmOptimization createParticleSwarmOptimization( + AbstractOptimizationProblem problem, int popsize, double phi1, + double phi2, double k, InterfacePopulationChangedEventListener listener, + int selectedTopology) { + + problem.initProblem(); + + AbstractEAIndividual tmpIndi = problem.getIndividualTemplate(); + tmpIndi.setCrossoverOperator(new NoCrossover()); + tmpIndi.setCrossoverProbability(0.0); + tmpIndi.setMutationOperator(new NoMutation()); + tmpIndi.setMutationProbability(0.0); + + ParticleSwarmOptimization pso = new ParticleSwarmOptimization(); + pso.SetProblem(problem); + pso.getPopulation().setPopulationSize(popsize); + pso.setPhi1(phi1); + pso.setPhi2(phi2); + pso.setSpeedLimit(k); + topology.setSelectedTag(selectedTopology); + pso.setTopology(topology); + pso.addPopulationChangedEventListener(listener); + pso.init(); + + listener.registerPopulationStateChanged(pso.getPopulation(), ""); + + return pso; + } + + /** + * This method performs a Simulated Annealing Optimization and prints the + * result as R output. It uses real valued individuals. The mutation + * probability is always 1.0. + * + * @param problem + * @param popsize + * @param alpha + * The parameter for the linear cooling + * @param temperature + * The initial temperature + * @param mut + * @param listener + * @return Returns an optimizer that performs simulated annealing. + */ + public static final SimulatedAnnealing createSimulatedAnnealing( + AbstractOptimizationProblem problem, int popsize, double alpha, + double temperature, InterfaceMutation mut, + InterfacePopulationChangedEventListener listener) { + + problem.initProblem(); + + AbstractEAIndividual tmpIndi = problem.getIndividualTemplate(); + tmpIndi.setCrossoverOperator(new NoCrossover()); + tmpIndi.setCrossoverProbability(0.0); + tmpIndi.setMutationOperator(mut); + tmpIndi.setMutationProbability(1.0); + + SimulatedAnnealing sa = new SimulatedAnnealing(); + sa.setAlpha(alpha); + sa.setInitialTemperature(temperature); + sa.SetProblem(problem); + sa.getPopulation().setPopulationSize(popsize); + sa.addPopulationChangedEventListener(listener); + sa.init(); + + listener.registerPopulationStateChanged(sa.getPopulation(), ""); + + return sa; + } + + ///////////////////////////// Termination criteria + public static InterfaceTerminator defaultTerminator() { + if (term == null) term = new EvaluationTerminator(defaultFitCalls); + return term; + } + +/** + * The default Terminator finishes after n fitness calls, the default n is returned here. + * @return the default number of fitness call done before termination + */ + public static int getDefaultFitCalls() { + return defaultFitCalls; + } + + public static OptimizerRunnable getOptRunnable(final int optType, AbstractOptimizationProblem problem, int fitCalls, String outputFilePrefix) { + OptimizerRunnable opt = null; + switch (optType) { + case STD_ES: + opt = new OptimizerRunnable(standardES(problem), outputFilePrefix); + break; + case CMA_ES: + opt = new OptimizerRunnable(cmaES(problem), outputFilePrefix); + break; + case STD_GA: + opt = new OptimizerRunnable(standardGA(problem), outputFilePrefix); + break; + case PSO: + opt = new OptimizerRunnable(standardPSO(problem), outputFilePrefix); + break; + case DE: + opt = new OptimizerRunnable(standardDE(problem), outputFilePrefix); + break; + case TRIBES: + opt = new OptimizerRunnable(tribes(problem), outputFilePrefix); + break; + case RANDOM: + opt = new OptimizerRunnable(monteCarlo(problem), outputFilePrefix); + break; + case HILLCL: + opt = new OptimizerRunnable(hillClimbing(problem), outputFilePrefix); + break; + case CBN_ES: + opt = new OptimizerRunnable(cbnES(problem), outputFilePrefix); + break; + case CL_HILLCL: + opt = new OptimizerRunnable(clusteringHillClimbing(problem), outputFilePrefix); + break; + default: + System.err.println("Error: optimizer type " + optType + " is unknown!"); + return null; + } + if (fitCalls != defaultFitCalls) opt.getGOParams().setTerminator(new EvaluationTerminator(fitCalls)); + return opt; + } + + ///////////////////////////// constructing a default OptimizerRunnable + public static OptimizerRunnable getOptRunnable(final int optType, AbstractOptimizationProblem problem, String outputFilePrefix) { + return getOptRunnable(optType, problem, defaultFitCalls, outputFilePrefix); + } + + public static InterfaceTerminator getTerminator() { + return OptimizerFactory.term; + } + +public static GOParameters hillClimbing(AbstractOptimizationProblem problem) { + HillClimbing hc = new HillClimbing(); + hc.SetProblem(problem); + Population pop = new Population(); + pop.setPopulationSize(50); + problem.initPopulation(pop); + return makeParams(hc, pop, problem, randSeed, defaultTerminator()); + } + + public static int lastEvalsPerformed() { + if (lastRunnable != null) return lastRunnable.getProgress(); + else return -1; + } + + ///////////////////////// Creating default strategies + public static GOParameters makeParams(InterfaceOptimizer opt, Population pop, AbstractOptimizationProblem problem, long seed, InterfaceTerminator term) { + GOParameters params = new GOParameters(); + params.setProblem(problem); + opt.SetProblem(problem); + opt.setPopulation(pop); + params.setOptimizer(opt); + params.setTerminator(term); + params.setSeed(seed); + return params; + } + + public static GOParameters monteCarlo(AbstractOptimizationProblem problem) { + MonteCarloSearch mc = new MonteCarloSearch(); + Population pop = new Population(); + pop.setPopulationSize(50); + problem.initPopulation(pop); + return makeParams(mc, pop, problem, randSeed, defaultTerminator()); + } + + // TODO hier weiter kommentieren + public static OptimizerRunnable optimize(final int optType, AbstractOptimizationProblem problem, String outputFilePrefix) { + return optimize(getOptRunnable(optType, problem, outputFilePrefix)); + } + + public static OptimizerRunnable optimize(OptimizerRunnable runnable) { + if (runnable != null) { + new Thread(runnable).run(); + lastRunnable = runnable; + return runnable; + } else return null; + } + + /** + * Create a runnable optimization Runnable and directly start it in an own thread. The Runnable + * will notify waiting threads and set the isFinished flag when the optimization is complete. + * If the optType is invalid, null will be returned. + * + * @param optType + * @param problem + * @param outputFilePrefix + * @return + */ + public static OptimizerRunnable optimizeInThread(final int optType, AbstractOptimizationProblem problem, String outputFilePrefix) { + OptimizerRunnable runnable = getOptRunnable(optType, problem, outputFilePrefix); + if (runnable != null) new Thread(runnable).start(); + return runnable; + } + + /////////////////////////////// Optimize a given parameter instance + public static BitSet optimizeToBinary(GOParameters params, String outputFilePrefix) { + OptimizerRunnable runnable = optimize(new OptimizerRunnable(params, outputFilePrefix)); + return runnable.getBinarySolution(); + } + + /////////////////////////////// Optimize using a default strategy + public static BitSet optimizeToBinary(final int optType, AbstractOptimizationProblem problem, String outputFilePrefix) { + OptimizerRunnable runnable = optimize(optType, problem, outputFilePrefix); + if (runnable != null) return runnable.getBinarySolution(); + else return null; + } + + /////////////////////////////// Optimize a given runnable + public static BitSet optimizeToBinary(OptimizerRunnable runnable) { + optimize(runnable); + if (runnable != null) return runnable.getBinarySolution(); + else return null; + } + + public static double[] optimizeToDouble(GOParameters params, String outputFilePrefix) { + OptimizerRunnable runnable = optimize(new OptimizerRunnable(params, outputFilePrefix)); + return runnable.getDoubleSolution(); + } + + public static double[] optimizeToDouble(final int optType, AbstractOptimizationProblem problem, String outputFilePrefix) { + OptimizerRunnable runnable = optimize(optType, problem, outputFilePrefix); + if (runnable != null) return runnable.getDoubleSolution(); + else return null; + } + + public static double[] optimizeToDouble(OptimizerRunnable runnable) { + optimize(runnable); + if (runnable != null) return runnable.getDoubleSolution(); + else return null; + } + + public static IndividualInterface optimizeToInd(GOParameters params, String outputFilePrefix) { + OptimizerRunnable runnable = optimize(new OptimizerRunnable(params, outputFilePrefix)); + return runnable.getResult(); + } + + public static IndividualInterface optimizeToInd(final int optType, AbstractOptimizationProblem problem, String outputFilePrefix) { + OptimizerRunnable runnable = optimize(optType, problem, outputFilePrefix); + if (runnable != null) return runnable.getResult(); + else return null; + } + + public static IndividualInterface optimizeToInd(OptimizerRunnable runnable) { + optimize(runnable); + if (runnable != null) return runnable.getResult(); + else return null; + } + +public static Population optimizeToPop(GOParameters params, String outputFilePrefix) { + OptimizerRunnable runnable = optimize(new OptimizerRunnable(params, outputFilePrefix)); + return runnable.getSolutionSet(); + } + + public static Population optimizeToPop(final int optType, AbstractOptimizationProblem problem, String outputFilePrefix) { + OptimizerRunnable runnable = optimize(optType, problem, outputFilePrefix); + if (runnable != null) return runnable.getSolutionSet(); + else return null; + } + +public static Population optimizeToPop(OptimizerRunnable runnable) { + optimize(runnable); + if (runnable != null) return runnable.getSolutionSet(); + else return null; + } + + public static Population postProcess(int steps, double sigma, int nBest) { + return (lastRunnable == null) ? null : postProcess(lastRunnable, new PostProcessParams(steps, sigma, nBest)); + } + + public static Population postProcess(InterfacePostProcessParams ppp) { + return (lastRunnable == null) ? null : postProcess(lastRunnable, ppp); + } + + public static Population postProcess(OptimizerRunnable runnable, int steps, double sigma, int nBest) { + PostProcessParams ppp = new PostProcessParams(steps, sigma, nBest); + return postProcess(runnable, ppp); + } + + public static Population postProcess(OptimizerRunnable runnable, InterfacePostProcessParams ppp) { + runnable.setDoRestart(true); + runnable.setDoPostProcessOnly(true); + runnable.setPostProcessingParams(ppp); + runnable.run(); // this run will not set the lastRunnable - postProcessing starts always anew + return runnable.getSolutionSet(); + } + + public static Vector postProcessBinVec(int steps, double sigma, int nBest) { + return (lastRunnable != null) ? postProcessBinVec(lastRunnable, new PostProcessParams(steps, sigma, nBest)) : null; + } + +public static Vector postProcessBinVec(InterfacePostProcessParams ppp) { + return (lastRunnable != null) ? postProcessBinVec(lastRunnable, ppp) : null; + } + + public static Vector postProcessBinVec(OptimizerRunnable runnable, int steps, double sigma, int nBest) { + return postProcessBinVec(runnable, new PostProcessParams(steps, sigma, nBest)); + } + + public static Vector postProcessBinVec(OptimizerRunnable runnable, InterfacePostProcessParams ppp) { + Population resPop = postProcess(runnable, ppp); + Vector ret = new Vector(resPop.size()); + for (Object o : resPop) { + if (o instanceof InterfaceDataTypeBinary) { + InterfaceDataTypeBinary indy = (InterfaceDataTypeBinary)o; + ret.add(indy.getBinaryData()); + } + } + return ret; + } + + public static Vector postProcessDblVec(int steps, double sigma, int nBest) { + return (lastRunnable == null) ? null : postProcessDblVec(lastRunnable, new PostProcessParams(steps, sigma, nBest)); + } + + public static Vector postProcessDblVec(InterfacePostProcessParams ppp) { + if (lastRunnable != null) return postProcessDblVec(lastRunnable, ppp); + else return null; + } + + public static Vector postProcessDblVec(OptimizerRunnable runnable, int steps, double sigma, int nBest) { + return postProcessDblVec(runnable, new PostProcessParams(steps, sigma, nBest)); + } + + public static Vector postProcessDblVec(OptimizerRunnable runnable, InterfacePostProcessParams ppp) { + Population resPop = postProcess(runnable, ppp); + Vector ret = new Vector(resPop.size()); + for (Object o : resPop) { + if (o instanceof InterfaceDataTypeDouble) { + InterfaceDataTypeDouble indy = (InterfaceDataTypeDouble)o; + ret.add(indy.getDoubleData()); + } + } + return ret; + } + + public static Vector postProcessIndVec(int steps, double sigma, int nBest) { + return (lastRunnable != null) ? postProcessIndVec(lastRunnable, new PostProcessParams(steps, sigma, nBest)) : null; + } + + public static Vector postProcessIndVec(InterfacePostProcessParams ppp) { + return (lastRunnable != null) ? postProcessIndVec(lastRunnable, ppp) : null; + } + + ///////////////////////////// post processing + public static Vector postProcessIndVec(OptimizerRunnable runnable, int steps, double sigma, int nBest) { + return postProcessIndVec(runnable, new PostProcessParams(steps, sigma, nBest)); + } + + public static Vector postProcessIndVec(OptimizerRunnable runnable, InterfacePostProcessParams ppp) { + Population resPop = postProcess(runnable, ppp); + Vector ret = new Vector(resPop.size()); + for (Object o : resPop) { + if (o instanceof AbstractEAIndividual) { + AbstractEAIndividual indy = (AbstractEAIndividual)o; + ret.add(indy); + } + } + return ret; + } + + + public static void setEvaluationTerminator(int maxEvals) { + setTerminator(new EvaluationTerminator(maxEvals)); + } + + public static void setFitnessConvergenceTerminator(double fitThresh) { + setTerminator(new FitnessConvergenceTerminator(fitThresh, 100, true, true)); + } + + public static void setTerminator(InterfaceTerminator term) { + OptimizerFactory.term = term; + } + + /** + * Return a simple String showing the accessible optimizers. For external access." + * + * @return a String listing the accessible optimizers + */ + public static String showOptimizers() { + return "1: Standard ES \n2: CMA-ES \n3: GA \n4: PSO \n5: DE \n6: Tribes \n7: Random (Monte Carlo) " + + "\n8: Hill-Climbing \n9: Cluster-based niching ES \n10: Clustering Hill-Climbing"; + } + + public static GOParameters standardDE(AbstractOptimizationProblem problem) { + DifferentialEvolution de = new DifferentialEvolution(); + Population pop = new Population(); + pop.setPopulationSize(50); + de.setPopulation(pop); + de.getDEType().setSelectedTag(1); // this sets current-to-best + de.setF(0.8); + de.setK(0.6); + de.setLambda(0.6); + de.setMt(0.05); + + return makeParams(de, pop, problem, randSeed, defaultTerminator()); + } + + public static GOParameters standardES(AbstractOptimizationProblem problem) { + EvolutionStrategies es = new EvolutionStrategies(); + es.setMu(15); + es.setLambda(50); + es.setPlusStrategy(false); + + AbstractEAIndividual indy = problem.getIndividualTemplate(); + + if ((indy != null) && (indy instanceof InterfaceESIndividual)) { + // Set CMA operator for mutation + indy.setMutationOperator(new MutateESGlobal()); + indy.setCrossoverOperator(new CrossoverESDefault()); + } else { + System.err.println("Error, standard ES is implemented for ES individuals only (requires double data types)"); + return null; + } + + Population pop = new Population(); + pop.setPopulationSize(es.getLambda()); + + return makeParams(es, pop, problem, randSeed, defaultTerminator()); + } + + public static GOParameters standardGA(AbstractOptimizationProblem problem) { + GeneticAlgorithm ga = new GeneticAlgorithm(); + Population pop = new Population(); + pop.setPopulationSize(100); + ga.setPopulation(pop); + ga.setElitism(true); + + return makeParams(ga, pop, problem, randSeed, defaultTerminator()); + } + + public static GOParameters standardPSO(AbstractOptimizationProblem problem) { + ParticleSwarmOptimization pso = new ParticleSwarmOptimization(); + Population pop = new Population(); + pop.setPopulationSize(30); + pso.setPopulation(pop); + pso.setPhiValues(2.05, 2.05); + pso.getTopology().setSelectedTag("Grid"); + return makeParams(pso, pop, problem, randSeed, defaultTerminator()); + } + + public static String terminatedBecause() { + if (lastRunnable != null) return lastRunnable.terminatedBecause(); + else return null; + } + + public static GOParameters tribes(AbstractOptimizationProblem problem) { + Tribes tr = new Tribes(); + Population pop = new Population(); + pop.setPopulationSize(1); // only for init + problem.initPopulation(pop); + return makeParams(tr, pop, problem, randSeed, defaultTerminator()); + } } diff --git a/src/javaeva/server/go/operators/crossover/CrossoverGADefault.java b/src/javaeva/server/go/operators/crossover/CrossoverGADefault.java index 75fc7438..3a54436d 100644 --- a/src/javaeva/server/go/operators/crossover/CrossoverGADefault.java +++ b/src/javaeva/server/go/operators/crossover/CrossoverGADefault.java @@ -9,102 +9,136 @@ import javaeva.server.go.tools.RandomNumberGenerator; import java.util.BitSet; /** - * Created by IntelliJ IDEA. - * User: streiche - * Date: 03.04.2003 - * Time: 10:34:17 - * To change this template use Options | File Templates. + * Created by IntelliJ IDEA. User: streiche Date: 03.04.2003 Time: 10:34:17 To + * change this template use Options | File Templates. */ -public class CrossoverGADefault implements InterfaceCrossover, java.io.Serializable { - private InterfaceOptimizationProblem m_OptimizationProblem; +public class CrossoverGADefault implements InterfaceCrossover, + java.io.Serializable { + private InterfaceOptimizationProblem m_OptimizationProblem; - public CrossoverGADefault() { + public CrossoverGADefault() { - } - public CrossoverGADefault(CrossoverGADefault c) { - this.m_OptimizationProblem = c.m_OptimizationProblem; - } - /** This method will enable you to clone a given mutation operator - * @return The clone - */ - public Object clone() { - return new CrossoverGADefault(this); - } + } - /** This method performs crossover on two individuals. If the individuals do - * not implement InterfaceGAIndividual, then nothing will happen. - * @param indy1 The first individual - * @param partners The second individual - */ - public AbstractEAIndividual[] mate(AbstractEAIndividual indy1, Population partners) { - AbstractEAIndividual[] result = null; - result = new AbstractEAIndividual[partners.size()+1]; - result[0] = (AbstractEAIndividual) (indy1).clone(); - for (int i = 0; i < partners.size(); i++) result[i+1] = (AbstractEAIndividual) ((AbstractEAIndividual)partners.get(i)).clone(); - //for (int i = 0; i < result.length; i++) System.out.println("Before Crossover: " +result[i].getSolutionRepresentationFor()); - if (partners.size() == 0) return result; - if ((indy1 instanceof InterfaceGAIndividual) && (partners.get(0) instanceof InterfaceGAIndividual)) { - // Currently we will only handle two parents - int crossoverpoint = RandomNumberGenerator.randomInt(0,((InterfaceGAIndividual)indy1).getGenotypeLength()-1); - boolean tmpValue; - BitSet[] tmpBitSets = new BitSet[2]; - tmpBitSets[0] = ((InterfaceGAIndividual)result[0]).getBGenotype(); - tmpBitSets[1] = ((InterfaceGAIndividual)result[1]).getBGenotype(); - for (int i = crossoverpoint; i < ((InterfaceGAIndividual)result[0]).getGenotypeLength(); i++) { - if (tmpBitSets[0].get(i)) tmpValue = true; - else tmpValue = false; - if (tmpBitSets[1].get(i)) tmpBitSets[0].set(i); - else tmpBitSets[0].clear(i); - if (tmpValue) tmpBitSets[1].set(i); - else tmpBitSets[1].clear(i); - } - ((InterfaceGAIndividual)result[0]).SetBGenotype(tmpBitSets[0]); - ((InterfaceGAIndividual)result[1]).SetBGenotype(tmpBitSets[1]); - } - //in case the crossover was successfull lets give the mutation operators a chance to mate the strategy parameters - for (int i = 0; i < result.length; i++) result[i].getMutationOperator().crossoverOnStrategyParameters(indy1, partners); - //for (int i = 0; i < result.length; i++) System.out.println("After Crossover: " +result[i].getSolutionRepresentationFor()); - return result; - } + public CrossoverGADefault(CrossoverGADefault c) { + this.m_OptimizationProblem = c.m_OptimizationProblem; + } - /** This method allows you to evaluate wether two crossover operators - * are actually the same. - * @param crossover The other crossover operator - */ - public boolean equals(Object crossover) { - if (crossover instanceof CrossoverGADefault) return true; - else return false; - } + /** + * This method will enable you to clone a given mutation operator + * + * @return The clone + */ + public Object clone() { + return new CrossoverGADefault(this); + } - /** This method will allow the crossover operator to be initialized depending on the - * individual and the optimization problem. The optimization problem is to be stored - * since it is to be called during crossover to calculate the exogene parameters for - * the offsprings. - * @param individual The individual that will be mutated. - * @param opt The optimization problem. - */ - public void init(AbstractEAIndividual individual, InterfaceOptimizationProblem opt) { - this.m_OptimizationProblem = opt; - } + /** + * This method performs crossover on two individuals. If the individuals do + * not implement InterfaceGAIndividual, then nothing will happen. + * + * @param indy1 + * The first individual + * @param partners + * The second individual + */ + public AbstractEAIndividual[] mate(AbstractEAIndividual indy1, + Population partners) { + AbstractEAIndividual[] result = null; + result = new AbstractEAIndividual[partners.size() + 1]; + result[0] = (AbstractEAIndividual) (indy1).clone(); + for (int i = 0; i < partners.size(); i++) + result[i + 1] = (AbstractEAIndividual) ((AbstractEAIndividual) partners + .get(i)).clone(); + // for (int i = 0; i < result.length; i++) System.out.println("Before + // Crossover: " +result[i].getSolutionRepresentationFor()); + if (partners.size() == 0) return result; + if ((indy1 instanceof InterfaceGAIndividual) + && (partners.get(0) instanceof InterfaceGAIndividual)) { + // Currently we will only handle two parents + int crossoverpoint = RandomNumberGenerator.randomInt(0, + ((InterfaceGAIndividual) indy1).getGenotypeLength() - 1); + boolean tmpValue; + BitSet[] tmpBitSets = new BitSet[2]; + tmpBitSets[0] = ((InterfaceGAIndividual) result[0]).getBGenotype(); + tmpBitSets[1] = ((InterfaceGAIndividual) result[1]).getBGenotype(); + for (int i = crossoverpoint; i < ((InterfaceGAIndividual) result[0]) + .getGenotypeLength(); i++) { + if (tmpBitSets[0].get(i)) + tmpValue = true; + else tmpValue = false; + if (tmpBitSets[1].get(i)) + tmpBitSets[0].set(i); + else tmpBitSets[0].clear(i); + if (tmpValue) + tmpBitSets[1].set(i); + else tmpBitSets[1].clear(i); + } + ((InterfaceGAIndividual) result[0]).SetBGenotype(tmpBitSets[0]); + ((InterfaceGAIndividual) result[1]).SetBGenotype(tmpBitSets[1]); + } + // in case the crossover was successfull lets give the mutation operators a + // chance to mate the strategy parameters + for (int i = 0; i < result.length; i++) + result[i].getMutationOperator().crossoverOnStrategyParameters(indy1, + partners); + // for (int i = 0; i < result.length; i++) System.out.println("After + // Crossover: " +result[i].getSolutionRepresentationFor()); + return result; + } - public String getStringRepresentation() { - return this.getName(); - } - -/********************************************************************************************************************** - * These are for GUI - */ - /** This method allows the CommonJavaObjectEditorPanel to read the - * name to the current object. - * @return The name. - */ - public String getName() { - return "GA default crossover"; - } - /** This method returns a global info string - * @return description - */ - public String globalInfo() { - return "This is a one-point crossover between two individuals."; - } + /** + * This method allows you to evaluate wether two crossover operators are + * actually the same. + * + * @param crossover + * The other crossover operator + */ + public boolean equals(Object crossover) { + if (crossover instanceof CrossoverGADefault) + return true; + else return false; + } + + /** + * This method will allow the crossover operator to be initialized depending + * on the individual and the optimization problem. The optimization problem is + * to be stored since it is to be called during crossover to calculate the + * exogene parameters for the offsprings. + * + * @param individual + * The individual that will be mutated. + * @param opt + * The optimization problem. + */ + public void init(AbstractEAIndividual individual, + InterfaceOptimizationProblem opt) { + this.m_OptimizationProblem = opt; + } + + public String getStringRepresentation() { + return this.getName(); + } + + /***************************************************************************** + * These are for GUI + */ + /** + * This method allows the CommonJavaObjectEditorPanel to read the name to the + * current object. + * + * @return The name. + */ + public String getName() { + return "GA default crossover"; + } + + /** + * This method returns a global info string + * + * @return description + */ + public String globalInfo() { + return "This is a one-point crossover between two individuals."; + } } diff --git a/src/javaeva/server/go/strategies/MemeticAlgorithm.java b/src/javaeva/server/go/strategies/MemeticAlgorithm.java index ed79088e..594d7abb 100644 --- a/src/javaeva/server/go/strategies/MemeticAlgorithm.java +++ b/src/javaeva/server/go/strategies/MemeticAlgorithm.java @@ -1,311 +1,397 @@ package javaeva.server.go.strategies; +import java.util.Hashtable; + import javaeva.server.go.InterfacePopulationChangedEventListener; -import javaeva.server.go.PopulationInterface; import javaeva.server.go.individuals.AbstractEAIndividual; import javaeva.server.go.operators.selection.InterfaceSelection; -import javaeva.server.go.operators.selection.SelectBest; import javaeva.server.go.operators.selection.SelectBestIndividuals; import javaeva.server.go.populations.Population; import javaeva.server.go.problems.F1Problem; import javaeva.server.go.problems.InterfaceLocalSearchable; import javaeva.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: The JavaEvA

- *

Description:

- *

Copyright: Copyright (c) 2003

- *

Company:

+/** + * 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: The JavaEvA + *

+ *

+ * Description: + *

+ *

+ * Copyright: Copyright (c) 2003 + *

+ *

+ * Company: + *

+ * * @author not attributable * @version 1.0 */ -public class MemeticAlgorithm implements InterfaceOptimizer, java.io.Serializable { +public class MemeticAlgorithm implements InterfaceOptimizer, + java.io.Serializable { - private int localSearchSteps = 1; - private int subsetsize = 5; - private int globalSearchSteps = 1; - private boolean lamarckism = true; - // int counter = 0; !? - // int maxfunctioncalls = 1000; !? + /** + * serial version uid. + */ + private static final long serialVersionUID = -1730086430763348568L; - 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; + private int subsetsize = 5; - public MemeticAlgorithm() { + private int globalSearchSteps = 1; - } + private boolean lamarckism = true; - 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.globalSearchSteps = a.globalSearchSteps; - this.lamarckism = a.lamarckism; - } + // int counter = 0; !? + // int maxfunctioncalls = 1000; !? - public Object clone() { - return (Object) new MemeticAlgorithm(this); - } + private boolean TRACE = false; - 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("NextGenerationPerformed"); - } + private String m_Identifier = ""; - public void init() { - //counter = 0; - this.m_GlobalOptimizer.SetProblem(this.m_Problem); - this.m_GlobalOptimizer.init(); - this.evaluatePopulation(this.m_GlobalOptimizer.getPopulation()); - this.firePropertyChangedEvent("NextGenerationPerformed"); - } + private InterfaceOptimizationProblem m_Problem = new F1Problem(); - /** 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(); - } + private InterfaceOptimizer m_GlobalOptimizer = new GeneticAlgorithm(); - public void optimize() { + private InterfaceSelection selectorPlug = new SelectBestIndividuals(); - if (TRACE) System.out.println("global search"); - this.m_GlobalOptimizer.optimize(); + transient private InterfacePopulationChangedEventListener m_Listener; - if ((this.m_GlobalOptimizer.getPopulation().getGeneration()%this.globalSearchSteps == 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.out.println("ALERT! identic 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); - } - } + public MemeticAlgorithm() { - //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.out.println("indy 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()); + 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.globalSearchSteps = a.globalSearchSteps; + this.lamarckism = a.lamarckism; + } - this.setPopulation(gop); - } + @Override + public Object clone() { + return new MemeticAlgorithm(this); + } - if (TRACE) System.out.println("function calls" + this.m_GlobalOptimizer.getPopulation().getFunctionCalls()); - this.firePropertyChangedEvent("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("NextGenerationPerformed"); + } - /** This method allows you to add the LectureGUI as listener to the Optimizer - * @param ea - */ - public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { - this.m_Listener = ea; - } - /** 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); - } - } + public void init() { + // counter = 0; + this.m_GlobalOptimizer.SetProblem(this.m_Problem); + this.m_GlobalOptimizer.init(); + this.evaluatePopulation(this.m_GlobalOptimizer.getPopulation()); + this.firePropertyChangedEvent("NextGenerationPerformed"); + } - /** This method will set the problem that is to be optimized - * @param problem - */ - public void SetProblem (InterfaceOptimizationProblem problem) { - this.m_Problem = problem; - this.m_GlobalOptimizer.SetProblem(this.m_Problem); - } - public InterfaceOptimizationProblem getProblem () { - return this.m_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) { + this.m_Problem.evaluate(population); + population.incrGeneration(); + } - /** This method will return a string describing all properties of the optimizer - * and the applied methods. - * @return A descriptive string - */ - 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; - } - /** This method allows you to set an identifier for the algorithm - * @param name The indenifier - */ - public void SetIdentifier(String name) { - this.m_Identifier = name; - } - public String getIdentifier() { - return this.m_Identifier; - } + public void optimize() { - /** This method is required to free the memory on a RMIServer, - * but there is nothing to implement. - */ - public void freeWilly() { + if (TRACE) System.out.println("global search"); + this.m_GlobalOptimizer.optimize(); - } -/********************************************************************************************************************** -* These are for GUI -*/ - /** This method returns a global info string - * @return description - */ - public String globalInfo() { - return "This is a basic generational Memetic Algorithm."; - } - /** This method will return a naming String - * @return The name of the algorithm - */ - public String getName() { - return "Memetic-Algorithm"; - } + if ((this.m_GlobalOptimizer.getPopulation().getGeneration() + % this.globalSearchSteps == 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); + } + } - /** 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. - */ - public Population getPopulation() { - return this.m_GlobalOptimizer.getPopulation(); - } - public void setPopulation(Population pop){ - this.m_GlobalOptimizer.setPopulation(pop); - } - public String populationTipText() { - return "Edit the properties of the population used."; - } + // 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()); + this.firePropertyChangedEvent("NextGenerationPerformed"); + } + + /** + * This method allows you to add the LectureGUI as listener to the Optimizer + * + * @param ea + */ + public void addPopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + this.m_Listener = ea; + } + + /** + * 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 will set the problem that is to be optimized + * + * @param problem + */ + public void SetProblem(InterfaceOptimizationProblem problem) { + this.m_Problem = problem; + this.m_GlobalOptimizer.SetProblem(this.m_Problem); + } + + 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 + */ + 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; + } + + /** + * This method allows you to set an identifier for the algorithm + * + * @param name + * The indenifier + */ + public void SetIdentifier(String name) { + this.m_Identifier = name; + } + + public String getIdentifier() { + return this.m_Identifier; + } + + /** + * This method is required to free the memory on a RMIServer, but there is + * nothing to implement. + */ + public void freeWilly() { + + } + + /* + * ======================================================================================== + * These are for GUI + */ + /** + * This method returns a global info string + * + * @return description + */ + public String globalInfo() { + return "This is a basic generational Memetic Algorithm."; + } + + /** + * This method will return a naming String + * + * @return The name of the algorithm + */ + public String getName() { + return "Memetic-Algorithm"; + } + + /** + * 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. + */ + public Population getPopulation() { + return this.m_GlobalOptimizer.getPopulation(); + } + + public void setPopulation(Population pop) { + this.m_GlobalOptimizer.setPopulation(pop); + } + + 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 setGlobalSearchSteps(int globalSearchSteps) { + this.globalSearchSteps = globalSearchSteps; + } + + public int getGlobalSearchSteps() { + return globalSearchSteps; + } + + public String globalSearchStepsTipText() { + return "Choose the interval between the application of the local search."; + } + + /** + * Choose the number of individual to be locally optimized + * + * @param subsetsize + */ + public void setSubsetsize(int subsetsize) { + this.subsetsize = subsetsize; + } public Population getAllSolutions() { return getPopulation(); } - /** 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."; - } + public int getSubsetsize() { + return subsetsize; + } - /** 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."; - } + public String subsetsizeTipText() { + return "Choose the number of individual to be locally optimized."; + } - /** Choose the interval between the application of the local search - * @param globalSearchSteps - */ - public void setGlobalSearchSteps(int globalSearchSteps) { - this.globalSearchSteps = globalSearchSteps; - } - public int getGlobalSearchSteps() { - return globalSearchSteps; - } - public String globalSearchStepsTipText() { - return "Choose the interval between the application of the local search."; - } + /** + * Toggel between Lamarcksim and the Baldwin Effect + * + * @param lamarckism + */ + public void setLamarckism(boolean lamarckism) { + this.lamarckism = lamarckism; + } - /** 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 individual to be locally optimized."; - } + public boolean getLamarckism() { + return this.lamarckism; + } - /** Toggel between Lamarcksim and the Baldwin Effect - * @param lamarckism - */ - public void setLamarckism(boolean lamarckism) { - this.lamarckism = lamarckism; - } - public boolean getLamarckism() { - return this.lamarckism; - } - public String lamarckismTipText() { - return "Toggel between Lamarcksim and the Baldwin Effect."; - } - public boolean isLamarckism() { - return lamarckism; - } -} \ No newline at end of file + public String lamarckismTipText() { + return "Toggel between Lamarcksim and the Baldwin Effect."; + } + + public boolean isLamarckism() { + return lamarckism; + } +}