Larger commit, adding IPOP-ES and RankMuCMA mutator. Revs. 130-174 from MK-branch should be merged with this.

This commit is contained in:
Marcel Kronfeld
2008-08-29 14:04:32 +00:00
parent c2a3f06498
commit 68241a0dc0
39 changed files with 1593 additions and 404 deletions

View File

@@ -35,8 +35,8 @@ import eva2.server.go.individuals.GAIndividualDoubleData;
import eva2.server.go.individuals.InterfaceDataTypeDouble;
import eva2.server.go.operators.crossover.CrossoverGANPoint;
import eva2.server.go.operators.mutation.InterfaceMutation;
import eva2.server.go.operators.mutation.MutateESFixedStepSize;
import eva2.server.go.operators.mutation.MutateESLocal;
import eva2.server.go.operators.mutation.MutateESStandard;
import eva2.server.go.operators.selection.SelectTournament;
import eva2.server.go.operators.terminators.EvaluationTerminator;
import eva2.server.go.populations.Population;
@@ -304,7 +304,7 @@ public class GOStandaloneVersion implements InterfaceGOStandalone, InterfacePopu
this.m_OutputPath = "results/";
// These are some tmp Variables
InterfaceDataTypeDouble tmpIndy = new ESIndividualDoubleData();
InterfaceMutation tmpMut = new MutateESStandard();
InterfaceMutation tmpMut = new MutateESFixedStepSize();
switch (experimentType) {
case 0 : {

View File

@@ -2,6 +2,19 @@ package eva2.server.go.individuals;
import java.util.Comparator;
/**
* Comparator implementation which compares two individuals based on their fitness.
* The default version calls isDominatingDebConstraints() of the AbstractEAIndividual
* class and assigns -1 if first is dominant, 1 if second is dominant, 0 if the two ind.s
* are not comparable.
* As an alternative, a data key String may be set which is then used to request a data
* object from the individuals. The objects are interpreted as fitness vectors (double[]) and
* the comparison is based on those. This may be used to access alternative (e.g. older or
* best-so-far fitness values) for individual comparison.
*
* @author mkron
*
*/
public class AbstractEAIndividualComparator implements Comparator<Object> {
// flag whether a data field should be used.
@@ -31,9 +44,21 @@ public class AbstractEAIndividualComparator implements Comparator<Object> {
this.indyDataKey = indyDataKey;
}
public AbstractEAIndividualComparator(AbstractEAIndividualComparator other) {
indyDataKey = other.indyDataKey;
}
public Object clone() {
return new AbstractEAIndividualComparator(this);
}
/**
* Compare two individuals, return -1 if first is dominant, 1 if second is dominant, 0 if they
* Compare two individuals, return -1 if the first is dominant, 1 if the second is dominant, 0 if they
* are not comparable.
*
* @param o1 the first AbstractEAIndividual to compare
* @param o2 the second AbstractEAIndividual to compare
* @return -1 if the first is dominant, 1 if the second is dominant, else 0
*/
public int compare(Object o1, Object o2) {
boolean o1domO2, o2domO1;

View File

@@ -0,0 +1,15 @@
package eva2.server.go.operators.mutation;
import eva2.server.go.populations.Population;
/**
* An interface for a mutation operator which is updated on a generational basis, such as
* the 1/5-success rule.
*
* @author mkron
*
*/
public interface InterfaceMutationGenerational extends InterfaceMutation {
public void adaptAfterSelection(Population oldGen, Population selected);
public void adaptGenerational(Population selectedPop, Population parentPop, Population newPop, boolean updateSelected);
}

View File

@@ -18,8 +18,8 @@ public class MutateESCorrolated implements InterfaceMutation, java.io.Serializab
protected double m_Tau1 = 0.15;
protected double m_LowerLimitStepSize = 0.0000005;
private static final long serialVersionUID = 1L;
private double[] m_Sigmas;
private double[] m_Alphas;
private double[] m_Sigmas = null;
private double[] m_Alphas = null;
protected double m_Tau2 = 0.15;
public MutateESCorrolated() {
@@ -56,7 +56,7 @@ public class MutateESCorrolated implements InterfaceMutation, java.io.Serializab
return new MutateESCorrolated(this);
}
/** This method allows you to evaluate wether two mutation operators
/** This method allows you to evaluate whether two mutation operators
* are actually the same.
* @param mutator The other mutation operator
*/
@@ -85,7 +85,19 @@ public class MutateESCorrolated implements InterfaceMutation, java.io.Serializab
* @param opt The optimization problem.
*/
public void init(AbstractEAIndividual individual, InterfaceOptimizationProblem opt) {
if (individual instanceof InterfaceESIndividual) {
double[] x = ((InterfaceESIndividual)individual).getDGenotype();
if (this.m_Sigmas == null) {
// init the Sigmas
this.m_Sigmas = new double[x.length];
for (int i = 0; i < this.m_Sigmas.length; i++) this.m_Sigmas[i] = this.m_MutationStepSize;
}
if (this.m_Alphas == null) {
// init the Alphas
this.m_Alphas = new double[(x.length*(x.length-1))/2];
for (int i = 0; i < this.m_Alphas.length; i++) this.m_Alphas[i] = 0.0;
}
}
}
/** This method will mutate a given AbstractEAIndividual. If the individual
@@ -158,22 +170,12 @@ public class MutateESCorrolated implements InterfaceMutation, java.io.Serializab
double[][] range = ((InterfaceESIndividual)individual).getDoubleRange();
double tmpR = RNG.gaussianDouble(1);
if (this.m_Sigmas == null) {
// init the Sigmas
this.m_Sigmas = new double[x.length];
for (int i = 0; i < this.m_Sigmas.length; i++) this.m_Sigmas[i] = this.m_MutationStepSize;
}
//Mutate Sigmas
for (int i = 0; i < x.length; i++) {
this.m_Sigmas[i] = this.m_Sigmas[i] * Math.exp(this.m_Tau1 * tmpR + this.m_Tau2 * RNG.gaussianDouble(1));
if (this.m_Sigmas[i] < this.m_LowerLimitStepSize) this.m_Sigmas[i] = this.m_LowerLimitStepSize;
}
if (this.m_Alphas == null) {
// init the Alphas
this.m_Alphas = new double[(x.length*(x.length-1))/2];
for (int i = 0; i < this.m_Alphas.length; i++) this.m_Alphas[i] = 0.0;
}
//Mutate Alphas
for (int i = 0; i < this.m_Alphas.length; i++) {
this.m_Alphas[i] = this.m_Alphas[i] + RNG.gaussianDouble(0.2);
@@ -230,7 +232,7 @@ public class MutateESCorrolated implements InterfaceMutation, java.io.Serializab
sum+=j-i; sum--;
return this.m_Alphas[sum];
}else{
System.out.println("Falscher Zugriff auf Alphaliste!");
System.err.println("Falscher Zugriff auf Alphaliste!");
return 0.0;
}
}
@@ -240,7 +242,7 @@ public class MutateESCorrolated implements InterfaceMutation, java.io.Serializab
* @return A descriptive string.
*/
public String getStringRepresentation() {
return "ES local mutation";
return "ES local correlated mutation";
}
/**********************************************************************************************************************

View File

@@ -160,6 +160,7 @@ public class MutateESCovarianceMatrixAdaption implements InterfaceMutation, java
double pathLen = 0.0;
for (int i = 0; i < this.m_D; i++)
this.s_N[i] = (1.0 - this.m_c) * this.s_N[i] + this.m_c * this.cu * this.Bz[i];
// System.out.println("C bef:\n" + m_C.toString());
// ADAPT COVARIANCE
for (int i = 0; i <this. m_D; i++) {
for (int j = i; j < this.m_D; j++) {
@@ -168,6 +169,7 @@ public class MutateESCovarianceMatrixAdaption implements InterfaceMutation, java
this.m_C.set(j, i, Cij);
}
}
// System.out.println("C aft:\n" + m_C.toString());
// ADAPT GLOBAL STEPSIZE
for (int i = 0; i < this.m_D; i++) {
Bz_d = 0.0;

View File

@@ -14,8 +14,7 @@ import wsi.ra.math.RNG;
* To change this template use File | Settings | File Templates.
*/
public class MutateESFixedStepSize implements InterfaceMutation, java.io.Serializable {
private double m_Sigma = 0.005;
protected double m_Sigma = 0.005;
public MutateESFixedStepSize() {
}

View File

@@ -1,36 +1,43 @@
package eva2.server.go.operators.mutation;
import wsi.ra.math.RNG;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceESIndividual;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import wsi.ra.math.RNG;
import eva2.tools.Mathematics;
/**
* Created by IntelliJ IDEA.
* User: streiche
* Date: 31.05.2005
* Time: 14:22:13
* To change this template use File | Settings | File Templates.
* ES mutation with path length control. The step size (single sigma) is
* adapted using the evolution path length by adapting the real path length
* to the expected path length in for uncorrelated single steps.
* See Hansen&Ostermeier 2001, Eqs. 16,17.
*
*/
public class MutateESDerandomized implements InterfaceMutation, java.io.Serializable {
public class MutateESPathLengthAdaption implements InterfaceMutation, java.io.Serializable {
private int m_D;
private double[] m_Z;
private int m_dim;
private double[] m_randZ;
private double[] m_Path;
private double m_SigmaGlobal = 1.0;
private double m_c;
private boolean m_UsePath = true;
private double dampening = 1;
private double expectedPathLen = -1;
private double m_cu;
public MutateESDerandomized() {
public MutateESPathLengthAdaption() {
}
public MutateESDerandomized(MutateESDerandomized mutator) {
public MutateESPathLengthAdaption(MutateESPathLengthAdaption mutator) {
this.m_UsePath = true;
this.m_D = mutator.m_D;
this.m_dim = mutator.m_dim;
this.m_SigmaGlobal = mutator.m_SigmaGlobal;
this.m_c = mutator.m_c;
if (mutator.m_Z != null) this.m_Z = (double[]) mutator.m_Z.clone();
this.dampening = mutator.dampening;
this.expectedPathLen = mutator.expectedPathLen;
this.m_cu = mutator.m_cu;
if (mutator.m_randZ != null) this.m_randZ = (double[]) mutator.m_randZ.clone();
if (mutator.m_Path != null) this.m_Path = (double[]) mutator.m_Path.clone();
}
@@ -38,7 +45,7 @@ public class MutateESDerandomized implements InterfaceMutation, java.io.Serializ
* @return The clone
*/
public Object clone() {
return new MutateESDerandomized(this);
return new MutateESPathLengthAdaption(this);
}
/** This method allows you to evaluate wether two mutation operators
@@ -46,14 +53,14 @@ public class MutateESDerandomized implements InterfaceMutation, java.io.Serializ
* @param mutator The other mutation operator
*/
public boolean equals(Object mutator) {
if (mutator instanceof MutateESDerandomized) {
MutateESDerandomized mut = (MutateESDerandomized)mutator;
if (mutator instanceof MutateESPathLengthAdaption) {
MutateESPathLengthAdaption mut = (MutateESPathLengthAdaption)mutator;
// i assume if the C Matrix is equal then the mutation operators are equal
if (this.m_D != mut.m_D) return false;
if (this.m_dim != mut.m_dim) return false;
if (this.m_SigmaGlobal != mut.m_SigmaGlobal) return false;
if (this.m_c != mut.m_c) return false;
if ((this.m_Z != null) && (mut.m_Z != null))
for (int i = 0; i < this.m_Z.length; i++) if (this.m_Z[i] != mut.m_Z[i]) return false;
if ((this.m_randZ != null) && (mut.m_randZ != null))
for (int i = 0; i < this.m_randZ.length; i++) if (this.m_randZ[i] != mut.m_randZ[i]) return false;
if ((this.m_Path != null) && (mut.m_Path != null))
for (int i = 0; i < this.m_Path.length; i++) if (this.m_Path[i] != mut.m_Path[i]) return false;
return true;
@@ -69,13 +76,24 @@ public class MutateESDerandomized implements InterfaceMutation, java.io.Serializ
if (!(individual instanceof InterfaceESIndividual)) return;
double[] x = ((InterfaceESIndividual)individual).getDGenotype();
double[][] ranges = ((InterfaceESIndividual)individual).getDoubleRange();
this.m_D = x.length;
if (this.m_UsePath == true) this.m_c = Math.sqrt(1.0 / (double) this.m_D);
this.m_dim = x.length;
// if (this.m_UsePath) this.m_c = Math.sqrt(1.0 / (double) this.m_dim);
this.m_randZ = new double[this.m_dim];
this.m_Path = new double[this.m_dim];
for (int i = 0; i < this.m_dim; i++) {
this.m_randZ[i] = RNG.gaussianDouble(1.0);
// this.m_Path[i]=1;
}
if (this.m_UsePath) this.m_c = 4./(m_dim+4);
else this.m_c = 1.0;
this.m_Z = new double[this.m_D];
this.m_Path = new double[this.m_D];
for (int i = 0; i < this.m_D; i++) this.m_Z[i] = RNG.gaussianDouble(1.0);
evaluateNewObjectX(x, ranges);
expectedPathLen = Math.sqrt(m_dim)*(1-(1./(4*m_dim))+(1./(21*m_dim*m_dim)));
dampening = (1./m_c)+1;
m_cu = Math.sqrt(m_c*(2.0-m_c));
mutateX(x, ranges, true);
}
/** This method will mutate a given AbstractEAIndividual. If the individual
@@ -87,19 +105,30 @@ public class MutateESDerandomized implements InterfaceMutation, java.io.Serializ
if (individual instanceof InterfaceESIndividual) {
double[] x = ((InterfaceESIndividual)individual).getDGenotype();
double[][] ranges = ((InterfaceESIndividual)individual).getDoubleRange();
this.adaptStrategy();
for (int i = 0; i < m_D; i++) m_Z[i] = RNG.gaussianDouble(1.0);
this.evaluateNewObjectX(x, ranges);
for (int i = 0; i < x.length; i++) {
if (x[i] < ranges[i][0]) x[i] = ranges[i][0];
if (x[i] > ranges[i][1]) x[i] = ranges[i][1];
}
this.adaptStrategy(); // this updates the path using the old step and adapts sigma
this.calculateNewStep();
this.mutateX(x, ranges, true); // this performs new mutation
((InterfaceESIndividual)individual).SetDGenotype(x);
}
//System.out.println("After Mutate: " +((GAIndividual)individual).getSolutionRepresentationFor());
}
private void checkRange(double[] x, double[][] ranges) {
for (int i = 0; i < x.length; i++) {
if (x[i] < ranges[i][0]) x[i] = ranges[i][0];
if (x[i] > ranges[i][1]) x[i] = ranges[i][1];
}
}
/** This method allows you to perform either crossover on the strategy parameters
private void calculateNewStep() {
for (int i = 0; i < m_dim; i++) m_randZ[i] = RNG.gaussianDouble(1.0);
}
/** This method allows you to perform either crossover on the strategy parameters
* or to deal in some other way with the crossover event.
* @param indy1 The original mother
* @param partners The original partners
@@ -109,21 +138,23 @@ public class MutateESDerandomized implements InterfaceMutation, java.io.Serializ
}
private void adaptStrategy() {
double length_of_Z = 0;
for (int i = 0; i < m_D; i++) {
m_Path [i] = (1.0 -m_c) * m_Path[i] + Math.sqrt(m_c*(2.0-m_c))*m_Z[i];
length_of_Z = length_of_Z + m_Path[i] * m_Path[i];
// remember the path taken. m_randZ is at this time the last step before selection.
for (int i = 0; i < m_dim; i++) {
m_Path [i] = (1.0 -m_c) * m_Path[i] + m_cu*m_randZ[i];
}
length_of_Z = Math.sqrt(length_of_Z);
double E_of_length_of_Z = Math.sqrt(((double)m_D)+0.5);
double kappa_d = ((double)m_D)/4.0+1.0;
double Exponent = (length_of_Z - E_of_length_of_Z)/(kappa_d*E_of_length_of_Z);
m_SigmaGlobal = m_SigmaGlobal * Math.exp(Exponent);
double pathLen = Mathematics.norm(m_Path);
// double expectedPathLen = Math.sqrt(((double)m_dim)+0.5);
// double kappa_d = ((double)m_dim)/4.0+1.0;
double exp = (pathLen - expectedPathLen)/(dampening*expectedPathLen);
m_SigmaGlobal = m_SigmaGlobal * Math.exp(exp);
}
private void evaluateNewObjectX(double[] x,double[][] range) {
private void mutateX(double[] x,double[][] range, boolean checkRange) {
for (int i = 0; i < x.length; i++)
x[i] = x[i] + m_SigmaGlobal * m_Z[i];
x[i] = x[i] + m_SigmaGlobal * m_randZ[i];
if (checkRange) checkRange(x, range);
}
/** This method allows you to get a string representation of the mutation
@@ -131,7 +162,7 @@ public class MutateESDerandomized implements InterfaceMutation, java.io.Serializ
* @return A descriptive string.
*/
public String getStringRepresentation() {
return "CMA mutation";
return "Mutation/Path-Length-Control";
}
/**********************************************************************************************************************
* These are for GUI
@@ -141,27 +172,27 @@ public class MutateESDerandomized implements InterfaceMutation, java.io.Serializ
* @return The name.
*/
public String getName() {
return "CMA mutation";
return "Mutation/Path-Length-Control";
}
/** This method returns a global info string
* @return description
*/
public String globalInfo() {
return "This is the most sophisticated CMA mutation.";
return "The single step size is controlled using the evolution path.";
}
/** Use only positive numbers this limits the freedom of effect.
* @param bit The new representation for the inner constants.
*/
public void setUsePath(boolean bit) {
this.m_UsePath = bit;
}
public boolean getUsePath() {
return this.m_UsePath;
}
public String usePathTipText() {
return "Use path.";
}
// /** Use only positive numbers this limits the freedom of effect.
// * @param bit The new representation for the inner constants.
// */
// public void setUsePath(boolean bit) {
// this.m_UsePath = bit;
// }
// public boolean getUsePath() {
// return this.m_UsePath;
// }
// public String usePathTipText() {
// return "Use path.";
// }
/** This method allows you to set the initial sigma value.
* @param d The initial sigma value.
@@ -173,6 +204,6 @@ public class MutateESDerandomized implements InterfaceMutation, java.io.Serializ
return this.m_SigmaGlobal;
}
public String initSigmaGlobalTipText() {
return "Set the initial global sigma value.";
return "Set the initial global step size.";
}
}

View File

@@ -0,0 +1,648 @@
package eva2.server.go.operators.mutation;
import java.io.Serializable;
import java.util.Arrays;
import wsi.ra.math.RNG;
import wsi.ra.math.Jama.EigenvalueDecomposition;
import wsi.ra.math.Jama.Matrix;
import eva2.gui.BeanInspector;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeDouble;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.tools.EVAERROR;
import eva2.tools.Mathematics;
import eva2.tools.Pair;
/**
* Implementing CMA ES with rank-mu-update and weighted recombination. This is partly based on the
* java implementation provided on http://www.bionik.tu-berlin.de/user/niko/cmaes_inmatlab.html.
*
* N.Hansen & S.Kern 2004: Evaluating the CMA Evolution Strategy on Multimodal Test Functions.
* Parallel Problem Solving from Nature 2004.
*
* @author mkron
*
*/
public class MutateESRankMuCMA implements InterfaceMutationGenerational, Serializable {
int dim;
private double c_c, expRandStepLen;
private double[] z, zCor;
private InitialSigmaEnum initialSig = InitialSigmaEnum.avgInitialDistance;
private static double firstSigma = -1.;
private static double sigma;
private static double d_sig, c_sig;
private static double[] meanX, pathC, pathS, eigenvalues;
private static double[] weights = null;
private static double[][] range = null;
private static Matrix mC;
private static Matrix mB;
// private static double[] mBD;
private static boolean firstAdaptionDone = false;
private static boolean TRACE_1 = false;
private static boolean TRACE_2 = false;
private static boolean TRACE_TEST = false;
// private Matrix BD;
public MutateESRankMuCMA() {
firstAdaptionDone = false;
}
public MutateESRankMuCMA(MutateESRankMuCMA mutator) {
this.c_c = mutator.c_c;
// this.c_sig = mutator.c_sig;
// this.c_u_sig = mutator.c_u_sig;
// this.d_sig = mutator.d_sig;
this.expRandStepLen = mutator.expRandStepLen;
this.dim = mutator.dim;
this.initialSig = mutator.initialSig;
// if (mutator.meanX != null) this.meanX = (double[]) mutator.meanX.clone();
// if (mutator.pathC != null) this.pathC = (double[]) mutator.pathC.clone();
// if (mutator.pathS != null) this.pathS = (double[]) mutator.pathS.clone();
if (mutator.z != null) this.z = (double[]) mutator.z.clone();
if (mutator.zCor != null) this.zCor = (double[]) mutator.zCor.clone();
// if (mutator.eigenvalues != null) this.eigenvalues = (double[]) mutator.eigenvalues.clone();
// if (mutator.mC != null) this.mC = (Matrix) mutator.mC.clone();
// if (mutator.mB != null) this.mB = (Matrix) mutator.mB.clone();
}
public Object clone() {
// if (TRACE) System.out.println("WCMA clone");
return new MutateESRankMuCMA(this);
}
/**
* Retrieve the initial sigma for the given population and the user defined method.
* @param initGen
* @return
*/
private double getInitSigma(Population initGen) {
switch (initialSig) {
case avgInitialDistance: return initGen.getPopulationMeasures()[0];
case halfRange: return getAvgRange()/2.;
default: return 0.2;
}
}
public void adaptAfterSelection(Population oldGen, Population selectedP) {
Population selectedSorted = selectedP.getSortedBestFirst();
int mu,lambda;
mu = selectedP.size();
lambda = oldGen.size();
if (mu>= lambda) {
EVAERROR.errorMsgOnce("Warning: invalid mu/lambda ratio! Setting mu to lambda/2.");
mu = lambda/2;
}
if (!firstAdaptionDone) {
initWeights(mu, lambda);
double muEff = getMuEff(mu);
c_sig = (muEff+2)/(muEff+dim+3);
// c_u_sig = Math.sqrt(c_sig * (2.-c_sig));
d_sig = c_sig+1+2*Math.max(0, Math.sqrt((muEff-1)/(dim+1)) - 1);
sigma = getInitSigma(oldGen);
firstSigma = sigma;
meanX = oldGen.getCenter(); // this might be ok?
}
int generation = oldGen.getGeneration();
if (TRACE_1) {
System.out.println("WCMA adaptGenerational");
// System.out.println("newPop measures: " + BeanInspector.toString(newPop.getPopulationMeasures()));
System.out.println("mu_eff: " + getMuEff(mu));
System.out.println("meanX: " + BeanInspector.toString(meanX));
System.out.println("pathC: " + BeanInspector.toString(pathC));
System.out.println("pathS: " + BeanInspector.toString(pathS));
}
double[] newMeanX = calcMeanX(selectedSorted);
if (TRACE_1) System.out.println("newMeanX: " + BeanInspector.toString(newMeanX));
double[] BDz = new double[dim];
for (int i=0; i<dim; i++) { /* calculate xmean and BDz~N(0,C) */
// Eq. 4 from HK04, most right term
BDz[i] = Math.sqrt(getMuEff(mu)) * (newMeanX[i] - meanX[i]) / getSigma(i);
}
// if (TRACE_2) System.out.println("BDz is " + BeanInspector.toString(BDz));
double[] newPathS = pathS.clone();
double[] newPathC = pathC.clone();
double[] zVect = new double[dim];
/* calculate z := D^(-1) * B^(-1) * BDz into artmp, we could have stored z instead */
for (int i = 0; i < dim; ++i) {
double sum=0.;
for (int j = 0; j < dim; ++j) {
sum += mB.get(j,i) * BDz[j]; // times B transposed, (Eq 4) in HK04
}
zVect[i] = sum / Math.sqrt(eigenvalues[i]);
}
/* cumulation for sigma (ps) using B*z */
for (int i = 0; i < dim; ++i) {
double sum = 0.;
for (int j = 0; j < dim; ++j) sum += mB.get(i,j) * zVect[j];
newPathS[i] = (1. - getCs()) * pathS[i]
+ Math.sqrt(getCs() * (2. - getCs())) * sum;
}
// System.out.println("pathS diff: " + BeanInspector.toString(Mathematics.vvSub(newPathS, pathS)));
// System.out.println("newPathS is " + BeanInspector.toString(newPathS));
double psNorm = Mathematics.norm(newPathS);
double hsig = 0;
if (psNorm / Math.sqrt(1. - Math.pow(1. - getCs(), 2. * generation))
/ expRandStepLen < 1.4 + 2. / (dim + 1.)) {
hsig = 1;
}
for (int i = 0; i < dim; ++i) {
newPathC[i] = (1. - getCc()) * pathC[i] + hsig
* Math.sqrt(getCc() * (2. - getCc())) * BDz[i];
}
// TODO missing: "remove momentum in ps"
if (TRACE_1) {
System.out.println("newPathC: " + BeanInspector.toString(newPathC));
System.out.println("newPathS: " + BeanInspector.toString(newPathS));
}
if (TRACE_1) System.out.println("Bef: C is \n" + mC.toString());
if (meanX == null) meanX = newMeanX;
updateCov(newPathC, newMeanX, hsig, mu, selectedSorted);
updateBD();
if (TRACE_2) System.out.println("Aft: C is \n" + mC.toString());
/* update of sigma */
sigma *= Math.exp(((psNorm / expRandStepLen) - 1) * getCs()
/ getDamps());
if (Double.isInfinite(sigma) || Double.isNaN(sigma)) {
System.err.println("Error, unstable sigma!");
}
testAndCorrectNumerics(generation, selectedSorted);
// System.out.println("sigma=" + sigma + " psLen=" + (psNorm) + " chiN="+expRandStepLen + " cs="+getCs()+ " damps="+getDamps() + " diag " + BeanInspector.toString(eigenvalues));
if (TRACE_1) {
System.out.print("psLen=" + (psNorm) + " ");
outputParams(mu);
}
// take over data
meanX = newMeanX;
pathC = newPathC;
pathS = newPathS;
firstAdaptionDone = true;
// if (TRACE_2) System.out.println("sampling around " + BeanInspector.toString(meanX));
}
/**
* Expects newPop to have correct number of generations set.
*/
public void adaptGenerational(Population oldPop, Population selectedPop,
Population newPop, boolean updateSelected) {
// nothing to do?
}
/**
* Requires selected population to be sorted by fitness.
*
* @param iterations
* @param selected
*/
void testAndCorrectNumerics(int iterations, Population selected) { // not much left here
/* Flat Fitness, Test if function values are identical */
if (iterations > 1) {
// selected pop is sorted
if (nearlySame(selected.getEAIndividual(0).getFitness(),selected.getEAIndividual(selected.size()-1).getFitness())) {
if (TRACE_1) System.err.println("flat fitness landscape, consider reformulation of fitness, step-size increased");
sigma *= Math.exp(0.2+getCs()/getDamps());
// sigma=0.1;
}
}
/* Align (renormalize) scale C (and consequently sigma) */
/* e.g. for infinite stationary state simulations (noise
* handling needs to be introduced for that) */
double fac = 1.;
double minEig = 1e-12;
double maxEig = 1e8;
if (Mathematics.max(eigenvalues) < minEig)
fac = 1./Math.sqrt(Mathematics.max(eigenvalues));
else if (Mathematics.min(eigenvalues) > maxEig)
fac = 1./Math.sqrt(Mathematics.min(eigenvalues));
if (fac != 1.) {
System.err.println("Scaling by " + fac);
sigma /= fac;
for(int i = 0; i < dim; ++i) {
pathC[i] *= fac;
eigenvalues[i] *= fac*fac;
for (int j = 0; j <= i; ++j) {
mC.set(i, j, mC.get(i,j)*fac*fac);
if (i!=j) mC.set(j, i, mC.get(i,j));
}
}
}
} // Test...
private boolean nearlySame(double[] bestFitness, double[] worstFitness) {
double epsilon = 1e-14;
for (int i=0; i<bestFitness.length; i++) if (Math.abs(bestFitness[i]-worstFitness[i])>epsilon) return false;
return true;
}
/**
* Return the range scaled sigma parameter for dimension i.
*
* @param i
* @return
*/
private double getSigma(int i) {
return sigma;
}
private double getDamps() {
return d_sig;
}
private double getCc() {
return c_c;
}
private double getCs() {
return c_sig;
}
private double calcExpRandStepLen() {
// scale by avg range?
return Math.sqrt(dim)*(1.-(1./(4*dim))+(1./(21*dim*dim)));
}
private double getAvgRange() {
double sum = 0.;
for (int i=0; i<dim; i++) sum+=(range[i][1]-range[i][0]);
return sum/dim;
}
/* update C */
private void updateCov(double[] newPathC, double[] newMeanX, double hsig, int mu, Population selected) {
double newVal = 0;
if (getCCov(mu) > 0) {
/* (only upper triangle!) */
/* update covariance matrix */
//System.out.println("CCov " + getCCov(selected) + " Cc " + getCc() + " muCov " + getMuCov(selected));
for (int i = 0; i < dim; ++i)
for (int j = 0; j <= i; ++j) {
// oldVal = mC.get(i,j);
newVal = (1 - getCCov(mu)) * mC.get(i,j)
+ getCCov(mu)
* (1. / getMuCov(mu))
* (newPathC[i] * newPathC[j] + (1 - hsig) * getCc()
* (2. - getCc()) * mC.get(i,j));
mC.set(i,j,newVal);
for (int k = 0; k < mu; ++k) { /*
* additional rank mu
* update
*/
double[] x_k = ((InterfaceDataTypeDouble)selected.getEAIndividual(k)).getDoubleData();
newVal = mC.get(i,j)+ getCCov(mu) * (1 - 1. / getMuCov(mu))
* getWeight(k) * (x_k[i] - meanX[i])
* (x_k[j] - meanX[j]) / (getSigma(i) * getSigma(j)); // TODO right sigmas?
mC.set(i,j, newVal);
}
}
// fill rest of C
for (int i = 0; i < dim; ++i) {
for (int j = i+1; j < dim; ++j) {
mC.set(i, j, mC.get(j,i));
}
}
if (mC.get(0,1) != mC.get(1,0)) {
System.err.println("WARNING");
}
// maxsqrtdiagC = Math.sqrt(math.max(math.diag(C)));
// minsqrtdiagC = Math.sqrt(math.min(math.diag(C)));
} // update of C
}
private double getMuCov(int mu) {
// default parameter value ( HK03, sec. 2)
return getMuEff(mu);
}
private double getCCov(int mu) {
// ( HK03, sec. 2)
//return Math.min(1., 2*getMuEff(selected)/(dim*dim));
double ccov = (2./(getMuCov(mu)*Math.pow(dim+Math.sqrt(2.), 2)))+(1.-(1./getMuCov(mu)))*Math.min(1., (2*getMuEff(mu)-1.)/(dim*dim+2*dim+4+getMuEff(mu)));
return ccov;
}
private double getMuEff(int mu) {
double res = 0, u;
for (int i=0; i<mu;i++) {
u = getWeight(i);
res += u*u;
}
return 1./res;
}
private void outputParams(int mu) {
System.out.println("sigma=" + sigma + " chiN="+expRandStepLen + " cs="+getCs()+ " damps="+getDamps() + " Cc=" + getCc() + " Ccov=" + getCCov(mu) + " mueff=" + getMuEff(mu) + " mucov="+getMuCov(mu));
}
private void updateBD() {
// C=triu(C)+transpose(triu(C,1)); % enforce symmetry
// [B,D] = eig(C);
// % limit condition of C to 1e14 + 1
// if max(diag(D)) > 1e14*min(diag(D))
// tmp = max(diag(D))/1e14 - min(diag(D));
// C = C + tmp*eye(N);
// D = D + tmp*eye(N);
// end
// D = diag(sqrt(diag(D))); % D contains standard deviations now
// BD = B*D; % for speed up only
////////////////////////////////////////////7
mC = (mC.plus(mC.transpose()).times(0.5)); // MAKE C SYMMETRIC
EigenvalueDecomposition helper;
// this.m_Counter = 0;
helper = new EigenvalueDecomposition(mC);
mB = helper.getV(); // Return the eigenvector matrix
eigenvalues = helper.getRealEigenvalues();
// double[] sqrtEig = eigenvalues.clone();
// for (int i = 0; i < sqrtEig.length; i++) {
// sqrtEig[i] = Math.sqrt(eigenvalues[i]);
// }
// mB.times(sqrtEig, mBD);
// Matrix test = (Matrix)mB.clone();
// System.out.println(test);
// System.out.println(test.transpose());
// System.out.println(test.times(test.transpose()));
// test = (Matrix)mB.clone();
// double[] mult = new double[dim];
// int spalte=3;
// for (int i=0; i<dim; i++) {
// System.out.println(test.get(i,spalte));
// for (int j=0; j<dim; j++) mult[i] += mC.get(i,j)*test.get(j, spalte);
// }
// System.out.println("eigenv: " + eigenvalues[spalte]);
// System.out.println(BeanInspector.toString(mult));
// System.exit(1);
}
/**
* calculate weighted mean of the selected population
* @param selectedPop
* @return
*/
private double[] calcMeanX(Population selectedPop) {
return selectedPop.getCenterWeighted(weights);
}
private double getWeight(int i) {
return weights[i];
}
private void initWeights(int mu, int lambda) {
weights = new double[mu];
double sum = 0;
int type = 0; // zero is default log scale
for (int i=0; i<mu; i++) {
if (type == 0) {
weights[i] = (Math.log((lambda+1)/2.)-Math.log(i+1));
} else weights[i] = 1.;
sum+=weights[i];
}
for (int i=0; i<mu; i++) weights[i] /= sum;
}
public void crossoverOnStrategyParameters(AbstractEAIndividual indy1,
Population partners) {
// nothing to do
}
public String getName() {
return "Rank-Mu-CMA-Mutator";
}
public String getStringRepresentation() {
return "Rank-Mu-CMA-Mutator";
}
public String globalInfo() {
return "The CMA mutator scheme with static cov. matrix, rank-mu update and weighted recombination.";
}
public void init(AbstractEAIndividual individual,
InterfaceOptimizationProblem opt) {
// TODO recheck all this; some is handled in adaptGeneration on the first call
firstAdaptionDone = false;
range = ((InterfaceDataTypeDouble)individual).getDoubleRange();
dim = range.length;
if (TRACE_1) System.out.println("WCMA init " + dim);
c_c = (4./(dim+4));
c_sig = Double.NaN; // mark as not yet initialized
// c_u_sig = Double.NaN;
d_sig = Double.NaN; // init in first adaption step!
if (TRACE_1) System.out.println("WCMA static init " + dim);
eigenvalues = new double[dim];
Arrays.fill(eigenvalues, 1.);
meanX = new double[dim];
pathC = new double[dim];
pathS = new double[dim];
// mBD = new double[dim];
mC = Matrix.identity(dim, dim);
mB = Matrix.identity(dim, dim);
sigma = 0.2;
z = new double[dim];
zCor = new double[dim];
expRandStepLen = calcExpRandStepLen();
}
public void mutate(AbstractEAIndividual individual) {
// if (!firstAdaptionDone) {
// if (TRACE) System.out.println("No mutation before first adaptions step");
// return;
// }
if (individual instanceof InterfaceDataTypeDouble) {
double[] x = ((InterfaceDataTypeDouble)individual).getDoubleData();
// if (TRACE) System.out.println("WCMA mutate, bef: " + BeanInspector.toString(x));
double[][] range = ((InterfaceDataTypeDouble)individual).getDoubleRange();
((InterfaceDataTypeDouble)individual).SetDoubleGenotype(mutate(x, range, 0));
// if (TRACE) System.out.println("WCMA mutate, aft: " + BeanInspector.toString(x));
} else System.err.println("Error, expecting InterfaceDataTypeDouble");
}
private double[] mutate(double[] x, double[][] range, int count) {
if (firstAdaptionDone) {
double[] artmp = new double[x.length];
for (int i = 0; i < dim; ++i) {
artmp[i] = Math.sqrt(eigenvalues[i]) * RNG.gaussianDouble(1.);
}
// System.out.println("Sampling around " + BeanInspector.toString(meanX));
/* add mutation (sigma * B * (D*z)) */
for (int i = 0; i < dim; ++i) {
double sum = 0.;
for (int j = 0; j < dim; ++j)
sum += mB.get(i,j) * artmp[j];
x[i] = meanX[i]+getSigma(i)*sum;
}
} else {
// no valid meanX yet, so just do a gaussian jump with sigma
for (int i = 0; i < dim; ++i) {
x[i] += RNG.gaussianDouble(getSigma(i));
}
}
if (isInRange(x, range)) return x;
else {
if (count > 5) return repairMutation(x, range); // allow some nice tries before using brute force
else return mutate(x, range, count+1); // for really bad initial deviations this might be a quasi infinite loop
}
}
private double[] repairMutation(double[] x, double[][] range) {
// TODO % You may handle constraints here. You may either resample
// % arz(:,k) and/or multiply it with a factor between -1 and 1
// % (the latter will decrease the overall step size) and
// % recalculate arx accordingly. Do not change arx or arz in any
// % other way.
for (int i=0; i<x.length; i++) {
if (x[i]<range[i][0]) x[i]=range[i][0];
else if (x[i]>range[i][1]) x[i]=range[i][1];
}
return x;
}
private boolean isInRange(double[] x, double[][] range) {
for (int i=0; i<x.length; i++) {
if (x[i]<range[i][0] || (x[i]>range[i][1])) return false;
}
return true;
}
/**
* After optimization start, this returns the initial sigma value
* actually employed.
*
* @return the initial sigma value actually employed
*/
public double getFirstSigma() {
return firstSigma;
}
/**
* @return the initialSig
*/
public InitialSigmaEnum getInitialSigma() {
return initialSig;
}
/**
* @param initialSig the initialSig to set
*/
public void setInitialSigma(InitialSigmaEnum initialSig) {
this.initialSig = initialSig;
}
public String initialSigmaTipText() {
return "Method to use for setting the initial step size.";
}
/**
* From Auger&Hansen, CEC '05, stopping criterion TolX.
*
* @param tolX
* @return
*/
public boolean testAllDistBelow(double tolX) {
// if all(sigma*(max(abs(pc), sqrt(diag(C)))) < stopTolX)
boolean res = true;
int i=0;
while (res && i<dim) {
res = res && (getSigma(i)*Math.max(Math.abs(pathC[i]), Math.sqrt(mC.get(i,i))) < tolX);
i++;
}
if (TRACE_TEST) if (res) System.out.println("testAllDistBelow hit");
return res;
}
/**
* From Auger&Hansen, CEC '05, stopping criterion noeffectaxis.
* @param d
* @param gen
* @return
*/
public boolean testNoChangeAddingDevAxis(double d, int gen) {
// if all(xmean == xmean + 0.1*sigma*BD(:,1+floor(mod(countiter,N))))
// i = 1+floor(mod(countiter,N));
// stopflag(end+1) = {'warnnoeffectaxis'};
int k = gen%dim;
double[] ev_k = mB.getColumn(k);
Mathematics.svMult(Math.sqrt(eigenvalues[k]), ev_k, ev_k); // this is now e_k*v_k = BD(:,...)
int i=0;
boolean res = true;
while (res && (i<dim)) {
res = res && (meanX[i] == (meanX[i] + d*getSigma(i)*ev_k[i]));
i++;
}
if (TRACE_TEST) if (res) System.out.println("testNoChangeAddingDevAxis hit");
return res;
}
/**
* From Auger&Hansen, CEC '05, stopping criterion noeffectcoord.
* @param d
* @return
*/
public boolean testNoEffectCoord(double d) {
// if any(xmean == xmean + 0.2*sigma*sqrt(diag(C)))
// stopflag(end+1) = {'warnnoeffectcoord'};
boolean ret = false;
int i=0;
while ((i<dim) && !ret) {
ret = ret || (meanX[i]==(meanX[i] + d*getSigma(i)*Math.sqrt(mC.get(i, i))));
i++;
}
if (TRACE_TEST) if (ret) System.out.println("testNoEffectCoord hit");
return ret;
}
/**
* Test condition of C (Auger&Hansen, CEC '05, stopping criterion conditioncov).
* Return true, if a diagonal entry is <= 0 or >= d.
*
* @param d
* @return true, if a diagonal entry is <= 0 or >= d, else false
*/
public boolean testCCondition(double d) {
// if (min(diag(D)) <= 0) || (max(diag(D)) > 1e14*min(diag(D)))
// stopflag(end+1) = {'warnconditioncov'};
Pair<Double,Double> minMax = mC.getMinMaxDiag();
if ((minMax.head <= 0) || (minMax.tail >= d)) {
if (TRACE_TEST) System.out.println("testCCondition hit");
return true;
} else return false;
}
}
enum InitialSigmaEnum {
halfRange, avgInitialDistance;
}

View File

@@ -1,121 +1,120 @@
package eva2.server.go.operators.mutation;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeDouble;
import eva2.server.go.individuals.InterfaceESIndividual;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import wsi.ra.math.RNG;
/**
* Created by IntelliJ IDEA.
* User: streiche
* Date: 15.05.2003
* Time: 17:04:24
* To change this template use Options | File Templates.
*/
public class MutateESStandard implements InterfaceMutation, java.io.Serializable {
protected double m_MutationStepSize = 0.1;
public MutateESStandard() {
}
public MutateESStandard(MutateESStandard d) {
this.m_MutationStepSize = d.m_MutationStepSize;
}
/** This method will enable you to clone a given mutation operator
* @return The clone
*/
public Object clone() {
return new MutateESStandard(this);
}
/** This method allows you to evaluate wether two mutation operators
* are actually the same.
* @param mutator The other mutation operator
*/
public boolean equals(Object mutator) {
if (mutator instanceof MutateESStandard) {
MutateESStandard mut = (MutateESStandard)mutator;
if (this.m_MutationStepSize != mut.m_MutationStepSize) return false;
return true;
} else return false;
}
/** This method allows you to init the mutation operator
* @param individual The individual that will be mutated.
* @param opt The optimization problem.
*/
public void init(AbstractEAIndividual individual, InterfaceOptimizationProblem opt) {
}
/** This method will mutate a given AbstractEAIndividual. If the individual
* doesn't implement InterfaceESIndividual nothing happens.
* @param individual The individual that is to be mutated
*/
public void mutate(AbstractEAIndividual individual) {
//System.out.println("Before Mutate: " +((GAIndividual)individual).getSolutionRepresentationFor());
if (individual instanceof InterfaceESIndividual) {
double[] x = ((InterfaceESIndividual)individual).getDGenotype();
double[][] range = ((InterfaceESIndividual)individual).getDoubleRange();
for (int i = 0; i < x.length; i++) {
x[i] += ((range[i][1] -range[i][0])/2)*RNG.gaussianDouble(this.m_MutationStepSize);
if (range[i][0] > x[i]) x[i] = range[i][0];
if (range[i][1] < x[i]) x[i] = range[i][1];
}
((InterfaceESIndividual)individual).SetDGenotype(x);
}
//System.out.println("After Mutate: " +((GAIndividual)individual).getSolutionRepresentationFor());
}
/** This method allows you to perform either crossover on the strategy parameters
* or to deal in some other way with the crossover event.
* @param indy1 The original mother
* @param partners The original partners
*/
public void crossoverOnStrategyParameters(AbstractEAIndividual indy1, Population partners) {
// nothing to do here
}
/** This method allows you to get a string representation of the mutation
* operator
* @return A descriptive string.
*/
public String getStringRepresentation() {
return "ES standard mutation";
}
/**********************************************************************************************************************
* These are for GUI
*/
/** This method allows the CommonJavaObjectEditorPanel to read the
* name to the current object.
* @return The name.
*/
public String getName() {
return "ES standard mutation ";
}
/** This method returns a global info string
* @return description
*/
public String globalInfo() {
return "The standard mutation alters all elements of the double attributes with a fixed mutation step size.";
}
/** This method allows you to set the fixed mutation step size
* @param step The new mutation step size
*/
public void setMutationStepSize(double step) {
if (step < 0) step = 0.0000001;
this.m_MutationStepSize = step;
}
public double getMutationStepSize() {
return this.m_MutationStepSize;
}
public String mutationStepSizeTipText() {
return "Set the value for the fixed mutation step size.";
}
}
//package eva2.server.go.operators.mutation;
//
//import eva2.server.go.individuals.AbstractEAIndividual;
//import eva2.server.go.individuals.InterfaceDataTypeDouble;
//import eva2.server.go.individuals.InterfaceESIndividual;
//import eva2.server.go.populations.Population;
//import eva2.server.go.problems.InterfaceOptimizationProblem;
//import wsi.ra.math.RNG;
//
///**
// * Created by IntelliJ IDEA.
// * User: streiche
// * Date: 15.05.2003
// * Time: 17:04:24
// * To change this template use Options | File Templates.
// */
//public class MutateESStandard implements InterfaceMutation, java.io.Serializable {
// protected double m_MutationStepSize = 0.1;
// public MutateESStandard() {
// }
//
// public MutateESStandard(MutateESStandard d) {
// this.m_MutationStepSize = d.m_MutationStepSize;
// }
//
// /** This method will enable you to clone a given mutation operator
// * @return The clone
// */
// public Object clone() {
// return new MutateESStandard(this);
// }
//
// /** This method allows you to evaluate wether two mutation operators
// * are actually the same.
// * @param mutator The other mutation operator
// */
// public boolean equals(Object mutator) {
// if (mutator instanceof MutateESStandard) {
// MutateESStandard mut = (MutateESStandard)mutator;
// if (this.m_MutationStepSize != mut.m_MutationStepSize) return false;
// return true;
// } else return false;
// }
//
// /** This method allows you to init the mutation operator
// * @param individual The individual that will be mutated.
// * @param opt The optimization problem.
// */
// public void init(AbstractEAIndividual individual, InterfaceOptimizationProblem opt) {
//
// }
//
// /** This method will mutate a given AbstractEAIndividual. If the individual
// * doesn't implement InterfaceESIndividual nothing happens.
// * @param individual The individual that is to be mutated
// */
// public void mutate(AbstractEAIndividual individual) {
// //System.out.println("Before Mutate: " +((GAIndividual)individual).getSolutionRepresentationFor());
// if (individual instanceof InterfaceESIndividual) {
// double[] x = ((InterfaceESIndividual)individual).getDGenotype();
// double[][] range = ((InterfaceESIndividual)individual).getDoubleRange();
// for (int i = 0; i < x.length; i++) {
// x[i] += ((range[i][1] -range[i][0])/2)*RNG.gaussianDouble(this.m_MutationStepSize);
// if (range[i][0] > x[i]) x[i] = range[i][0];
// if (range[i][1] < x[i]) x[i] = range[i][1];
// }
// ((InterfaceESIndividual)individual).SetDGenotype(x);
//
// }
// //System.out.println("After Mutate: " +((GAIndividual)individual).getSolutionRepresentationFor());
// }
//
// /** This method allows you to perform either crossover on the strategy parameters
// * or to deal in some other way with the crossover event.
// * @param indy1 The original mother
// * @param partners The original partners
// */
// public void crossoverOnStrategyParameters(AbstractEAIndividual indy1, Population partners) {
// // nothing to do here
// }
//
// /** This method allows you to get a string representation of the mutation
// * operator
// * @return A descriptive string.
// */
// public String getStringRepresentation() {
// return "ES standard mutation";
// }
//
///**********************************************************************************************************************
// * These are for GUI
// */
// /** This method allows the CommonJavaObjectEditorPanel to read the
// * name to the current object.
// * @return The name.
// */
// public String getName() {
// return "ES standard mutation ";
// }
// /** This method returns a global info string
// * @return description
// */
// public String globalInfo() {
// return "The standard mutation alters all elements of the double attributes with a fixed mutation step size.";
// }
//
// /** This method allows you to set the fixed mutation step size
// * @param step The new mutation step size
// */
// public void setMutationStepSize(double step) {
// if (step < 0) step = 0.0000001;
// this.m_MutationStepSize = step;
// }
// public double getMutationStepSize() {
// return this.m_MutationStepSize;
// }
// public String mutationStepSizeTipText() {
// return "Set the value for the fixed mutation step size.";
// }
//}

View File

@@ -14,11 +14,7 @@ import wsi.ra.math.RNG;
* Time: 14:11:49
* To change this template use File | Settings | File Templates.
*/
public class MutateESSuccessRule extends MutateESStandard implements InterfaceMutation, java.io.Serializable {
/*
* This is a bit of a cheat as the implementation does only hold some
* more parameters while the ES strategy really acts on it.
*/
public class MutateESSuccessRule extends MutateESFixedStepSize implements InterfaceMutationGenerational, java.io.Serializable {
// it would be quite nice to make this variable static, but in that case
// no one could runs n independent ES runs in parallel anymore *sigh*
// protected static double m_MutationStepSize = 0.2;
@@ -30,7 +26,7 @@ public class MutateESSuccessRule extends MutateESStandard implements InterfaceMu
}
public MutateESSuccessRule(MutateESSuccessRule mutator) {
this.m_MutationStepSize = mutator.m_MutationStepSize;
super(mutator);
this.m_SuccessRate = mutator.m_SuccessRate;
this.m_Alpha = mutator.m_Alpha;
}
@@ -49,12 +45,13 @@ public class MutateESSuccessRule extends MutateESStandard implements InterfaceMu
public boolean equals(Object mutator) {
if (mutator instanceof MutateESSuccessRule) {
MutateESSuccessRule mut = (MutateESSuccessRule)mutator;
if (this.m_MutationStepSize != mut.m_MutationStepSize) return false;
if (this.m_Sigma != mut.m_Sigma) return false;
if (this.m_SuccessRate != mut.m_SuccessRate) return false;
if (this.m_Alpha != mut.m_Alpha) return false;
return true;
} else return false;
}
/** This method allows you to get a string representation of the mutation
* operator
* @return A descriptive string.
@@ -66,12 +63,12 @@ public class MutateESSuccessRule extends MutateESStandard implements InterfaceMu
/** This method increases the mutation step size.
*/
public void increaseMutationStepSize() {
this.m_MutationStepSize = this.m_MutationStepSize * this.m_Alpha;
this.m_Sigma = this.m_Sigma * this.m_Alpha;
}
/** This method decrease the mutation step size.
*/
public void decreaseMutationStepSize() {
this.m_MutationStepSize = this.m_MutationStepSize / this.m_Alpha;
this.m_Sigma = this.m_Sigma / this.m_Alpha;
}
/**********************************************************************************************************************
@@ -121,6 +118,36 @@ public class MutateESSuccessRule extends MutateESStandard implements InterfaceMu
return this.m_Alpha;
}
public String alphaTipText() {
return "Choose the factor by which the mutation step size is to be increased/decreased.";
return "Choose the factor > 1 by which the mutation step size is to be increased/decreased.";
}
public void adaptAfterSelection(Population oldGen, Population selected) {
// nothing to do here
}
public void adaptGenerational(Population selectedPop, Population parentPop, Population newPop, boolean updateSelected) {
double rate = 0.;
for (int i = 0; i < parentPop.size(); i++) {
// calculate success rate
// System.out.println("new fit / old fit: " + BeanInspector.toString(newPop.getEAIndividual(i).getFitness()) + " , " + BeanInspector.toString(parentPop.getEAIndividual(i).getFitness()));
if (newPop.getEAIndividual(i).getFitness(0) < parentPop.getEAIndividual(i).getFitness(0)) rate++;
}
rate = rate / parentPop.size();
if (updateSelected) for (int i = 0; i < selectedPop.size(); i++) { // applied to the old population as well in case of plus strategy
MutateESSuccessRule mutator = (MutateESSuccessRule)((AbstractEAIndividual)selectedPop.get(i)).getMutationOperator();
updateMutator(rate, mutator);
// System.out.println("old pop step size " + mutator.getSigma()+ " (" + mutator+ ")");
}
for (int i = 0; i < newPop.size(); i++) {
MutateESSuccessRule mutator = (MutateESSuccessRule)((AbstractEAIndividual)newPop.get(i)).getMutationOperator();
updateMutator(rate, mutator);
// System.out.println("new pop step size " + mutator.getSigma()+ " (" + mutator+ ")");
}
}
private void updateMutator(double rate, MutateESSuccessRule mutator) {
if (rate < mutator.getSuccessRate()) mutator.decreaseMutationStepSize();
else mutator.increaseMutationStepSize();
}
}

View File

@@ -62,6 +62,14 @@ Serializable {
else convergenceCondition.setSelectedTag("Relative");
}
public FitnessConvergenceTerminator(FitnessConvergenceTerminator other) {
pMetric = new PhenotypeMetric();
convThresh = other.convThresh;
this.m_stagTime = other.m_stagTime;
stagnationMeasure.setSelectedTag(other.getStagnationMeasure().getSelectedTagID());
convergenceCondition.setSelectedTag(other.getConvergenceCondition().getSelectedTagID());
}
/**
*
*/

View File

@@ -941,6 +941,9 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
/**
* Fire an event every n function calls, the event sends the public String funCallIntervalReached.
* Be aware that if this interval is smaller than the population size, it may happen that a notification
* is fired before all individuals have been evaluated once, meaning that a false zero fitness
* appears at the beginning of the optimization.
*
* @param notifyEvalInterval the notifyEvalInterval to set
*/

View File

@@ -56,7 +56,7 @@ public abstract class AbstractOptimizationProblem implements InterfaceOptimizati
// System.err.println("Population evaluation seems not required!");
// } else {
// @todo This is the position to implement a granular
// @todo paralliziation scheme
// @todo paralleliziation scheme
evaluatePopulationStart(population);
for (int i = 0; i < population.size(); i++) {
tmpIndy = (AbstractEAIndividual) population.get(i);

View File

@@ -90,8 +90,10 @@ public class CHCAdaptiveSearchAlgorithm implements InterfaceOptimizer, java.io.S
System.out.println("Problem does not apply InterfaceGAIndividual, which is the only individual type valid for CHC!");
}
this.evaluatePopulation(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
if (reset) {
this.evaluatePopulation(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
}
}
/** This method will evaluate the current population using the

View File

@@ -124,9 +124,11 @@ public class ClusteringHillClimbing implements InterfacePopulationChangedEventLi
loopCnt = 0;
this.m_Population = (Population)pop.clone();
m_Population.addPopulationChangedEventListener(null);
if (reset) this.m_Population.init();
this.m_Problem.evaluate(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
if (reset) {
this.m_Population.init();
this.m_Problem.evaluate(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
}
}
/** Something has changed

View File

@@ -93,11 +93,13 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial
*/
public void initByPopulation(Population pop, boolean reset) {
this.m_Population = (Population)pop.clone();
if (reset) this.m_Population.init();
if (reset) {
this.m_Population.init();
this.evaluatePopulation(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
}
// if (reset) this.m_Population.init();
// else children = new Population(m_Population.size());
this.evaluatePopulation(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
}
/** This method will evaluate the current population using the

View File

@@ -1,7 +1,10 @@
package eva2.server.go.strategies;
import eva2.gui.BeanInspector;
import eva2.gui.GenericObjectEditor;
import eva2.server.go.InterfacePopulationChangedEventListener;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.operators.mutation.InterfaceMutationGenerational;
import eva2.server.go.operators.mutation.MutateESSuccessRule;
import eva2.server.go.operators.selection.InterfaceSelection;
import eva2.server.go.operators.selection.SelectBestIndividuals;
@@ -33,7 +36,6 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
//private double m_MyuRatio = 6;
private int m_Mu = 5;
private int m_Lambda = 20;
private int m_InitialPopulationSize = 0;
private boolean m_UsePlusStrategy = false;
private Population m_Population = new Population();
private InterfaceOptimizationProblem m_Problem = new B1Problem();
@@ -42,7 +44,7 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
private InterfaceSelection m_EnvironmentSelection = new SelectBestIndividuals();
private int m_NumberOfPartners = 1;
private int origPopSize = -1; // especially for CBN
private double[] m_FitnessOfParents = null;
// private double[] m_FitnessOfParents = null;
private boolean forceOrigPopSize = true;// especially for CBN
transient private String m_Identifier = "";
@@ -64,7 +66,6 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone();
this.m_Mu = a.m_Mu;
this.m_Lambda = a.m_Lambda;
this.m_InitialPopulationSize = a.m_InitialPopulationSize;
this.m_UsePlusStrategy = a.m_UsePlusStrategy;
this.m_NumberOfPartners = a.m_NumberOfPartners;
this.m_ParentSelection = (InterfaceSelection)a.m_ParentSelection.clone();
@@ -72,6 +73,10 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
this.m_EnvironmentSelection = (InterfaceSelection)a.m_EnvironmentSelection.clone();
}
public void hideHideable() {
GenericObjectEditor.setHideProperty(this.getClass(), "population", true);
}
public Object clone() {
return (Object) new EvolutionStrategies(this);
}
@@ -86,7 +91,7 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
this.m_Problem.initPopulation(this.m_Population);
this.evaluatePopulation(this.m_Population);
// this.m_Population.setPopulationSize(orgPopSize);
this.firePropertyChangedEvent("NextGenerationPerformed");
// this.firePropertyChangedEvent("NextGenerationPerformed");// not necessary if incrGeneration is called
}
@@ -98,9 +103,11 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
origPopSize = pop.getPopulationSize();
// System.out.println("ES: orig popsize is " + origPopSize);
this.m_Population = (Population)pop.clone();
if (reset) this.m_Population.init();
this.evaluatePopulation(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
if (reset) {
this.m_Population.init();
this.evaluatePopulation(this.m_Population);
// this.firePropertyChangedEvent("NextGenerationPerformed"); // not necessary if incrGeneration is called
}
}
/** This method will evaluate the current population using the
@@ -129,94 +136,88 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
/** This method will generate the offspring population from the
* given population of evaluated individuals.
*/
private Population generateChildren() {
Population result = this.m_Population.cloneWithoutInds(), parents;
protected Population generateEvalChildren(Population fromPopulation) {
Population result = m_Population.cloneWithoutInds(), parents;
AbstractEAIndividual[] offSprings;
AbstractEAIndividual tmpIndy;
result.clear();
this.m_ParentSelection.prepareSelection(this.m_Population);
this.m_PartnerSelection.prepareSelection(this.m_Population);
parents = this.m_ParentSelection.selectFrom(this.m_Population, this.m_Lambda);
this.m_ParentSelection.prepareSelection(fromPopulation);
this.m_PartnerSelection.prepareSelection(fromPopulation);
parents = this.m_ParentSelection.selectFrom(fromPopulation, this.m_Lambda);
for (int i = 0; i < parents.size(); i++) {
tmpIndy = (AbstractEAIndividual)parents.get(i);
if (tmpIndy == null) System.out.println("Individual null "+i);
if (parents == null) System.out.println("parents null "+i);
if (tmpIndy.getMutationOperator() instanceof MutateESSuccessRule) {
if (this.m_FitnessOfParents == null) this.m_FitnessOfParents = new double[this.m_Lambda];
this.m_FitnessOfParents[i] = tmpIndy.getFitness(0);
}
offSprings = tmpIndy.mateWith(this.m_PartnerSelection.findPartnerFor(tmpIndy, this.m_Population, this.m_NumberOfPartners));
// for (int j = 0; j < offSprings.length; j++) {
// offSprings[j].mutate();
// }
offSprings = tmpIndy.mateWith(this.m_PartnerSelection.findPartnerFor(tmpIndy, fromPopulation, this.m_NumberOfPartners));
offSprings[0].mutate();
result.add(i, offSprings[0]);
}
this.evaluatePopulation(result);
if (result.getEAIndividual(0).getMutationOperator() instanceof InterfaceMutationGenerational) {
// this seems to be the right moment for the 1/5-success rule
// parents and result have the same size and correspond per individual
((InterfaceMutationGenerational)parents.getEAIndividual(0).getMutationOperator()).adaptGenerational(fromPopulation, parents, result, m_UsePlusStrategy);
}
return result;
}
protected Population selectParents() {
this.m_EnvironmentSelection.prepareSelection(this.m_Population);
return this.m_EnvironmentSelection.selectFrom(this.m_Population, this.m_Mu);
}
/** The optimize method will compute a 'improved' and evaluated population
*/
public void optimize() {
Population nextGeneration, parents;
// // calculate myu and lambda from the current population size and settings
// if (this.m_UsePlusStrategy) {
// this.m_Myu = (int)Math.round((this.m_Population.size()/this.m_MyuRatio) - (this.m_Population.size()/Math.pow(this.m_MyuRatio, 2)));
// this.m_Myu = Math.max(1, this.m_Myu);
// this.m_Lambda = this.m_Population.size() - this.m_Myu;
//// System.out.println("Parameters: (Pop.size:"+this.m_Population.size()+"; MyuRatio:"+this.m_MyuRatio+")");
//// System.out.println("Population Strategy: ("+ this.m_Myu+"+"+this.m_Lambda+")");
// }
// else {
// this.m_Lambda = this.m_Population.size();
// this.m_Myu = (int)Math.round(this.m_Population.size()/this.m_MyuRatio);
// this.m_Myu = Math.max(1, this.m_Myu);
//// System.out.println("Parameters: (Pop.size:"+this.m_Population.size()+"; MyuRatio:"+this.m_MyuRatio+")");
//// System.out.println("Population Strategy: ("+ this.m_Myu+","+this.m_Lambda+")");
// }
//System.out.println("optimize");
// first perform the environment selection to select myu parents
this.m_EnvironmentSelection.prepareSelection(this.m_Population);
parents = this.m_EnvironmentSelection.selectFrom(this.m_Population, this.m_Mu);
this.m_Population.clear();
this.m_Population.addPopulation(parents);
parents = selectParents();
// System.out.println("-- selected avg fit " + BeanInspector.toString(parents.getMeanFitness()) + " from last gen " + BeanInspector.toString(m_Population.getMeanFitness()));
// m_Population / parents are of sizes lambda / mu
if (parents.getEAIndividual(0).getMutationOperator() instanceof InterfaceMutationGenerational) {
((InterfaceMutationGenerational)parents.getEAIndividual(0).getMutationOperator()).adaptAfterSelection(getPopulation(), parents);
}
// now generate the lambda offsprings
this.m_FitnessOfParents = null;
nextGeneration = this.generateChildren();
this.evaluatePopulation(nextGeneration);
if ((this.m_FitnessOfParents != null) && (((AbstractEAIndividual)parents.get(0)).getMutationOperator() instanceof MutateESSuccessRule)) {
double rate = 0;
for (int i = 0; i < this.m_FitnessOfParents.length; i++) {
if (((AbstractEAIndividual)nextGeneration.get(i)).getFitness(0) < this.m_FitnessOfParents[i]) rate++;
}
this.applySuccessRule((rate/((double)this.m_FitnessOfParents.length)), this.m_Population, nextGeneration);
}
if (this.m_UsePlusStrategy) nextGeneration.addPopulation(this.m_Population);
nextGeneration = this.generateEvalChildren(parents); // create lambda new ones from mu parents
if (forceOrigPopSize && (origPopSize > 0) && (origPopSize < nextGeneration.size())) {
// this is especially for CBN:
this.m_EnvironmentSelection.prepareSelection(nextGeneration);
Population tmpPop = (Population)nextGeneration.clone();
nextGeneration.clear();
nextGeneration.addPopulation(this.m_EnvironmentSelection.selectFrom(tmpPop, origPopSize));
// System.out.println("ES post selection! " + origPopSize + " from " + tmpPop.size());
m_Population = nextGeneration;
} else {
if ((origPopSize > 0) && (origPopSize != nextGeneration.size())) {
System.err.println("Warning in ES! orig: " + origPopSize + " / " + nextGeneration.size());
}
this.m_Population = nextGeneration;
}
//System.out.println("Population size: " + this.m_Population.size());
//System.out.println("-- Best Fitness " + this.m_Population.getBestFitness()[0]);
if (this.isPlusStrategy()) nextGeneration.addPopulation(parents);
setPop(getReplacePop(nextGeneration));
// System.out.println("Population size: " + this.m_Population.size());
// System.out.println("-- Best Fitness " + this.m_Population.getBestFitness()[0]);
this.firePropertyChangedEvent("NextGenerationPerformed");
this.firePropertyChangedEvent("NextGenerationPerformed"); // necessary here because evalPop was not called on m_Population
}
/**
* Usually, this just returns the given population.
* However, in case of CBN this method prepares the next generation according to the species size.
*
* @param nextGeneration
* @return
*/
protected Population getReplacePop(Population nextGeneration) {
if (forceOrigPopSize && (origPopSize > 0) && (origPopSize < nextGeneration.size())) {
// this is especially for CBN:
this.m_EnvironmentSelection.prepareSelection(nextGeneration);
Population tmpPop = (Population)nextGeneration.clone();
nextGeneration.clear();
nextGeneration.addPopulation(this.m_EnvironmentSelection.selectFrom(tmpPop, origPopSize));
// System.out.println("ES post selection! " + origPopSize + " from " + tmpPop.size());
} else {
if ((origPopSize > 0) && (origPopSize != nextGeneration.size())) {
System.err.println("Warning in ES! orig: " + origPopSize + " / " + nextGeneration.size());
}
}
return nextGeneration;
}
/** This method is just a shortcut to set the mutation step size for
@@ -227,46 +228,48 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
* @param oldPop The old population
* @param newPop The new population
*/
private void applySuccessRule(double successRate, Population oldPop, Population newPop) {
MutateESSuccessRule mutator = (MutateESSuccessRule)((AbstractEAIndividual)oldPop.get(0)).getMutationOperator();
boolean success = (successRate < mutator.getSuccessRate());
// this was the old solution when the mutation step size was still static
// if (successRate < mutator.getSuccessRate()) {
// mutator.decreaseMutationStepSize();
// } else {
// mutator.increaseMutationStepSize();
// private void applySuccessRule(double successRate, Population oldPop, Population newPop) {
// MutateESSuccessRule mutator = (MutateESSuccessRule)((AbstractEAIndividual)oldPop.get(0)).getMutationOperator();
// boolean success = (successRate < mutator.getSuccessRate());
// // this was the old solution when the mutation step size was still static
//// if (successRate < mutator.getSuccessRate()) {
//// mutator.decreaseMutationStepSize();
//// } else {
//// mutator.increaseMutationStepSize();
//// }
// if (isPlusStrategy()) for (int i = 0; i < oldPop.size(); i++) { // applied to the old population as well for plus strategy
// if (((AbstractEAIndividual)oldPop.get(i)).getMutationOperator() instanceof MutateESSuccessRule) {
// mutator = (MutateESSuccessRule)((AbstractEAIndividual)oldPop.get(i)).getMutationOperator();
// if (success) mutator.decreaseMutationStepSize();
// else mutator.increaseMutationStepSize();
// System.out.println("old pop step size " + mutator.getSigma()+ " (" + mutator+ ")");
// }
// }
for (int i = 0; i < oldPop.size(); i++) {
if (((AbstractEAIndividual)oldPop.get(i)).getMutationOperator() instanceof MutateESSuccessRule) {
mutator = (MutateESSuccessRule)((AbstractEAIndividual)oldPop.get(i)).getMutationOperator();
if (success) mutator.decreaseMutationStepSize();
else mutator.increaseMutationStepSize();
}
}
for (int i = 0; i < newPop.size(); i++) {
if (((AbstractEAIndividual)newPop.get(i)).getMutationOperator() instanceof MutateESSuccessRule) {
mutator = (MutateESSuccessRule)((AbstractEAIndividual)newPop.get(i)).getMutationOperator();
if (success) mutator.decreaseMutationStepSize();
else mutator.increaseMutationStepSize();
}
}
this.m_FitnessOfParents = null;
}
// for (int i = 0; i < newPop.size(); i++) {
// if (((AbstractEAIndividual)newPop.get(i)).getMutationOperator() instanceof MutateESSuccessRule) {
// mutator = (MutateESSuccessRule)((AbstractEAIndividual)newPop.get(i)).getMutationOperator();
// if (success) mutator.decreaseMutationStepSize();
// else mutator.increaseMutationStepSize();
// System.out.println("new pop step size " + mutator.getSigma() + " (" + mutator+ ")");
// }
// }
//// this.m_FitnessOfParents = null;
// }
/** This is for debugging only
*/
private String showFitness(Population pop) {
String result = "";
AbstractEAIndividual indy;
double[] fitness;
for (int i = 0; i < pop.size(); i++) {
indy = (AbstractEAIndividual)pop.get(i);
fitness = indy.getFitness();
for (int j = 0; j < fitness.length; j++) result += fitness[j] +"; ";
result += "\n";
}
return result;
}
// /** This is for debugging only
// */
// private String showFitness(Population pop) {
// String result = "";
// AbstractEAIndividual indy;
// double[] fitness;
// for (int i = 0; i < pop.size(); i++) {
// indy = (AbstractEAIndividual)pop.get(i);
// fitness = indy.getFitness();
// for (int j = 0; j < fitness.length; j++) result += fitness[j] +"; ";
// result += "\n";
// }
// return result;
// }
/** This method allows you to add the LectureGUI as listener to the Optimizer
* @param ea
@@ -276,7 +279,7 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
}
/** Something has changed
*/
protected void firePropertyChangedEvent (String name) {
protected void firePropertyChangedEvent(String name) {
if (this.m_Listener != null) this.m_Listener.registerPopulationStateChanged(this, name);
}
@@ -354,7 +357,7 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
* @return The name of the algorithm
*/
public String getName() {
return "("+getMu()+(getPlusStrategy() ? "+" : ",")+getLambda()+")-ES";
return "("+getMu()+(isPlusStrategy() ? "+" : ",")+getLambda()+")-ES";
}
/**
@@ -366,6 +369,12 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
public Population getPopulation() {
return this.m_Population;
}
// for internal usage
protected void setPop(Population pop) {
m_Population = pop;
}
public void setPopulation(Population pop){
origPopSize = pop.size();
// System.out.println("ES: orig popsize is " + origPopSize);
@@ -437,7 +446,7 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
this.m_UsePlusStrategy = elitism;
this.checkPopulationConstraints();
}
public boolean getPlusStrategy() {
public boolean isPlusStrategy() {
return this.m_UsePlusStrategy;
}
public String plusStrategyTipText() {
@@ -513,17 +522,4 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
public String lambdaTipText() {
return "This is the children population size.";
}
/** Set an initial population size (if smaller lambda this is ignored).
* @param l The inital population size.
*/
public void setInitialPopulationSize(int l) {
this.m_InitialPopulationSize = l;
}
public int getInitialPopulationSize() {
return this.m_InitialPopulationSize;
}
public String initialPopulationSizeTipText() {
return "Set an initial population size (if smaller lambda this is ignored).";
}
}

View File

@@ -0,0 +1,251 @@
package eva2.server.go.strategies;
import java.util.Arrays;
import java.util.LinkedList;
import eva2.gui.GenericObjectEditor;
import eva2.server.go.InterfacePopulationChangedEventListener;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.operators.mutation.MutateESRankMuCMA;
import eva2.server.go.operators.terminators.FitnessConvergenceTerminator;
import eva2.server.go.populations.Population;
import eva2.server.go.populations.SolutionSet;
/**
* This implements the IPOP (increased population size restart) strategy ES, which increases
* the ES population size (lambda) after phases or stagnation and restarts the optimization.
* Stagnation is for this implementation defined by a FitnessConvergenceTerminator instance
* which terminates if the absolute change in fitness is below a threshold (default 10e-12) for a
* certain number of generations (default: 10+floor(30*n/lambda) for problem dimension n).
*
* If the MutateESRankMuCMA mutation operator is used, additional criteria are used for restarts,
* such as numeric conditions of the covariance matrix.
* Lambda is increased multiplicatively for every restart, and typical initial values are
* mu=5, lambda=10, incFact=2.
* The IPOP-CMA-ES won the CEC 2005 benchmark challenge.
* Refer to Auger&Hansen 05 for more details.
*
* A.Auger & N.Hansen. A Restart CMA Evolution Strategy With Increasing Population Size. CEC 2005.
*
* @author mkron
*
*/
public class EvolutionStrategyIPOP extends EvolutionStrategies implements InterfacePopulationChangedEventListener {
private static final long serialVersionUID = 4102736881931867818L;
int dim = -1;
int initialLambda = 10;
private double stagThreshold = 10e-12;
private int stagTime = -1;
double incPopSizeFact = 2.;
FitnessConvergenceTerminator fitConvTerm = null;
LinkedList<AbstractEAIndividual> bestList = null;
AbstractEAIndividual best = null;
public EvolutionStrategyIPOP() {
super();
setMu(5);
setLambda(10);
}
public EvolutionStrategyIPOP(EvolutionStrategyIPOP other) {
dim = other.dim;
initialLambda = other.initialLambda;
incPopSizeFact = other.incPopSizeFact;
stagThreshold = other.stagThreshold;
stagTime = other.stagTime;
if (other.fitConvTerm != null) fitConvTerm = new FitnessConvergenceTerminator(other.fitConvTerm);
}
public Object clone() {
return new EvolutionStrategyIPOP(this);
}
/** The optimize method will compute a 'improved' and evaluated population
*/
public void optimize() {
// Population nextGeneration, parents;
//
// // first perform the environment selection to select myu parents
// parents = selectParents();
//
// // m_Population / parents are of sizes lambda / mu
// if (parents.getEAIndividual(0).getMutationOperator() instanceof InterfaceMutationGenerational) {
// ((InterfaceMutationGenerational)parents.getEAIndividual(0).getMutationOperator()).adaptAfterSelection(getPopulation(), parents);
// }
//
// // now generate the lambda offsprings
// nextGeneration = this.generateEvalChildren(parents); // create lambda new ones from mu parents
//
// if (this.isPlusStrategy()) nextGeneration.addPopulation(parents);
//
// setPop(getReplacePop(nextGeneration));
//
// this.firePropertyChangedEvent("NextGenerationPerformed");
//////////////////////////
super.optimize();
// remember the best indy
if ((best == null) || !best.isDominating(getPopulation().getBestEAIndividual())) {
best = getPopulation().getBestEAIndividual();
}
if (testIPOPStopCrit(getPopulation())) {
// reinitialize population with increased mu,lambda
boostPopSize();
}
}
public void hideHideable() {
GenericObjectEditor.setHideProperty(this.getClass(), "population", true);
}
/**
* Reinitialize population with increased mu,lambda
**/
private void boostPopSize() {
// increase by at least one
int newLambda = Math.max((int)(getLambda()*incPopSizeFact), getLambda() + 1);
super.setLambda(newLambda);
bestList.add(best);
best = null;
Population newPop = getPopulation().cloneWithoutInds();
getProblem().initPopulation(newPop);
double[] badFit = getPopulation().getBestFitness().clone();
Arrays.fill(badFit, Double.MAX_VALUE);
newPop.setAllFitnessValues(badFit);
getPopulation().clear();
getPopulation().addAll(newPop);
getProblem().evaluate(getPopulation());
}
protected void firePropertyChangedEvent(String name) {
if (name.equals(Population.funCallIntervalReached)) {
super.firePropertyChangedEvent("NextGenerationPerformed");
}
else {} // nothing, evt is produced in #registerPopulationStateChanged, dont forward original due to changing pop size
}
public void init() {
// setMu(initialMu);
super.setLambda(initialLambda);
getPopulation().setNotifyEvalInterval(initialLambda);
super.init();
bestList = new LinkedList<AbstractEAIndividual>();
best = getPopulation().getBestEAIndividual();
dim = AbstractEAIndividual.getDoublePosition(getPopulation().getEAIndividual(0)).length;
stagTime = (int)(10+Math.floor(30*dim/getPopulation().size()));
fitConvTerm = new FitnessConvergenceTerminator(stagThreshold, stagTime, false, true); // gen. based, absolute
getPopulation().addPopulationChangedEventListener(this);
getPopulation().setNotifyEvalInterval(initialLambda);
}
/**
* Test for the IPOP stopping criteria.
* @param population
* @return
*/
private boolean testIPOPStopCrit(Population pop) {
int curGen = pop.getGeneration();
MutateESRankMuCMA rcmaMute = null;
if (pop.getEAIndividual(0).getMutationOperator() instanceof MutateESRankMuCMA) {
rcmaMute = (MutateESRankMuCMA)pop.getEAIndividual(0).getMutationOperator();
}
// stop if the range of the best fitness of the last 10 + flor(30 n /lambda) generations is zero
// or if the range of these values and all fit values of the recent generation is below Tolfun = 10^-12
//// interpret it a bit differently using FitnessConvergenceTerminator
if (fitConvTerm.isTerminated(new SolutionSet(pop))) {
return true;
}
if (rcmaMute != null) {
// stop if the std dev of the normal distribution is smaller than TolX in all coords
// and sigma p_c is smaller than TolX in all components; TolX = 10^-12 sigma_0
if (rcmaMute.testAllDistBelow(10e-12*rcmaMute.getFirstSigma())) return true;
// stop if adding a 0.1 std dev vector in a principal axis dir. of C does not change <x>_w^g
if (rcmaMute.testNoChangeAddingDevAxis(0.1, curGen)) return true;
// stop if adding a 0.2 std dev in each coordinate does (not???) change <x>_w^g
if (rcmaMute.testNoEffectCoord(0.2)) return true;
// stop if the condition number of C exceeds 10^14
if (rcmaMute.testCCondition(10e14)) return true;
}
return false;
}
/**
* Returns the current population and a set of best individuals found (best current
* and best single ones before
* reinitializing the population after boosting the population size).
*
* @return A solution set of the current population and possibly earlier solutions
*/
public SolutionSet getAllSolutions() {
Population sols = getPopulation().cloneWithoutInds();
if (bestList != null) sols.addAll(bestList);
if (best != null) sols.add(best);
else sols.add(getPopulation().getBestEAIndividual());
SolutionSet solSet = new SolutionSet(getPopulation(), sols);
return solSet;
}
public void registerPopulationStateChanged(Object source, String name) {
if (name.equals(Population.funCallIntervalReached)) {
getPopulation().SetFunctionCalls(((Population)source).getFunctionCalls()); // TODO this is ugly
super.firePropertyChangedEvent(name);
} else {
// System.err.println("Not forwarding event " + name);
}
}
public String getName() {
return "ES-IPOP";
}
public String globalInfo() {
return "An ES with increasing population size.";
}
/** Set an initial population size (if smaller lambda this is ignored).
* @param l The inital population size.
*/
public void setInitialLambda(int l) {
initialLambda = l;
if (initialLambda < getMu()) setMu((initialLambda/2)+1);
}
public int getInitialLambda() {
return initialLambda;
}
public String initialLambdaTipText() {
return "Set the initial population size (lambda); mu should be about lambda/2";
}
/**
* @return the incPopSizeFact
*/
public double getIncPopSizeFact() {
return incPopSizeFact;
}
/**
* @param incPopSizeFact the incPopSizeFact to set
*/
public void setIncPopSizeFact(double incPopSizeFact) {
this.incPopSizeFact = incPopSizeFact;
}
public String incPopSizeFactTipText() {
return "Factor by which to increase lambda for each restart event, default is 2.";
}
}

View File

@@ -58,9 +58,11 @@ public class EvolutionaryProgramming implements InterfaceOptimizer, java.io.Seri
*/
public void initByPopulation(Population pop, boolean reset) {
this.m_Population = (Population)pop.clone();
if (reset) this.m_Population.init();
this.evaluatePopulation(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
if (reset) {
this.m_Population.init();
this.evaluatePopulation(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
}
}
/** This method will evaluate the current population using the

View File

@@ -67,10 +67,12 @@ public class FloodAlgorithm implements InterfaceOptimizer, java.io.Serializable
*/
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);
if (reset) {
this.m_Population.init();
this.m_Problem.evaluate(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
}
this.m_CurrentFloodPeak = this.m_InitialFloodPeak;
this.firePropertyChangedEvent("NextGenerationPerformed");
}
/** This method will optimize

View File

@@ -3,6 +3,7 @@ package eva2.server.go.strategies;
import eva2.server.go.InterfacePopulationChangedEventListener;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.GAIndividualBinaryData;
import eva2.server.go.operators.mutation.InterfaceMutationGenerational;
import eva2.server.go.operators.selection.InterfaceSelection;
import eva2.server.go.operators.selection.SelectTournament;
import eva2.server.go.populations.InterfaceSolutionSet;
@@ -66,9 +67,11 @@ public class GeneticAlgorithm implements InterfaceOptimizer, java.io.Serializabl
*/
public void initByPopulation(Population pop, boolean reset) {
this.m_Population = (Population)pop.clone();
if (reset) this.m_Population.init();
this.evaluatePopulation(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
if (reset) {
this.m_Population.init();
this.evaluatePopulation(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
}
}
/** This method will evaluate the current population using the
@@ -110,6 +113,10 @@ public class GeneticAlgorithm implements InterfaceOptimizer, java.io.Serializabl
parents = this.m_ParentSelection.selectFrom(this.m_Population, this.m_Population.getPopulationSize());
//System.out.println("Parents:"+parents.getSolutionRepresentationFor());
if (parents.getEAIndividual(0).getMutationOperator() instanceof InterfaceMutationGenerational) {
((InterfaceMutationGenerational)parents.getEAIndividual(0).getMutationOperator()).adaptAfterSelection(m_Population, parents);
}
for (int i = 0; i < parents.size(); i++) {
tmpIndy = ((AbstractEAIndividual)parents.get(i));
if (tmpIndy == null) System.out.println("Individual null " + i + " Population size: "+ parents.size());
@@ -121,13 +128,18 @@ public class GeneticAlgorithm implements InterfaceOptimizer, java.io.Serializabl
}
result.add(i, offSprings[0]);
}
this.evaluatePopulation(result);
if (parents.getEAIndividual(0).getMutationOperator() instanceof InterfaceMutationGenerational) {
((InterfaceMutationGenerational)parents.getEAIndividual(0).getMutationOperator()).adaptGenerational(m_Population, parents, result, true);
}
return result;
}
public void optimize() {
Population nextGeneration;
nextGeneration = this.generateChildren();
this.evaluatePopulation(nextGeneration);
if (this.m_UseElitism) {
AbstractEAIndividual elite = this.m_Population.getBestEAIndividual();
if (elite != null) {

View File

@@ -53,9 +53,11 @@ public class GradientDescentAlgorithm implements InterfaceOptimizer, java.io.Ser
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");
if (reset) {
this.getPopulation().init();
this.m_Problem.evaluate(this.getPopulation());
this.firePropertyChangedEvent("NextGenerationPerformed");
}
//System.out.println("initByPopulation() called");
indyhash = new Hashtable();
}

View File

@@ -58,15 +58,13 @@ public class HillClimbing implements InterfaceOptimizer, java.io.Serializable {
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");
if (reset) {
this.m_Population.init();
this.m_Problem.evaluate(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
}
}
/** This method will optimize

View File

@@ -38,9 +38,11 @@ public interface InterfaceOptimizer {
*/
public void init();
/** This method will init the optimizer with a given population
/**
* This method will init the optimizer with a given population.
*
* @param pop The initial population
* @param reset If true the population is reset.
* @param reset If true the population is reinitialized and reevaluated.
*/
public void initByPopulation(Population pop, boolean reset);
@@ -66,7 +68,7 @@ public interface InterfaceOptimizer {
* May return the the same set as getPopulation if the optimizer makes no distinction, i.e. does
* not collect solutions outside the current population.
*
* @return A population of found solutions.
* @return A solution set of the current population and possibly earlier solutions.
*/
public InterfaceSolutionSet getAllSolutions();

View File

@@ -142,6 +142,7 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I
* @param reset If true the population is reset.
*/
public void initByPopulation(Population tpop, boolean reset) {
// TODO this is again evil copy&paste style
if (this.m_Show) {
if (this.m_Plot == null) {
double[] tmpD = new double[2];
@@ -152,8 +153,10 @@ public class IslandModelEA implements InterfacePopulationChangedEventListener, I
}
this.m_Population = (Population)tpop.clone();
if (reset) this.m_Population.init();
this.m_Population.incrGeneration();
if (reset) {
this.m_Population.init();
this.m_Population.incrGeneration();
}
this.m_Optimizer.init();
this.m_Optimizer.SetProblem(this.m_Problem);
InterfacePopulationChangedEventListener myLocal = null;

View File

@@ -89,9 +89,11 @@ public class MemeticAlgorithm implements InterfaceOptimizer,
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");
if (reset) {
this.getPopulation().init();
this.m_Problem.evaluate(this.getPopulation());
this.firePropertyChangedEvent("NextGenerationPerformed");
}
}
public void init() {

View File

@@ -64,9 +64,11 @@ public class MonteCarloSearch implements InterfaceOptimizer, java.io.Serializabl
*/
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");
if (reset) {
this.m_Population.init();
this.m_Problem.evaluate(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
}
}
/** This method will optimize

View File

@@ -85,9 +85,11 @@ public class ParticleFilterOptimization implements InterfaceOptimizer, java.io.S
*/
public void initByPopulation(Population pop, boolean reset) {
this.m_Population = (Population)pop.clone();
if (reset) this.m_Population.init();
this.evaluatePopulation(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
if (reset) {
this.m_Population.init();
this.evaluatePopulation(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
}
}
/** This method will evaluate the current population using the

View File

@@ -372,7 +372,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
indy.SetData(indexKey, i);
indy.setIndividualIndex(i);
}
this.evaluatePopulation(this.m_Population);
if (reset) this.evaluatePopulation(this.m_Population);
for (int i = 0; i < this.m_Population.size(); i++) {
indy = (AbstractEAIndividual) this.m_Population.get(i);
@@ -382,7 +382,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
}
this.m_BestIndividual = (AbstractEAIndividual)this.m_Population.getBestEAIndividual().clone();
this.firePropertyChangedEvent("NextGenerationPerformed");
if (reset) this.firePropertyChangedEvent("NextGenerationPerformed");
treeLevels = 0;
// the HPSO tree will contain layers 0...HPSOLevels, the last one is "incomplete" with only HPSOOrphans number of nodes

View File

@@ -72,10 +72,12 @@ public class PopulationBasedIncrementalLearning implements InterfaceOptimizer, j
System.err.println("Error: PBIL only works with GAIndividuals!");
}
this.m_Population = new PBILPopulation();
if (reset) this.m_Population.init();
this.m_Population.addPopulation((Population)pop.clone());
if (reset) {
this.m_Population.init();
this.evaluatePopulation(this.m_Population);
}
((PBILPopulation)this.m_Population).buildProbabilityVector();
this.evaluatePopulation(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
}

View File

@@ -67,10 +67,12 @@ public class SimulatedAnnealing implements InterfaceOptimizer, java.io.Serializa
*/
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_CurrentTemperature = this.m_InitialTemperature;
this.firePropertyChangedEvent("NextGenerationPerformed");
if (reset) {
this.m_Population.init();
this.m_Problem.evaluate(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
}
}
/** This method will optimize

View File

@@ -62,9 +62,11 @@ public class SteadyStateGA implements InterfaceOptimizer, java.io.Serializable {
*/
public void initByPopulation(Population pop, boolean reset) {
this.m_Population = (Population)pop.clone();
if (reset) this.m_Population.init();
this.evaluatePopulation(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
if (reset) {
this.m_Population.init();
this.evaluatePopulation(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
}
}
/** This method will evaluate the current population using the

View File

@@ -65,10 +65,12 @@ public class ThresholdAlgorithm implements InterfaceOptimizer, java.io.Serializa
*/
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");
if (reset) {
this.m_Population.init();
this.m_Problem.evaluate(this.m_Population);
this.firePropertyChangedEvent("NextGenerationPerformed");
}
}
/** This method will optimize

View File

@@ -240,6 +240,11 @@ public class Tribes implements InterfaceOptimizer, java.io.Serializable {
}
/**
* As TRIBES manages an own structured set of particles (the list of Tribes containing explorers
* and memories), the setPopulation method is only telling Tribes the range
* of the indiviuals in the beginning of the run, the individuals will be discarded.
*/
public void initByPopulation(Population pop, boolean reset) {
setPopulation(pop);
}

View File

@@ -675,4 +675,16 @@ public class Mathematics {
}
return A;
}
public static double max(double[] vals) {
double maxVal = vals[0];
for (int i=1; i<vals.length; i++) maxVal = Math.max(maxVal, vals[i]);
return maxVal;
}
public static double min(double[] vals) {
double minVal = vals[0];
for (int i=1; i<vals.length; i++) minVal = Math.min(minVal, vals[i]);
return minVal;
}
}

View File

@@ -9,9 +9,9 @@ import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Locale;
import eva2.gui.BeanInspector;
import wsi.ra.math.Jama.util.Maths;
import eva2.gui.BeanInspector;
import eva2.tools.Pair;
/**
@@ -260,6 +260,17 @@ public class Matrix implements Cloneable, java.io.Serializable {
return vals;
}
/** Copy a column from the matrix.
@return Matrix elements packed in a one-dimensional array by columns.
*/
public double[] getColumn(int k) {
double[] vals = new double[m];
for (int i = 0; i < m; i++) {
vals[i] = A[i][k];
}
return vals;
}
/** Make a one-dimensional row packed copy of the internal array.
@return Matrix elements packed in a one-dimensional array by rows.
*/
@@ -764,6 +775,34 @@ public class Matrix implements Cloneable, java.io.Serializable {
return X;
}
/** Multiply a matrix by a vector, returning A*v.
*
@param v vector
@return result vector
*/
public double[] times (double[] v) {
// m: no rows
double[] result = new double[m];
times(v, result);
return result;
}
/** Multiply a matrix by a vector in place, result=A*v.
*
@param v vector
@param result
@return result vector
*/
public void times (double[] v, double[] result) {
// m: no rows
for (int i = 0; i < m; i++) {
result[i] = 0;
for (int j = 0; j < n; j++) {
result[i] += get(i,j)*v[j];
}
}
}
public String toString() {
StringBuffer sb = new StringBuffer();
for (int i=0; i<m; i++) {
@@ -976,6 +1015,25 @@ public class Matrix implements Cloneable, java.io.Serializable {
return A;
}
/**
* Return the minimum and maximum value on the diagonal
* as a pair.
*
* @return
*/
public Pair<Double,Double> getMinMaxDiag() {
if (m<1 || n<1) return null;
double v = get(0,0);
Pair<Double,Double> ret = new Pair<Double,Double>(v,v);
for (int i=1; i<Math.min(m,n); i++) {
v = get(i,i);
ret.head = Math.min(ret.head, v);
ret.tail = Math.max(ret.tail, v);
}
return ret;
}
/** Print the matrix to stdout. Line the elements up in columns
* with a Fortran-like 'Fw.d' style format.