package javaeva.server.go.strategies; import javaeva.server.go.InterfacePopulationChangedEventListener; import javaeva.server.go.individuals.AbstractEAIndividual; import javaeva.server.go.individuals.GAIndividualBinaryData; import javaeva.server.go.populations.Population; import javaeva.server.go.problems.B1Problem; import javaeva.server.go.problems.InterfaceOptimizationProblem; import javaeva.server.go.tools.RandomNumberGenerator; /** 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; // These variables are necessary for the more complex LectureGUI enviroment transient private String m_Identifier = ""; transient private InterfacePopulationChangedEventListener m_Listener; private Population m_Population; public ThresholdAlgorithm() { this.m_Population = new Population(); this.m_Population.setPopulationSize(10); } 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; } public Object clone() { return (Object) new ThresholdAlgorithm(this); } /** This method will init the HillClimber */ public void init() { this.m_Problem.initPopulation(this.m_Population); this.m_Problem.evaluate(this.m_Population); this.m_CurrentT = this.m_InitialT; this.firePropertyChangedEvent("NextGenerationPerformed"); } /** This method will init the optimizer with a given population * @param pop The initial population * @param reset If true the population is reset. */ public void initByPopulation(Population pop, boolean reset) { this.m_Population = (Population)pop.clone(); if (reset) this.m_Population.init(); this.m_Problem.evaluate(this.m_Population); this.m_CurrentT = this.m_InitialT; this.firePropertyChangedEvent("NextGenerationPerformed"); } /** This method will optimize */ public void optimize() { 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)); double tmpD = indy.getMutationProbability(); indy.setMutationProbability(1.0); indy.mutate(); indy.setMutationProbability(tmpD); } 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))); if (delta < this.m_CurrentT) { this.m_Population.remove(i); this.m_Population.add(i, original.get(i)); } } this.m_CurrentT = this.m_Alpha * this.m_CurrentT; this.m_Population.incrGeneration(); this.firePropertyChangedEvent("NextGenerationPerformed"); } /** 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; fitOrg = org.getFitness(); fitMut = mut.getFitness(); for (int i = 0; i < fitOrg.length; i++) { result += fitOrg[i] - fitMut[i]; } return result; } /** This method will set the problem that is to be optimized * @param problem */ public void SetProblem (InterfaceOptimizationProblem problem) { this.m_Problem = problem; } public InterfaceOptimizationProblem getProblem () { return this.m_Problem; } /** This method will init the HillClimber */ public void defaultInit() { this.m_FitnessCallsNeeded = 0; this.m_Best = new GAIndividualBinaryData(); this.m_Best.defaultInit(); } /** 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.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; } } /** This main method will start a simple hillclimber. * No arguments necessary. * @param args */ public static void main(String[] args) { ThresholdAlgorithm program = new ThresholdAlgorithm(); int TmpMeanCalls = 0, TmpMeanFitness = 0; for (int i = 0; i < program.m_MultiRuns; i++) { program.defaultInit(); program.defaultOptimize(); TmpMeanCalls += program.m_FitnessCallsNeeded; TmpMeanFitness += program.m_Best.defaultEvaulateAsMiniBits(); } TmpMeanCalls = TmpMeanCalls/program.m_MultiRuns; 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 * @param ea */ public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { this.m_Listener = ea; } /** Something has changed */ 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. * @return A descriptive string */ public String getStringRepresentation() { String result = ""; if (this.m_Population.size() > 1) result += "Multi(" + this.m_Population.size() + ")-Start Hill Climbing:\n"; else result += "Threshold 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 */ 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 "The threshold algorithm uses an declining threshold to accpect new solutions."; } /** This method will return a naming String * @return The name of the algorithm */ 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. * @return The population of current solutions to a given problem. */ public Population getPopulation() { return this.m_Population; } public void setPopulation(Population pop){ this.m_Population = pop; } public String populationTipText() { return "Change the number of best individuals stored (MS-TA)."; } public Population getAllSolutions() { return getPopulation(); } /** Set the initial threshold * @return The initial temperature. */ public double getInitialT() { return this.m_InitialT; } 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 * @return The initial temperature. */ public double getAlpha() { return this.m_Alpha; } 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."; } }