eva2/src/javaeva/server/go/strategies/HillClimbing.java
2008-03-11 10:57:37 +00:00

241 lines
9.3 KiB
Java

package javaeva.server.go.strategies;
import javaeva.server.go.InterfacePopulationChangedEventListener;
import javaeva.server.go.individuals.AbstractEAIndividual;
import javaeva.server.go.operators.mutation.InterfaceMutation;
import javaeva.server.go.populations.Population;
import javaeva.server.go.problems.B1Problem;
import javaeva.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 $
*/
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 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;
public HillClimbing() {
this.m_Population = new Population();
this.m_Population.setPopulationSize(10);
}
public HillClimbing(HillClimbing a) {
this.m_Population = (Population)a.m_Population.clone();
this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone();
}
public Object clone() {
return (Object) new HillClimbing(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.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.firePropertyChangedEvent("NextGenerationPerformed");
}
/** This method will optimize
*/
public void optimize() {
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 mutator.mutate(indy);
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)))) {
this.m_Population.remove(i);
this.m_Population.add(i, original.get(i));
} // else: mutation improved the individual
}
this.m_Population.incrGeneration();
// for (int i = 0; i < this.m_Population.size(); i++) {
// indy1 = (AbstractEAIndividual) this.m_Population.get(i);
// indy2 = (AbstractEAIndividual)(indy1).clone();
// indy2.mutate();
// this.m_Problem.evaluate((AbstractEAIndividual) indy2);
// //indy2.SetFitness(0, indy2.evaulateAsMiniBits());
// this.m_Population.incrFunctionCalls();
// //if (indy2.getFitness(0) < indy1.getFitness(0)) {
// if (indy2.isDominating(indy1)) {
// this.m_Population.remove(i);
// this.m_Population.add(i, indy2);
// }
// }
// this.m_Population.incrGeneration();
this.firePropertyChangedEvent("NextGenerationPerformed");
}
public InterfaceMutation getMutationOperator() {
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.
*
* @param mute
*/
public void SetMutationOperator(InterfaceMutation mute) {
mutator = mute;
}
/** 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) {
// HillClimbing program = new HillClimbing();
// 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 += "Hill Climbing:\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 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
* @return The name of the algorithm
*/
public String getName() {
return "MS-HC";
}
public Population getPopulation() {
return this.m_Population;
}
public void setPopulation(Population pop){
this.m_Population = pop;
}
public Population getAllSolutions() {
return getPopulation();
}
public String populationTipText() {
return "Change the number of best individuals stored (MS-HC).";
}
}