Merging changes from mk-branch 122:123.

This commit is contained in:
Marcel Kronfeld 2008-07-29 09:20:56 +00:00
parent b34c349e00
commit 8ab56480a3
11 changed files with 236 additions and 97 deletions

View File

@ -4,8 +4,10 @@ package eva2;
* Main product and version information strings.
*
* --- Changelog
* 2.028: Tuned the Population to sort only when necessary on calls to getBestN... Added StatisticsDummy.
* Slightly tuned SimpleProblemWrapper to call initProblem of simple problems if available.
* 2.027: Renamed SetData and SetDataLamarckian from individual datatype interfaces to SetGenotype and SetPhenotype.
* Repaired the GenericArrayEditor. Population measures can now be plottet in stats.
* Repaired the GenericArrayEditor. Population measures can now be plotted in stats.
* 2.026: Added DiversityTerminator and KnownOptimaTerminator, slightly changed InterfaceTerminator for these
* and InterfaceStatistics to provide termination message to text window.
* Killed redundant method getGenerations() in Population. Population.getAllSolutions now returns a
@ -25,7 +27,7 @@ package eva2;
public class EvAInfo {
public static final String productName = "EvA 2";
public static final String productLongName = "Evolutionary Algorithms Workbench 2";
public static final String versionNum = new String ("2.027");
public static final String versionNum = new String ("2.028");
public static final String url = "http://www.ra.cs.uni-tuebingen.de/software/EvA2";
public static final String propertyFile = "resources/EvA2.props";

View File

@ -16,6 +16,7 @@ import eva2.server.go.populations.Population;
import eva2.server.modules.GOParameters;
import eva2.server.modules.Processor;
import eva2.server.stat.AbstractStatistics;
import eva2.server.stat.StatisticsDummy;
import eva2.server.stat.InterfaceTextListener;
import eva2.server.stat.StatisticsStandalone;
@ -33,13 +34,42 @@ public class OptimizerRunnable implements Runnable {
private boolean postProcessOnly = false;
private InterfaceTextListener listener = null;
/**
* Construct an OptimizerRunnable with given parameters and a StatisticsStandalone instance without restart,
* meaning that the population will be initialized randomly.
*
* @param params
* @param outputFilePrefix
*/
public OptimizerRunnable(GOParameters params, String outputFilePrefix) {
this(params, outputFilePrefix, false);
}
/**
* This constructor assumes that DummyStatistics are enough. This saves time e.g. for small populations.
* If restart is true, the processor will not reinitialize the population allowing search on predefined populations.
*
* @param params
* @param restart
*/
public OptimizerRunnable(GOParameters params, boolean restart) {
proc = new Processor(new StatisticsDummy(), null, params);
if (proc.getStatistics() instanceof AbstractStatistics) ((AbstractStatistics)proc.getStatistics()).setSaveParams(false);
doRestart = restart;
}
/**
* Construct an OptimizerRunnable with given parameters and a StatisticsStandalone instance with optional restart.
* If restart is true, the processor will not reinitialize the population allowing search on predefined populations.
* The outputFilePrefix may be null.
*
* @param params
* @param outputFilePrefix
* @param restart
*/
public OptimizerRunnable(GOParameters params, String outputFilePrefix, boolean restart) {
proc = new Processor(new StatisticsStandalone(outputFilePrefix), null, params);
((AbstractStatistics)proc.getStatistics()).setSaveParams(false);
if (proc.getStatistics() instanceof AbstractStatistics) ((AbstractStatistics)proc.getStatistics()).setSaveParams(false);
doRestart = restart;
}

View File

@ -96,7 +96,7 @@ public class MutateESMutativeStepSizeControl implements InterfaceMutation, java.
if (range[i][1] < x[i]) x[i] = range[i][1];
}
((InterfaceESIndividual)individual).SetDGenotype(x);
System.out.println("new step size: " + m_MutationStepSize);
// System.out.println("new step size: " + m_MutationStepSize);
}
//System.out.println("After Mutate: " +((GAIndividual)individual).getSolutionRepresentationFor());
}

View File

@ -22,6 +22,7 @@ import eva2.server.go.problems.FM0Problem;
import eva2.server.go.problems.InterfaceMultimodalProblemKnown;
import eva2.server.go.strategies.HillClimbing;
import eva2.server.stat.InterfaceTextListener;
import eva2.server.stat.StatsParameter;
import eva2.tools.Pair;
@ -371,8 +372,9 @@ public class PostProcess {
}
hc.setPopulation(pop);
// hc.initByPopulation(pop, false);
hcRunnable = new OptimizerRunnable(OptimizerFactory.makeParams(hc, pop, problem, 0, term), null, true);
hcRunnable = new OptimizerRunnable(OptimizerFactory.makeParams(hc, pop, problem, 0, term), true);
hcRunnable.getGOParams().setDoPostProcessing(false);
hcRunnable.setVerbosityLevel(StatsParameter.VERBOSITY_NONE);
hcRunnable.run();
hcRunnable.getGOParams().setDoPostProcessing(true);
hcRunnable = null;

View File

@ -34,6 +34,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
protected int m_FunctionCalls = 0;
protected int m_Size = 50;
protected Population m_Archive = null;
transient private ArrayList<AbstractEAIndividual> sortedArr = null;
private int lastQModCount = -1;
transient protected InterfacePopulationChangedEventListener m_Listener = null;
protected int notifyEvalInterval = 0;
protected HashMap<String, Object> additionalPopData = null;
@ -161,7 +163,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
useHistory = useHist;
}
/** This method will allow cou to increment the current number of function calls.
/** This method will allow you to increment the current number of function calls.
*/
public void incrFunctionCalls() {
this.m_FunctionCalls++;
@ -178,17 +180,23 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
*/
public void incrFunctionCallsby(int d) {
if (doEvalNotify()) {
System.out.println("checking funcall event...");
int nextStep = ((m_FunctionCalls/notifyEvalInterval)+1) * notifyEvalInterval; // next interval boundary
if (nextStep <= (m_FunctionCalls+d)) {
// System.out.println("checking funcall event...");
int nextStep; // next interval boundary
while ((nextStep = calcNextBoundary()) <= (m_FunctionCalls+d)) {
// the notify interval will be stepped over or hit
int toHit = (nextStep - m_FunctionCalls);
this.m_FunctionCalls += toHit; // little cheat, notify may be after some more evals
firePropertyChangedEvent(funCallIntervalReached);
this.m_FunctionCalls += (d-toHit);
d = d-toHit;
// this.m_FunctionCalls += (d-toHit);
}
if (d>0) this.m_FunctionCalls += d; // add up the rest
} else this.m_FunctionCalls += d;
}
private int calcNextBoundary() {
return ((m_FunctionCalls/notifyEvalInterval)+1) * notifyEvalInterval;
}
/** Something has changed
*/
@ -363,32 +371,69 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
}
/**
* This method returns the n current best individuals from the population, where
* This method returns the n currently best individuals from the population, where
* the sorting criterion is delivered by an AbstractEAIndividualComparator.
* There are less than n individuals returned if the population is smaller than n.
* If n is <= 0, then all individuals are returned and effectively just sorted
* by fitness.
* The comparator does not check constraints!
*
* @param n number of individuals to look out for
* @return The m best individuals, where m <= n
*
*/
public Population getBestNIndividuals(int n) {
if (n <= 0) n = super.size();
return getSortedNIndividuals(n, true);
}
/**
* This method returns the n current best individuals from the population, where
* the sorting criterion is delivered by an AbstractEAIndividualComparator.
* There are less than n individuals returned if the population is smaller than n.
* The comparator does not check constraints!
*
* @param n number of individuals to look out for
* @param bBestOrWorst if true, the best n are returned, else the worst n individuals
* @return The m sorted best or worst individuals, where m <= n
*
*/
public Population getSortedNIndividuals(int n, boolean bBestOrWorst) {
if ((n < 0) || (n>super.size())) {
System.err.println("invalid request to getSortedNIndividuals: n="+n + ", size is " + super.size());
n = super.size();
}
int skip = 0;
if (!bBestOrWorst) skip = super.size()-n;
Population result = new Population(n);
PriorityQueue<AbstractEAIndividual> queue = new PriorityQueue<AbstractEAIndividual>(super.size(), new AbstractEAIndividualComparator());
ArrayList<AbstractEAIndividual> sorted = getSorted();
for (int i = 0; i < super.size(); i++) {
queue.add(getEAIndividual(i));
}
for (int i = 0; i<n ; i++) {
if (queue.size() == 0) break;
result.add(queue.poll());
for (int i = skip; i < skip+n; i++) {
result.add(sorted.get(i));
}
result.setPopulationSize(result.size());
return result;
}
/**
* Avoids having to sort again in several calls without modifications in between.
* The returned array should not be modified!
*
* @return
*/
protected ArrayList<AbstractEAIndividual> getSorted() {
if (sortedArr == null || (super.modCount != lastQModCount)) {
PriorityQueue<AbstractEAIndividual> sQueue = new PriorityQueue<AbstractEAIndividual>(super.size(), new AbstractEAIndividualComparator());
for (int i = 0; i < super.size(); i++) {
sQueue.add(getEAIndividual(i));
}
lastQModCount = super.modCount;
if (sortedArr==null) sortedArr = new ArrayList<AbstractEAIndividual>(this.size());
else sortedArr.clear();
AbstractEAIndividual indy;
while ((indy=sQueue.poll())!=null) sortedArr.add(indy);
}
return sortedArr;
}
/** This method returns n random best individuals from the population.
*
* @param n number of individuals to look out for
@ -662,6 +707,15 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
return addIndividual((IndividualInterface)o);
}
/**
* ArrayList does not increase the modCount in set. Why???
*/
public Object set(int index, Object element) {
Object prev = super.set(index, element);
modCount++;
return prev;
}
public boolean addIndividual(IndividualInterface ind) {
super.add(ind);
return true;

View File

@ -50,6 +50,7 @@ public class F1Problem extends AbstractProblemDouble implements Interface2DBorde
*/
public void initProblem() {
// this.m_OverallBest = null;
initTemplate();
}
protected double[] getEvalArray(AbstractEAIndividual individual){

View File

@ -1,7 +1,7 @@
package eva2.server.go.problems;
import eva2.server.go.individuals.ESIndividualDoubleData;
import eva2.server.go.strategies.ParticleSwarmOptimization;
import eva2.tools.Mathematics;
import wsi.ra.math.Jama.Matrix;
/**
@ -32,10 +32,12 @@ public class F6Problem extends F1Problem implements InterfaceMultimodalProblem,
*/
public void initProblem() {
super.initProblem();
rotation = new Matrix(m_ProblemDimension, m_ProblemDimension);
Matrix vec = new Matrix(m_ProblemDimension, 1);
for (int i=0; i<m_ProblemDimension; i++) vec.set(i,0, i+1);
rotation = ParticleSwarmOptimization.getRotationMatrix(vec).transpose();
if (doRotation) {
rotation = new Matrix(m_ProblemDimension, m_ProblemDimension);
Matrix vec = new Matrix(m_ProblemDimension, 1);
for (int i=0; i<m_ProblemDimension; i++) vec.set(i,0, i+1);
rotation = Mathematics.getRotationMatrix(vec).transpose();
} else rotation = null;
}
/** This method returns a deep clone of the problem.

View File

@ -20,6 +20,7 @@ import eva2.server.go.problems.Interface2DBorderProblem;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import wsi.ra.math.RNG;
import eva2.tools.EVAERROR;
import eva2.tools.Mathematics;
import eva2.tools.SelectedTag;
import wsi.ra.chart2d.DPoint;
@ -797,7 +798,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
for (int i=1; i<dim; i++) {
randVec.set(i, 0, project(-len/2, len/2, RNG.gaussianDouble(len/(scale*2))));
}
Matrix rotation = getRotationMatrix(dir);
Matrix rotation = Mathematics.getRotationMatrix(dir);
rotation = rotation.transpose();
//printMatrix(rotation);
resVec = rotation.times(randVec);
@ -860,75 +861,6 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
// vec.setElement(j, val1);
// }
/**
* Return a matrix A which performs the rotation of vec to (1,0,0,...0) if forward is true, else
* return a matrix B which performs the reverted rotation, where B=A' (transposition).
*
* @param vec
* @return
*/
public static Matrix getRotationMatrix(Matrix vec) {
Matrix A = Matrix.identity(vec.getRowDimension(), vec.getRowDimension());
Matrix tmp = Matrix.identity(vec.getRowDimension(), vec.getRowDimension());
Matrix z = (Matrix)vec.clone();
double w, cosw, sinw;
z.multi(z.norm2()); // normalize
for (int i=1; i<vec.getRowDimension(); i++) {
w = Math.atan2(z.get(i,0), z.get(0,0));// calc angle between the projection of x and x0 in x0-xi-plane
cosw = Math.cos(w);
sinw = Math.sin(w);
tmp.set(0, 0, cosw); // make partial rotation matrix
tmp.set(0, i, sinw);
tmp.set(i, 0, -sinw);
tmp.set(i, i, cosw);
A = tmp.times(A); // add to resulting rotation
z = tmp.times(z); // z is now 0 in i-th component
tmp.set(0, 0, 1); // reset tmp matrix to unity
tmp.set(0, i, 0);
tmp.set(i, 0, 0);
tmp.set(i, i, 1);
}
return A;
}
// protected GMatrix nrotate(GVector vec) {
// GMatrix A = new GMatrix(vec.getSize(), vec.getSize());
// GMatrix tmp = new GMatrix(vec.getSize(), vec.getSize());
// GVector z = new GVector(vec);
//
// double w, cosw, sinw;
//
// z.normalize();
//
//
// for (int i=1; i<vec.getSize(); i++) {
// w = Math.atan2(z.getElement(i), z.getElement(0));// calc angle between the projection of x and x0 in x0-xi-plane
//
// cosw = Math.cos(w);
// sinw = Math.sin(w);
// tmp.setElement(0, 0, cosw); // make partial rotation matrix
// tmp.setElement(0, i, sinw);
// tmp.setElement(i, 0, -sinw);
// tmp.setElement(i, i, cosw);
//
// A.mul(tmp, A); // add to resulting rotation
// z.mul(tmp, z); // z is now 0 in i-th component
//
// tmp.setElement(0, 0, 1); // reset tmp matrix to unity
// tmp.setElement(0, i, 0);
// tmp.setElement(i, 0, 0);
// tmp.setElement(i, i, 1);
// }
// return A;
// }
/**
* In the topology range for the given index, find the best stored individual and return its position.
*

View File

@ -0,0 +1,76 @@
package eva2.server.stat;
import eva2.server.go.IndividualInterface;
import eva2.server.go.PopulationInterface;
import eva2.server.go.problems.InterfaceAdditionalPopulationInformer;
/**
* This may be given to a Processor if no further stats are required. It speeds up
* optimization especially with small populations (e.g. HC as local search operator).
*
* @author mkron
*
*/
public class StatisticsDummy implements InterfaceStatistics, InterfaceTextListener {
boolean consoleOut = false;
StatsParameter sParams = null;
public StatisticsDummy() {
sParams = new StatsParameter();
sParams.setOutputVerbosityK(StatsParameter.VERBOSITY_NONE);
}
public StatisticsDummy(boolean doConsoleOut) {
sParams = new StatsParameter();
sParams.setOutputVerbosityK(StatsParameter.VERBOSITY_NONE);
consoleOut = doConsoleOut;
}
public void addTextListener(InterfaceTextListener listener) {
System.err.println("addTextListener not provided!");
}
public void createNextGenerationPerformed(PopulationInterface Pop,
InterfaceAdditionalPopulationInformer informer) {
}
public void createNextGenerationPerformed(double[] bestfit,
double[] worstfit, int calls) {
}
public double[] getBestFitness() {
System.err.println("getBestFitness not provided!");
return null;
}
public IndividualInterface getBestSolution() {
System.err.println("getBestSolution not provided!");
return null;
}
public InterfaceStatisticsParameter getStatisticsParameter() {
return sParams;
}
public void printToTextListener(String s) {
if (consoleOut) System.out.println(s);
}
public boolean removeTextListener(InterfaceTextListener listener) {
System.err.println("removeTextListener not provided!");
return false;
}
public void startOptPerformed(String InfoString, int runnumber,
Object params) {}
public void stopOptPerformed(boolean normal, String stopMessage) {}
public void print(String str) {
if (consoleOut) System.out.print(str);
}
public void println(String str) {
if (consoleOut) System.out.println(str);
}
}

View File

@ -1,6 +1,8 @@
package eva2.tools;
import java.util.Arrays;
import wsi.ra.math.Jama.Matrix;
import wsi.ra.math.interpolation.BasicDataSet;
import wsi.ra.math.interpolation.InterpolationException;
import wsi.ra.math.interpolation.SplineInterpolation;
@ -609,4 +611,42 @@ public class Mathematics {
public static void normalizeSum(double[] v, double[] res) {
svMult(1./sum(v), v, res);
}
/**
* Return a matrix A which performs the rotation of vec to (1,0,0,...0) if forward is true, else
* return a matrix B which performs the reverted rotation, where B=A' (transposition).
*
* @param vec
* @return
*/
public static Matrix getRotationMatrix(Matrix vec) {
Matrix A = Matrix.identity(vec.getRowDimension(), vec.getRowDimension());
Matrix tmp = Matrix.identity(vec.getRowDimension(), vec.getRowDimension());
Matrix z = (Matrix)vec.clone();
double w, cosw, sinw;
z.multi(z.norm2()); // normalize
for (int i=1; i<vec.getRowDimension(); i++) {
w = Math.atan2(z.get(i,0), z.get(0,0));// calc angle between the projection of x and x0 in x0-xi-plane
cosw = Math.cos(w);
sinw = Math.sin(w);
tmp.set(0, 0, cosw); // make partial rotation matrix
tmp.set(0, i, sinw);
tmp.set(i, 0, -sinw);
tmp.set(i, i, cosw);
A = tmp.times(A); // add to resulting rotation
z = tmp.times(z); // z is now 0 in i-th component
tmp.set(0, 0, 1); // reset tmp matrix to unity
tmp.set(0, i, 0);
tmp.set(i, 0, 0);
tmp.set(i, i, 1);
}
return A;
}
}

View File

@ -146,7 +146,7 @@ public class RNG extends Random {
return (hi-lo)*random.nextFloat()+lo;
}
/**
*
* A random double value between 0 and 1.
*/
public static double randomDouble() {
return random.nextDouble();