Changes from MK branch rev 190-195, mainly cosmetics, some more enums, DE may do range checking, IPOP-CMA-ES works better from Matlab.

This commit is contained in:
Marcel Kronfeld 2008-09-11 13:27:53 +00:00
parent 49911cdcfd
commit 1782c0a4a7
23 changed files with 669 additions and 256 deletions

View File

@ -4,13 +4,13 @@ package eva2;
* Main product and version information strings.
*
* --- Changelog
* 2.030: Added an EnumEditor to access enums easily through the GUI.
* 2.030: Added an EnumEditor to access enums easily through the GUI, which will replace SelectedTags sometimes.
* IPOP-ES and RankMuCMA mutator have been added lately (wow!).
* Cleaned up the IndividualInterface and reduced the usage of InterfaceESIndividual. This
* means that, e.g., that DE and PSO now also work on GAIndividualDoubleData. Because this
* requires much time for transcoding, however, this is not useful by itself. Yet it could be
* interesting for combined individuals composed of two data types.
* Cleaned up MutateXXDefault to a single MutateDefault, too.
* Cleaned up MutateXXDefault to a single MutateDefault, too. DE may now do range checking.
* 2.029: Tuned the 2d-graphs which now paints quicker and changes size depending on the
* surrounding plot window. Added a preloader-thread to accelerate the GUI at starting time.
* 2.028: Tuned the Population to sort only when necessary on calls to getBestN... Added StatisticsDummy.

View File

@ -9,6 +9,7 @@ import java.util.Vector;
import eva2.server.go.IndividualInterface;
import eva2.server.go.InterfacePopulationChangedEventListener;
import eva2.server.go.InterfaceTerminator;
import eva2.server.go.enums.DETypeEnum;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeBinary;
import eva2.server.go.individuals.InterfaceDataTypeDouble;
@ -25,10 +26,12 @@ import eva2.server.go.operators.mutation.InterfaceMutation;
import eva2.server.go.operators.mutation.MutateESCovarianceMatrixAdaption;
import eva2.server.go.operators.mutation.MutateESFixedStepSize;
import eva2.server.go.operators.mutation.MutateESGlobal;
import eva2.server.go.operators.mutation.MutateESRankMuCMA;
import eva2.server.go.operators.mutation.NoMutation;
import eva2.server.go.operators.postprocess.InterfacePostProcessParams;
import eva2.server.go.operators.postprocess.PostProcessParams;
import eva2.server.go.operators.selection.InterfaceSelection;
import eva2.server.go.operators.selection.SelectBestIndividuals;
import eva2.server.go.operators.terminators.CombinedTerminator;
import eva2.server.go.operators.terminators.EvaluationTerminator;
import eva2.server.go.operators.terminators.FitnessConvergenceTerminator;
@ -38,6 +41,7 @@ import eva2.server.go.strategies.ClusterBasedNichingEA;
import eva2.server.go.strategies.ClusteringHillClimbing;
import eva2.server.go.strategies.DifferentialEvolution;
import eva2.server.go.strategies.EvolutionStrategies;
import eva2.server.go.strategies.EvolutionStrategyIPOP;
import eva2.server.go.strategies.GeneticAlgorithm;
import eva2.server.go.strategies.GradientDescentAlgorithm;
import eva2.server.go.strategies.HillClimbing;
@ -96,6 +100,8 @@ public class OptimizerFactory {
public final static int CBN_ES = 9;
public final static int CL_HILLCL = 10;
public final static int CMA_ES_IPOP = 11;
public final static int defaultFitCalls = 10000;
@ -121,69 +127,6 @@ public class OptimizerFactory {
newTerm, bAnd));
}
public static final GOParameters cbnES(AbstractOptimizationProblem problem) {
ClusterBasedNichingEA cbn = new ClusterBasedNichingEA();
EvolutionStrategies es = new EvolutionStrategies();
es.setMu(15);
es.setLambda(50);
es.setPlusStrategy(false);
cbn.setOptimizer(es);
ClusteringDensityBased clustering = new ClusteringDensityBased(0.1);
cbn.setConvergenceCA((ClusteringDensityBased) clustering.clone());
cbn.setDifferentationCA(clustering);
cbn.setShowCycle(0); // don't do graphical output
Population pop = new Population();
pop.setPopulationSize(100);
problem.initPopulation(pop);
return makeParams(cbn, pop, problem, randSeed, defaultTerminator());
}
public static final GOParameters clusteringHillClimbing(
AbstractOptimizationProblem problem) {
ClusteringHillClimbing chc = new ClusteringHillClimbing();
chc.SetProblem(problem);
Population pop = new Population();
pop.setPopulationSize(100);
problem.initPopulation(pop);
chc.setHcEvalCycle(1000);
chc.setInitialPopSize(100);
chc.setStepSizeInitial(0.05);
chc.setMinImprovement(0.000001);
chc.setNotifyGuiEvery(0);
chc.setStepSizeThreshold(0.000001);
chc.setSigmaClust(0.05);
return makeParams(chc, pop, problem, randSeed, defaultTerminator());
}
public static final GOParameters cmaES(AbstractOptimizationProblem problem) {
EvolutionStrategies es = new EvolutionStrategies();
es.setMu(15);
es.setLambda(50);
es.setPlusStrategy(false);
AbstractEAIndividual indyTemplate = problem.getIndividualTemplate();
if ((indyTemplate != null)
&& (indyTemplate instanceof InterfaceESIndividual)) {
// Set CMA operator for mutation
AbstractEAIndividual indy = (AbstractEAIndividual) indyTemplate;
MutateESCovarianceMatrixAdaption cmaMut = new MutateESCovarianceMatrixAdaption();
cmaMut.setCheckConstraints(true);
indy.setMutationOperator(cmaMut);
indy.setCrossoverOperator(new CrossoverESDefault());
} else {
System.err
.println("Error, CMA-ES is implemented for ES individuals only (requires double data types)");
return null;
}
Population pop = new Population();
pop.setPopulationSize(es.getLambda());
return makeParams(es, pop, problem, randSeed, defaultTerminator());
}
/**
* This method optimizes the given problem using differential evolution.
*
@ -211,7 +154,7 @@ public class OptimizerFactory {
DifferentialEvolution de = new DifferentialEvolution();
de.SetProblem(problem);
de.getPopulation().setPopulationSize(popsize);
de.getDEType().setSelectedTag(1);
de.setDEType(DETypeEnum.DE2_CurrentToBest);
de.setF(f);
de.setK(CR);
de.setLambda(lambda);
@ -232,38 +175,69 @@ public class OptimizerFactory {
* @param pm
* @param crossoveroperator
* @param pc
* @param selection
* @param selection environmental selection operator
* @param problem
* @param listener
* @return An optimization algorithm that employes an evolution strategy.
* @return An optimization algorithm that employs an evolution strategy.
*/
public static final EvolutionStrategies createEvolutionStrategy(int mu,
int lambda, boolean plus, InterfaceMutation mutationoperator,
double pm, InterfaceCrossover crossoveroperator, double pc,
InterfaceSelection selection, AbstractOptimizationProblem problem,
InterfacePopulationChangedEventListener listener) {
return createES(new EvolutionStrategies(mu, lambda, plus), mutationoperator, pm, crossoveroperator, pc, selection, problem, listener);
}
/**
* This method initializes the optimization using an Evolution strategy with
* increasing population size.
*
* @param mu
* @param lambda
* @param plus
* if true this operator uses elitism otherwise a comma strategy.
* @param mutationoperator
* @param pm
* @param crossoveroperator
* @param pc
* @param incPopSizeFact factor by which to inrease lambda ro restart, default is 2
* @param stagThresh if the fitness changes below this value during a stagnation phase, a restart is initiated
* @param problem
* @param listener
* @return An optimization algorithm that employs an IPOP-ES.
*/
public static final EvolutionStrategyIPOP createEvolutionStrategyIPOP(int mu,
int lambda, boolean plus, InterfaceMutation mutationoperator,
double pm, InterfaceCrossover crossoveroperator, double pc, double incPopSizeFact, double stagThresh,
AbstractOptimizationProblem problem, InterfacePopulationChangedEventListener listener) {
EvolutionStrategyIPOP esIPOP = (EvolutionStrategyIPOP)createES(new EvolutionStrategyIPOP(mu, lambda, plus), mutationoperator, pm, crossoveroperator, pc, new SelectBestIndividuals(), problem, listener);
esIPOP.setIncPopSizeFact(incPopSizeFact);
// esIPOP.setStagnationGenerations(stagTimeGens);
esIPOP.setStagThreshold(stagThresh);
return esIPOP;
}
private static final EvolutionStrategies createES(EvolutionStrategies theES, InterfaceMutation mutationoperator,
double pm, InterfaceCrossover crossoveroperator, double pc,
InterfaceSelection selection, AbstractOptimizationProblem problem,
InterfacePopulationChangedEventListener listener) {
problem.initProblem();
// RNG.setRandomSeed(100);
AbstractEAIndividual tmpIndi = problem.getIndividualTemplate();
tmpIndi.setMutationOperator(mutationoperator);
tmpIndi.setMutationProbability(pm);// */ // 1/tmpIndi.size()
tmpIndi.setCrossoverOperator(crossoveroperator);
tmpIndi.setCrossoverProbability(pc);// */ // 0.95
AbstractEAIndividual.setOperators(tmpIndi, mutationoperator, pm, crossoveroperator, pc);
EvolutionStrategies es = new EvolutionStrategies();
es.addPopulationChangedEventListener(listener);
es.setParentSelection(selection);
es.setPartnerSelection(selection);
//es.setParentSelection(selection);
//es.setPartnerSelection(selection);
es.setEnvironmentSelection(selection);
es.setGenerationStrategy(mu, lambda, plus); // comma strategy
es.SetProblem(problem);
es.init();
return es;
return theES;
}
/**
* This method performs a Genetic Algorithm.
*
@ -544,6 +518,13 @@ public class OptimizerFactory {
// /////////////////////////// constructing a default OptimizerRunnable
/**
* For an optimizer identifier, return the corresponding default parameter set including
* initialization (thats why the problem is required).
*
* @param optType optimizer identifier
* @param problem corresponding optimization problem
*/
public static GOParameters getParams(final int optType,
AbstractOptimizationProblem problem) {
switch (optType) {
@ -567,6 +548,8 @@ public class OptimizerFactory {
return cbnES(problem);
case CL_HILLCL:
return clusteringHillClimbing(problem);
case CMA_ES_IPOP:
return cmaESIPOP(problem);
default:
System.err.println("Error: optimizer type " + optType
+ " is unknown!");
@ -574,6 +557,27 @@ public class OptimizerFactory {
}
}
/**
* Return a simple String showing the accessible optimizers. For external
* access."
*
* @return a String listing the accessible optimizers
*/
public static String showOptimizers() {
return "1: Standard ES \n2: CMA-ES \n3: GA \n4: PSO \n5: DE \n6: Tribes \n7: Random (Monte Carlo) "
+ "\n8: Hill-Climbing \n9: Cluster-based niching ES \n10: Clustering Hill-Climbing \n11: IPOP-CMA-ES.";
}
/**
* Produce a runnable optimizer from a strategy identifier, a problem instance and with a given
* number of fitness calls to be performed. Output is written to a file if the prefix String is given.
*
* @param optType
* @param problem
* @param fitCalls
* @param outputFilePrefix
* @return a runnable optimizer
*/
public static OptimizerRunnable getOptRunnable(final int optType,
AbstractOptimizationProblem problem, int fitCalls,
String outputFilePrefix) {
@ -589,31 +593,86 @@ public class OptimizerFactory {
}
// /////////////////////////// constructing a default OptimizerRunnable
/**
* Produce a runnable optimizer from a strategy identifier, a problem instance and with the default
* number of fitness calls to be performed. Output is written to a file if the prefix String is given.
* @see #getOptRunnable(int, AbstractOptimizationProblem, int, String)
* @param optType
* @param problem
* @param outputFilePrefix
* @return a runnable optimizer
*/
public static OptimizerRunnable getOptRunnable(final int optType,
AbstractOptimizationProblem problem, String outputFilePrefix) {
return getOptRunnable(optType, problem, defaultFitCalls,
outputFilePrefix);
}
/**
* Return the current default terminator.
*
* @return the current default terminator
*/
public static InterfaceTerminator getTerminator() {
return OptimizerFactory.term;
}
public static final GOParameters hillClimbing(
AbstractOptimizationProblem problem) {
HillClimbing hc = new HillClimbing();
hc.SetProblem(problem);
Population pop = new Population();
pop.setPopulationSize(50);
problem.initPopulation(pop);
return makeParams(hc, pop, problem, randSeed, defaultTerminator());
}
/**
* Return the number of evaluations performed during the last run or -1 if unavailable.
*
* @return the number of evaluations performed during the last run or -1
*/
public static int lastEvalsPerformed() {
return (lastRunnable != null) ? lastRunnable.getProgress() : -1;
}
// /////////////////////// Creating default strategies
/**
* Use lambda, default random seed and terminator to produce GOParameters.
*
* @param es
* @param problem
* @return
*/
public static GOParameters makeESParams(EvolutionStrategies es,
AbstractOptimizationProblem problem) {
return makeParams(es, es.getLambda(), problem, randSeed, defaultTerminator());
}
/**
* Use default random seed and terminator for a parameter set.
*
* @see #makeParams(InterfaceOptimizer, int, AbstractOptimizationProblem, long, InterfaceTerminator)
* @param opt
* @param popSize
* @param problem
* @return
*/
public static GOParameters makeParams(InterfaceOptimizer opt, int popSize, AbstractOptimizationProblem problem) {
return makeParams(opt, popSize, problem, randSeed, defaultTerminator());
}
public static GOParameters makeParams(InterfaceOptimizer opt,
int popSize, AbstractOptimizationProblem problem, long seed,
InterfaceTerminator term) {
Population pop = new Population(popSize);
problem.initPopulation(pop);
return makeParams(opt, pop, problem, seed, term);
}
/**
* Create a GOParameters instance and prepare it with the given arguments. The result can be
* modified and then used to create an OptimizerRunnable, which of course can simply be run.
*
* @see OptimizerRunnable
* @param opt
* @param pop
* @param problem
* @param seed
* @param term
* @return
*/
public static GOParameters makeParams(InterfaceOptimizer opt,
Population pop, AbstractOptimizationProblem problem, long seed,
InterfaceTerminator term) {
@ -627,16 +686,6 @@ public class OptimizerFactory {
return params;
}
public static final GOParameters monteCarlo(
AbstractOptimizationProblem problem) {
MonteCarloSearch mc = new MonteCarloSearch();
Population pop = new Population();
pop.setPopulationSize(50);
problem.initPopulation(pop);
return makeParams(mc, pop, problem, randSeed, defaultTerminator());
}
// TODO hier weiter kommentieren
public static OptimizerRunnable optimize(final int optType,
AbstractOptimizationProblem problem, String outputFilePrefix) {
return optimize(getOptRunnable(optType, problem, outputFilePrefix));
@ -849,7 +898,7 @@ public class OptimizerFactory {
: null;
}
// /////////////////////////// post processing
///////////////////////////// post processing
public static Vector<AbstractEAIndividual> postProcessIndVec(
OptimizerRunnable runnable, int steps, double sigma, int nBest) {
return postProcessIndVec(runnable, new PostProcessParams(steps, sigma,
@ -869,7 +918,8 @@ public class OptimizerFactory {
}
return ret;
}
///////////////////////////// termination management
public static void setEvaluationTerminator(int maxEvals) {
setTerminator(new EvaluationTerminator(maxEvals));
}
@ -883,30 +933,124 @@ public class OptimizerFactory {
OptimizerFactory.term = term;
}
public static String terminatedBecause() {
return (lastRunnable != null) ? lastRunnable.terminatedBecause() : null;
}
///////////////////////////// default parameters
/**
* Return a simple String showing the accessible optimizers. For external
* access."
*
* @return a String listing the accessible optimizers
* Create a standard multi-start hill-climber parameter set with 50 initial individuals.
*
* @return a standard multi-start hill-climber
*/
public static String showOptimizers() {
return "1: Standard ES \n2: CMA-ES \n3: GA \n4: PSO \n5: DE \n6: Tribes \n7: Random (Monte Carlo) "
+ "\n8: Hill-Climbing \n9: Cluster-based niching ES \n10: Clustering Hill-Climbing";
public static final GOParameters hillClimbing(
AbstractOptimizationProblem problem) {
return makeParams(new HillClimbing(), 50, problem, randSeed, defaultTerminator());
}
public static final GOParameters monteCarlo(
AbstractOptimizationProblem problem) {
return makeParams(new MonteCarloSearch(), 50, problem, randSeed, defaultTerminator());
}
public static final GOParameters cbnES(AbstractOptimizationProblem problem) {
ClusterBasedNichingEA cbn = new ClusterBasedNichingEA();
EvolutionStrategies es = new EvolutionStrategies();
es.setMu(15);
es.setLambda(50);
es.setPlusStrategy(false);
cbn.setOptimizer(es);
ClusteringDensityBased clustering = new ClusteringDensityBased(0.1);
cbn.setConvergenceCA((ClusteringDensityBased) clustering.clone());
cbn.setDifferentationCA(clustering);
cbn.setShowCycle(0); // don't do graphical output
return makeParams(cbn, 100, problem, randSeed, defaultTerminator());
}
public static final GOParameters clusteringHillClimbing(
AbstractOptimizationProblem problem) {
ClusteringHillClimbing chc = new ClusteringHillClimbing();
chc.SetProblem(problem);
chc.setHcEvalCycle(1000);
chc.setInitialPopSize(100);
chc.setStepSizeInitial(0.05);
chc.setMinImprovement(0.000001);
chc.setNotifyGuiEvery(0);
chc.setStepSizeThreshold(0.000001);
chc.setSigmaClust(0.05);
return makeParams(chc, 100, problem, randSeed, defaultTerminator());
}
public static final GOParameters cmaES(AbstractOptimizationProblem problem) {
EvolutionStrategies es = new EvolutionStrategies();
es.setMu(15);
es.setLambda(50);
es.setPlusStrategy(false);
AbstractEAIndividual indyTemplate = problem.getIndividualTemplate();
if ((indyTemplate != null)
&& (indyTemplate instanceof InterfaceESIndividual)) {
// Set CMA operator for mutation
AbstractEAIndividual indy = (AbstractEAIndividual) indyTemplate;
MutateESCovarianceMatrixAdaption cmaMut = new MutateESCovarianceMatrixAdaption();
cmaMut.setCheckConstraints(true);
AbstractEAIndividual.setOperators(indy, cmaMut, 1., new CrossoverESDefault(), 0.);
} else {
System.err
.println("Error, CMA-ES is implemented for ES individuals only (requires double data types)");
return null;
}
return makeESParams(es, problem);
}
/**
* Create a new IPOP-CMA-ES strategy with Rank-mu-CMA. The population size is set to
* lambda = (int) (4.0 + 3.0 * Math.log(dim)) and mu = Math.floor(lambda/2.), but
* lambda may grow during optimization due to restarts with increased lambda.
* Operator probabilities are set to p_mut = 1 and p_c = 0.
* The given problem must work with an individual template which implements
* InterfaceDataTypeDouble.
*
* @param problem the optimization problem
* @return
*/
public static final GOParameters cmaESIPOP(AbstractOptimizationProblem problem) {
EvolutionStrategies es = new EvolutionStrategyIPOP();
AbstractEAIndividual indyTemplate = problem.getIndividualTemplate();
if ((indyTemplate != null) && ((indyTemplate instanceof InterfaceESIndividual) || (indyTemplate instanceof InterfaceDataTypeDouble))) {
// set selection strategy
int dim;
if (indyTemplate instanceof InterfaceESIndividual) dim=((InterfaceESIndividual)indyTemplate).getDGenotype().length;
else dim = ((InterfaceDataTypeDouble)indyTemplate).getDoubleData().length;
int lambda = (int) (4.0 + 3.0 * Math.log(dim));
es.setGenerationStrategy((int)Math.floor(lambda/2.),lambda, false);
es.setForceOrigPopSize(false);
// Set CMA operator for mutation
AbstractEAIndividual indy = (AbstractEAIndividual) indyTemplate;
MutateESRankMuCMA cmaMut = new MutateESRankMuCMA();
AbstractEAIndividual.setOperators(indy, cmaMut, 1., new CrossoverESDefault(), 0.);
} else {
System.err
.println("Error, CMA-ES is implemented for ES individuals only (requires double data types)");
return null;
}
return makeESParams(es, problem);
}
public static final GOParameters standardDE(
AbstractOptimizationProblem problem) {
DifferentialEvolution de = new DifferentialEvolution();
Population pop = new Population();
pop.setPopulationSize(50);
de.setPopulation(pop);
de.getDEType().setSelectedTag(1); // this sets current-to-best
de.setDEType(DETypeEnum.DE2_CurrentToBest); // this sets current-to-best
de.setF(0.8);
de.setK(0.6);
de.setLambda(0.6);
de.setMt(0.05);
return makeParams(de, pop, problem, randSeed, defaultTerminator());
return makeParams(de, 50, problem, randSeed, defaultTerminator());
}
public static final GOParameters standardES(
@ -928,43 +1072,26 @@ public class OptimizerFactory {
return null;
}
Population pop = new Population();
pop.setPopulationSize(es.getLambda());
return makeParams(es, pop, problem, randSeed, defaultTerminator());
return makeESParams(es, problem);
}
public static final GOParameters standardGA(
AbstractOptimizationProblem problem) {
GeneticAlgorithm ga = new GeneticAlgorithm();
Population pop = new Population();
pop.setPopulationSize(100);
ga.setPopulation(pop);
ga.setElitism(true);
return makeParams(ga, pop, problem, randSeed, defaultTerminator());
return makeParams(ga, 100, problem, randSeed, defaultTerminator());
}
public static final GOParameters standardPSO(
AbstractOptimizationProblem problem) {
ParticleSwarmOptimization pso = new ParticleSwarmOptimization();
Population pop = new Population();
pop.setPopulationSize(30);
pso.setPopulation(pop);
pso.setPhiValues(2.05, 2.05);
pso.getTopology().setSelectedTag("Grid");
return makeParams(pso, pop, problem, randSeed, defaultTerminator());
}
public static String terminatedBecause() {
return (lastRunnable != null) ? lastRunnable.terminatedBecause() : null;
return makeParams(pso, 30, problem, randSeed, defaultTerminator());
}
public static final GOParameters tribes(AbstractOptimizationProblem problem) {
Tribes tr = new Tribes();
Population pop = new Population();
pop.setPopulationSize(1); // only for init
problem.initPopulation(pop);
return makeParams(tr, pop, problem, randSeed, defaultTerminator());
return makeParams(new Tribes(), 1, problem, randSeed, defaultTerminator());
}
}

View File

@ -158,6 +158,10 @@ public class BeanInspector {
sbuf.append(" ]");
return sbuf.toString();
}
if (type.isEnum()) {
return Target.toString();
}
if (Target instanceof List && !(Target instanceof Population)) { // handle the list case
StringBuffer sbuf = new StringBuffer("[ ");
@ -566,6 +570,7 @@ public class BeanInspector {
* @return
*/
public static Object decodeType(Class<?> destType, Object value) {
// System.err.println("desttype: " + destType.toString() + ", val: " + value.getClass().toString());
if (destType.isAssignableFrom(value.getClass())) {
// value is already of destType or assignable (subclass), so just return it
return value;
@ -575,8 +580,9 @@ public class BeanInspector {
else return value.toString();
} else if (isJavaPrimitive(destType)) {
try {
if (value.getClass() == String.class) return stringToPrimitive((String)value, destType);
else {
if (value.getClass() == String.class) {
return stringToPrimitive((String)value, destType);
} else {
return doubleToPrimitive(toDouble(value), destType);
}
} catch(Exception e) {

View File

@ -0,0 +1,6 @@
package eva2.server.go.enums;
public enum DETypeEnum {
DE1_Rand_1, DE2_CurrentToBest, DE_Best_2, TrigonometricDE;
//", "DE2 - DE/current-to-best/1", "DE/best/2", "Trigonometric DE"};
}

View File

@ -0,0 +1,5 @@
package eva2.server.go.enums;
public enum ESMutationInitialSigma {
halfRange, avgInitialDistance, userDefined;
}

View File

@ -753,9 +753,13 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
m_dataHash.put(name, obj);
}
/** This method will return a stored object.
* @param name The name of the requested Object.
* @return Object
/**
* This method will return a stored object associated with a key String.
* The String "Fitness" is always a valid key connected to the
* individual fitness array.
*
* @param name The name of the requested Object
* @return Object The associated object or null if none is found
*/
public Object getData(String name) {
// if (name.equalsIgnoreCase("SelectionProbability")) return this.getSelectionProbability();
@ -764,13 +768,32 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
// if (name.equalsIgnoreCase("FitnessArray")) return this.getFitness();
Object data = m_dataHash.get(name);
if (data==null) { // Fitness is actually in use... so lets have a minor special treatment
if (name.compareToIgnoreCase("Fitness")==0) data = getFitness();
else {
EVAERROR.errorMsgOnce("Warning: data key " + name + " unknown (pot. multiple errors)!");
}
// try {
if (name.compareToIgnoreCase("Fitness")==0) data = getFitness();
else {
EVAERROR.errorMsgOnce("Warning: data key " + name + " unknown (pot. multiple errors)!");
// throw new RuntimeException(name + ": unknown key!");
}
// } catch(Exception e) {
// e.printStackTrace(System.err);
// }
}
return data;
}
/**
* Check whether the individual has an object in store which is associated with
* the given key String. The String "Fitness" is always a valid key connected to the
* individual fitness array.
*
* @param key The name of the requested Object.
* @return true if data is associated with the key, else false
*/
public boolean hasData(String key) {
if (m_dataHash.get(key)==null) {
return (key.compareToIgnoreCase("Fitness")==0);
} else return true;
}
/** This method will return a string description of the Individal
* noteably the Genotype.
@ -794,8 +817,10 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
sb.append(BeanInspector.toString(individual.getFitness()));
sb.append(", ID: ");
sb.append(individual.getIndyID());
sb.append(", parents: ");
sb.append(BeanInspector.toString(individual.getParentIDs()));
if (individual.getParentIDs()!=null) {
sb.append(", parents: ");
sb.append(BeanInspector.toString(individual.getParentIDs()));
}
return sb.toString();
}

View File

@ -13,13 +13,11 @@ import eva2.server.go.individuals.InterfaceDataTypePermutation;
import eva2.server.go.individuals.InterfaceDataTypeProgram;
import eva2.server.go.individuals.codings.gp.InterfaceProgram;
/** A phenotype metric suited for some of the most common
* data types.
* Created by IntelliJ IDEA.
/**
* A phenotype metric suited for the most common data types.
*
* User: streiche
* Date: 19.07.2005
* Time: 14:50:17
* To change this template use File | Settings | File Templates.
*/
public class PhenotypeMetric implements InterfaceDistanceMetric, java.io.Serializable {
private static PhenotypeMetric pMetric = null;

View File

@ -4,6 +4,7 @@ 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 eva2.tools.Mathematics;
import wsi.ra.math.RNG;
import wsi.ra.math.Jama.EigenvalueDecomposition;
import wsi.ra.math.Jama.Matrix;
@ -252,11 +253,8 @@ public class MutateESCovarianceMatrixAdaption implements InterfaceMutation, java
}
}
}
if (this.m_CheckConstraints == true) { // CSpieth
for (int i = 0; i < this.m_D; i++) {
if (x[i] < range[i][0]) x[i] = range[i][0];
if (x[i] > range[i][1]) x[i] = range[i][1];
}
if (this.m_CheckConstraints) { // CSpieth
Mathematics.projectToRange(x, range);
}
}

View File

@ -4,6 +4,7 @@ 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 eva2.tools.Mathematics;
import wsi.ra.math.RNG;
/**
@ -182,10 +183,7 @@ public class MutateESMainVectorAdaption implements InterfaceMutation, java.io.Se
x[i] = x[i] + this.m_SigmaScalar * (this.m_Z[i] + this.Z1 * this.w_v * this.m_main_v[i]);
}
if (getCheckConstraints()) { // MK: lets actually do a constraint check
for (int i = 0; i < x.length; i++) {
if (x[i] < range[i][0]) x[i] = range[i][0];
if (x[i] > range[i][1]) x[i] = range[i][1];
}
Mathematics.projectToRange(x, range);
}
}

View File

@ -7,6 +7,8 @@ import wsi.ra.math.RNG;
import wsi.ra.math.Jama.EigenvalueDecomposition;
import wsi.ra.math.Jama.Matrix;
import eva2.gui.BeanInspector;
import eva2.gui.GenericObjectEditor;
import eva2.server.go.enums.ESMutationInitialSigma;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeDouble;
import eva2.server.go.populations.Population;
@ -17,11 +19,10 @@ 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.
* Implementing CMA ES with rank-mu-update and weighted recombination. More information can be found here:
* - http://www.bionik.tu-berlin.de/user/niko/cmaesintro.html
* - N.Hansen & S.Kern 2004: Evaluating the CMA Evolution Strategy on Multimodal Test Functions.
* Parallel Problem Solving from Nature 2004.
*
* @author mkron
*
@ -31,7 +32,8 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
private double c_c, expRandStepLen;
private double[] z, zCor;
private InitialSigmaEnum initialSig = InitialSigmaEnum.avgInitialDistance;
private ESMutationInitialSigma initializeSig = ESMutationInitialSigma.avgInitialDistance;
private double userDefInitSig = 0.2;
private static double firstSigma = -1.;
private static double sigma;
private static double d_sig, c_sig;
@ -58,7 +60,7 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
// this.d_sig = mutator.d_sig;
this.expRandStepLen = mutator.expRandStepLen;
this.dim = mutator.dim;
this.initialSig = mutator.initialSig;
this.initializeSig = mutator.initializeSig;
// if (mutator.meanX != null) this.meanX = (double[]) mutator.meanX.clone();
// if (mutator.pathC != null) this.pathC = (double[]) mutator.pathC.clone();
@ -81,11 +83,14 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
* @return
*/
private double getInitSigma(Population initGen) {
switch (initialSig) {
switch (initializeSig) {
case avgInitialDistance:
// scaled by average range as the measures are normed
return initGen.getPopulationMeasures()[0]*getAvgRange();
//return initGen.getPopulationMeasures(null)[0]*getAvgRange();
// use euclidian measures without normation and scaling
return initGen.getPopulationMeasures(null)[0];
case halfRange: return getAvgRange()/2.;
case userDefined: return userDefInitSig ;
default: return 0.2;
}
}
@ -97,7 +102,7 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
mu = selectedP.size();
lambda = oldGen.size();
if (mu>= lambda) {
EVAERROR.errorMsgOnce("Warning: invalid mu/lambda ratio! Setting mu to lambda/2.");
EVAERROR.errorMsgOnce("Warning: invalid mu/lambda ratio (" + mu + "/" + lambda + ") ! Setting mu to lambda/2.");
mu = lambda/2;
}
if (!firstAdaptionDone) {
@ -107,6 +112,7 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
// 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);
// System.out.println("INitial sigma: "+sigma);
firstSigma = sigma;
meanX = oldGen.getCenter(); // this might be ok?
}
@ -496,16 +502,16 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
private double[] mutate(double[] x, double[][] range, int count) {
if (firstAdaptionDone) {
double[] artmp = new double[x.length];
double[] sampl = new double[x.length]; // generate scaled random vector (D * z)
for (int i = 0; i < dim; ++i) {
artmp[i] = Math.sqrt(eigenvalues[i]) * RNG.gaussianDouble(1.);
sampl[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];
sum += mB.get(i,j) * sampl[j];
x[i] = meanX[i]+getSigma(i)*sum;
}
} else {
@ -551,21 +557,26 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
return firstSigma;
}
public void hideHideable() {
this.setInitializeSigma(getInitializeSigma());
}
/**
* @return the initialSig
*/
public InitialSigmaEnum getInitialSigma() {
return initialSig;
public ESMutationInitialSigma getInitializeSigma() {
return initializeSig;
}
/**
* @param initialSig the initialSig to set
*/
public void setInitialSigma(InitialSigmaEnum initialSig) {
this.initialSig = initialSig;
public void setInitializeSigma(ESMutationInitialSigma initialSig) {
this.initializeSig = initialSig;
GenericObjectEditor.setHideProperty(this.getClass(), "userDefInitSig", initialSig!=ESMutationInitialSigma.userDefined);
}
public String initialSigmaTipText() {
public String initializeSigmaTipText() {
return "Method to use for setting the initial step size.";
}
@ -646,8 +657,18 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
return true;
} else return false;
}
}
enum InitialSigmaEnum {
halfRange, avgInitialDistance;
}
/**
* @return the userDefInitSig
*/
public double getUserDefInitSig() {
return userDefInitSig;
}
/**
* @param userDefInitSig the userDefInitSig to set
*/
public void setUserDefInitSig(double userDefInitSig) {
this.userDefInitSig = userDefInitSig;
}
}

View File

@ -16,6 +16,7 @@ import eva2.server.go.individuals.AbstractEAIndividualComparator;
import eva2.server.go.individuals.GAIndividualBinaryData;
import eva2.server.go.operators.distancemetric.InterfaceDistanceMetric;
import eva2.server.go.operators.distancemetric.PhenotypeMetric;
import eva2.server.go.operators.selection.probability.AbstractSelProb;
import eva2.tools.EVAERROR;
import eva2.tools.Mathematics;
import eva2.tools.Pair;
@ -884,6 +885,9 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
/**
* Returns the average, minimal and maximal individual distance as diversity measure for the population.
* If the given metric argument is null, the euclidian distance of individual positions is used, which
* presumes that {@link AbstractEAIndividual.getDoublePosition(indy)} returns a valid double position for the
* individuals of the population.
* This is of course rather expensive computationally.
*
* @return the average, minimal and maximal mean distance of individuals in an array of three
@ -898,7 +902,9 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
for (int i = 0; i < this.size(); i++) {
for (int j = i+1; j < this.size(); j++) {
d = metric.distance((AbstractEAIndividual)this.get(i), (AbstractEAIndividual)this.get(j));
if (metric == null) d = PhenotypeMetric.euclidianDistance(AbstractEAIndividual.getDoublePosition(getEAIndividual(i)),
AbstractEAIndividual.getDoublePosition(getEAIndividual(j)));
else d = metric.distance((AbstractEAIndividual)this.get(i), (AbstractEAIndividual)this.get(j));
meanDist += d;
if (d < minDist) minDist = d;
if (d > maxDist) maxDist = d;
@ -941,6 +947,32 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
return centerPos;
}
/**
* Return the population center weighted by fitness, using the same scaling as provided
* by a SelectionProbability instance.
* This only works for those individuals that have a position representation, meaning that
* AbstractEAIndidivual.getDoublePosition(individual) returns a valid position.
* If they dont, null is returned.
*
* @see AbstractEAIndidivual.getDoublePosition(individual)
* @param criterion
* @return
*/
public double[] getCenterWeighted(AbstractSelProb selProb, int criterion, boolean obeyConst) {
selProb.computeSelectionProbability(this, "Fitness", obeyConst);
double[] mean = AbstractEAIndividual.getDoublePosition(getEAIndividual(0));
if (mean != null) {
Arrays.fill(mean, 0.);
AbstractEAIndividual indy = null;
for (int i=0; i<size(); i++) {
indy = getEAIndividual(i);
double[] pos = AbstractEAIndividual.getDoublePosition(indy);
Mathematics.svvAddScaled(indy.getSelectionProbability(criterion), pos, mean, mean);
}
}
return mean;
}
/**
* 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
@ -953,6 +985,51 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
this.notifyEvalInterval = notifyEvalInterval;
}
/**
* Fit the population to its targeted population size. If it contains too many
* individuals, the last ones are removed. If it contains too few individuals,
* the first ones are cloned in a cycle.
* If the size matches, nothing happens. If there is no individual already contained,
* this method cannot grow, of course.
*/
public void fitToSize() {
if (size() != getPopulationSize()) {
while (size() > getPopulationSize()) remove(size()-1);
if (size() < getPopulationSize()) {
if (size() == 0) System.err.println("Cannot grow empty population!");
else {
int origSize=size();
int k=0;
while (size()< getPopulationSize()) {
addIndividual((AbstractEAIndividual)getEAIndividual(k%origSize).clone());
}
}
}
}
}
/**
* Calculate the fitness sum over all individuals for one criterion.
*
* @param criterion
* @return the fitness sum over all individuals for one criterio
*/
public double getFitSum(int criterion) {
double fSum = 0.;
for (int i=0; i<size(); i++) {
fSum += getEAIndividual(i).getFitness(criterion);
}
return fSum;
}
/**
* Set the desired population size parameter to the actual current size.
*
*/
public void synchSize() {
setPopulationSize(size());
}
// /**
// * Check whether the population at the current state has been marked as
// * evaluated. This allows to avoid double evaluations.

View File

@ -8,6 +8,27 @@ import eva2.server.go.strategies.InterfaceOptimizer;
import wsi.ra.math.RNG;
import eva2.server.go.problems.Interface2DBorderProblem;
/**
* For a double valued problem, there are two main methods to implement: {@link #getProblemDimension()}
* must return the problem dimension, while {@link #eval(double[])} is to evaluate a single double
* vector into the result fitness vector.
*
* To define the problem range, you may use the default range parameter resulting in a symmetric
* double range [-defaultRange,defaulRange] in all dimensions.
* Or you may implement {@link #getRangeLowerBound(int)} and {@link #getRangeUpperBound(int)}
* to define an arbitrary problem range. In that case, the default range parameter is not used.
*
* Anything you want to do before any optimization is started on the problem should go into
* {@link #initProblem()}, but remember to call the super-method in your implementation. The
* individual template will be initialized to an ESIndividualDoubleData by then.
*
* For the GUI, it is also convenient to implement the {@link #globalInfo()} and {@link #getName()}
* methods to provide some distinctive information for the user.
*
*
* @author mkron
*
*/
public abstract class AbstractProblemDouble extends AbstractOptimizationProblem implements InterfaceProblemDouble, Interface2DBorderProblem {
private double m_DefaultRange = 10;
private double m_Noise = 0;

View File

@ -20,7 +20,14 @@ import eva2.server.go.populations.Population;
import eva2.server.go.strategies.InterfaceOptimizer;
import eva2.server.stat.InterfaceTextListener;
/**
* Interface problem class for Matlab(TM). Towards EvA2 this behaves like any other double valued
* problem implementation. However internally, every evaluation "asks" a mediator instance for
* the result which waits for Matlab to evaluate the x value. When Matlab is finished, the mediator
* returns to the evaluate method and the optimization can continue.
* @author mkron
*
*/
public class MatlabProblem extends AbstractProblemDouble implements InterfaceTextListener, Serializable {
private static final long serialVersionUID = 4913310869887420815L;
public static final boolean TRACE = false;
@ -37,8 +44,6 @@ public class MatlabProblem extends AbstractProblemDouble implements InterfaceTex
public static boolean hideFromGOE = true;
// private F1Problem f1 = new F1Problem(); // TODO
// transient private double[] currArray = null;
// private String mtCmd = null;
@ -236,6 +241,7 @@ public class MatlabProblem extends AbstractProblemDouble implements InterfaceTex
} else {
log("setting specific parameters...\n");
InterfaceOptimizer opt = runnable.getGOParams().getOptimizer();
// log(BeanInspector.toString(BeanInspector.getMemberDescriptions(opt, true)));
for (int i=0; i<specParams.length; i++) { // loop over settings
log("try setting " + specParams[i] + " to " + specValues[i]);
String paramName = null;
@ -247,7 +253,10 @@ public class MatlabProblem extends AbstractProblemDouble implements InterfaceTex
System.err.println("Error, parameter "+ specParams[i] + " could not be cast to String, trying " + paramName);
}
}
if ((paramName == null) || (!BeanInspector.setMem(opt, paramName, specValues[i]))) {
Object specVal = null; // avoid giving chars to the converter method here - the ascii value would be assigned instead of the string
if (specValues[i] instanceof Character) specVal = ""+specValues[i];
else specVal = specValues[i];
if ((paramName == null) || (!BeanInspector.setMem(opt, paramName, specVal))) {
log("... Fail!\n");
System.err.println("Unable to set parameter " + paramName + ", skipping...");
} else log("... Ok.\n");

View File

@ -5,6 +5,7 @@ import java.util.Vector;
import wsi.ra.math.RNG;
import eva2.gui.GenericObjectEditor;
import eva2.server.go.InterfacePopulationChangedEventListener;
import eva2.server.go.enums.DETypeEnum;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeDouble;
import eva2.server.go.operators.selection.replacement.ReplacementCrowding;
@ -16,23 +17,21 @@ import eva2.server.go.problems.AbstractOptimizationProblem;
import eva2.server.go.problems.F1Problem;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.tools.EVAERROR;
import eva2.tools.SelectedTag;
import eva2.tools.Mathematics;
/** Differential evolution implementing DE1 and DE2 following the paper of Storm and
* Price and the Trigonometric DE published rectently, which doesn't really work that
* well. Please note that DE will only work on real-valued genotypes and will ignore
* Price and the Trigonometric DE published recently.
* Please note that DE will only work on real-valued genotypes and will ignore
* all mutation and crossover operators selected.
* Created by IntelliJ IDEA.
* User: streiche
* Date: 25.10.2004
* Time: 14:06:56
* To change this template use File | Settings | File Templates.
*
*/
public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serializable {
private Population m_Population = new Population();
private AbstractOptimizationProblem m_Problem = new F1Problem();
private SelectedTag m_DEType;
private DETypeEnum m_DEType;
private double m_F = 0.8;
private double m_k = 0.6;
private double m_Lambda = 0.6;
@ -44,15 +43,15 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial
private String m_Identifier = "";
transient private InterfacePopulationChangedEventListener m_Listener;
private boolean forceRange = true;
/**
* A constructor.
*
*/
public DifferentialEvolution() {
String[] deTypes = new String[] {"DE1 - DE/rand/1", "DE2 - DE/current-to-best/1", "DE/best/2", "Trigonometric DE"};
// sets DE2 as default
m_DEType = new SelectedTag(1, deTypes);
m_DEType = DETypeEnum.DE2_CurrentToBest;
}
/**
@ -61,8 +60,7 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial
* @param a
*/
public DifferentialEvolution(DifferentialEvolution a) {
if (a.m_DEType != null)
this.m_DEType = (SelectedTag)a.m_DEType.clone();
this.m_DEType = a.m_DEType;
this.m_Population = (Population)a.m_Population.clone();
this.m_Problem = (AbstractOptimizationProblem)a.m_Problem.clone();
this.m_Identifier = a.m_Identifier;
@ -236,8 +234,8 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial
oX = esIndy.getDoubleData();
vX = esIndy.getDoubleData();
nX = new double[oX.length];
switch (this.m_DEType.getSelectedTag().getID()) {
case 0 : {
switch (this.m_DEType) {
case DE1_Rand_1: {
// this is DE1 or DE/rand/1
double[] delta = this.fetchDeltaRandom(pop);
if (parents != null) parents.add(pop.getEAIndividual(firstParentIndex)); // Add wherever oX is used directly
@ -246,7 +244,7 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial
}
break;
}
case 1 : {
case DE2_CurrentToBest : {
// this is DE2 or DE/current-to-best/1
double[] rndDelta = this.fetchDeltaRandom(pop);
double[] bestDelta = this.fetchDeltaBest(pop, esIndy);
@ -256,7 +254,7 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial
}
break;
}
case 2: {
case DE_Best_2: {
// DE/best/2
AbstractEAIndividual bestIndy = getBestIndy(pop);
oX = getGenotype(bestIndy);
@ -268,7 +266,7 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial
}
break;
}
case 3 : {
case TrigonometricDE : {
// this is trigonometric mutation
if (parents != null) parents.add(pop.getEAIndividual(firstParentIndex)); // Add wherever oX is used directly
if (RNG.flipCoin(this.m_Mt)) {
@ -316,6 +314,7 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial
}
}
// setting the new genotype and fitness
if (forceRange) Mathematics.projectToRange(nX, esIndy.getDoubleRange()); // why did this never happen before?
esIndy.SetDoubleGenotype(nX);
indy.SetAge(0);
double[] fit = new double[1];
@ -325,14 +324,11 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial
return indy;
}
private AbstractEAIndividual getBestIndy(Population pop) {
double[] xb;
return (AbstractEAIndividual)pop.getBestIndividual();
}
private AbstractEAIndividual getRandomIndy(Population pop) {
double[] x1;
int randIndex = RNG.randomInt(0, pop.size()-1);
return pop.getEAIndividual(randIndex);
}
@ -584,12 +580,12 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial
/** This method allows you to choose the type of Differential Evolution.
* @param s The type.
*/
public void setDEType(SelectedTag s) {
public void setDEType(DETypeEnum s) {
this.m_DEType = s;
// show mt for trig. DE only
GenericObjectEditor.setShowProperty(this.getClass(), "mt", s.getSelectedTagID()==3);
GenericObjectEditor.setShowProperty(this.getClass(), "mt", s==DETypeEnum.TrigonometricDE);
}
public SelectedTag getDEType() {
public DETypeEnum getDEType() {
return this.m_DEType;
}
public String dETypeTipText() {
@ -613,4 +609,23 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial
public String maximumAgeTipText() {
return "The maximum age of individuals, older ones are discarded. Set to -1 (or 0) to deactivate";
}
/**
* Check whether the problem range will be enforced.
* @return the forceRange
*/
public boolean isCheckRange() {
return forceRange;
}
/**
* @param forceRange the forceRange to set
*/
public void setCheckRange(boolean forceRange) {
this.forceRange = forceRange;
}
public String checkRangeTipText() {
return "Set whether to enforce the problem range.";
}
}

View File

@ -9,6 +9,7 @@ import eva2.server.go.individuals.InterfaceESIndividual;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.AbstractOptimizationProblem;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.tools.Mathematics;
import eva2.tools.SelectedTag;
/**
@ -148,14 +149,11 @@ public class DynamicParticleSwarmOptimization extends ParticleSwarmOptimization
double[] rand = getNormalRandVect(position.length, range, quantumCloudDia);
//double[] rand = getUniformRandVect(position.length, range);
for (int i=0; i<newPos.length; i++) {
newPos[i] += rand[i];
if (m_CheckConstraints) {
if (newPos[i] < range[i][0]) newPos[i] = range[i][0];
else if (newPos[i] > range[i][1]) newPos[i] = range[i][1];
}
}
Mathematics.vvAdd(newPos, rand, newPos);
if (m_CheckConstraints) {
Mathematics.projectToRange(newPos, range);
}
if (indy instanceof InterfaceDataTypeDouble) ((InterfaceDataTypeDouble)indy).SetDoubleGenotype(newPos);
else endy.SetDoubleGenotype(newPos);

View File

@ -45,7 +45,7 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
private int m_NumberOfPartners = 1;
private int origPopSize = -1; // especially for CBN
// private double[] m_FitnessOfParents = null;
private boolean forceOrigPopSize = true;// especially for CBN
private boolean forceOrigPopSize = true;// especially for CBN
transient private String m_Identifier = "";
transient private InterfacePopulationChangedEventListener m_Listener;
@ -73,6 +73,14 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
this.m_EnvironmentSelection = (InterfaceSelection)a.m_EnvironmentSelection.clone();
}
/**
* Set to true in CBN, false for any extension which changes the population size during optimization.
* @param force
*/
public void setForceOrigPopSize(boolean force) {
forceOrigPopSize = force;
}
public void hideHideable() {
GenericObjectEditor.setHideProperty(this.getClass(), "population", true);
}
@ -88,6 +96,7 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
// this.m_Population.setPopulationSize(this.m_InitialPopulationSize);
// }
//System.out.println("init");
checkPopulationConstraints();
this.m_Problem.initPopulation(this.m_Population);
this.evaluatePopulation(this.m_Population);
// this.m_Population.setPopulationSize(orgPopSize);
@ -318,14 +327,19 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
this.checkPopulationConstraints();
}
/** This method will check the population constraints
/**
* This method will check the population constraints
* myu <= lambda and will calculate the population size
* accordingly.
*/
private void checkPopulationConstraints() {
if (this.m_Lambda < this.m_Mu) this.m_Lambda = this.m_Mu;
protected void checkPopulationConstraints() {
if (this.m_Lambda < this.m_Mu) {
System.err.println("Invalid mu/lambda ratio! Setting mu=lambda="+m_Mu);
this.m_Lambda = this.m_Mu;
}
if (this.m_UsePlusStrategy) this.m_Population.setPopulationSize(this.m_Mu + this.m_Lambda);
else this.m_Population.setPopulationSize(this.m_Lambda);
origPopSize=m_Population.getPopulationSize();
}
/** This method allows you to set an identifier for the algorithm
@ -377,7 +391,7 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
public void setPopulation(Population pop){
origPopSize = pop.size();
// System.out.println("ES: orig popsize is " + origPopSize);
// System.err.println("In ES: orig popsize is " + origPopSize);
this.m_Population = pop;
}
public String populationTipText() {
@ -444,7 +458,7 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
*/
public void setPlusStrategy (boolean elitism) {
this.m_UsePlusStrategy = elitism;
this.checkPopulationConstraints();
// this.checkPopulationConstraints(); // do this on init only
}
public boolean isPlusStrategy() {
return this.m_UsePlusStrategy;
@ -500,7 +514,7 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
*/
public void setMu(int mu) {
this.m_Mu = mu;
this.checkPopulationConstraints();
// this.checkPopulationConstraints(); // do this on init only
}
public int getMu() {
return this.m_Mu;
@ -514,7 +528,7 @@ public class EvolutionStrategies implements InterfaceOptimizer, java.io.Serializ
*/
public void setLambda(int lambda) {
this.m_Lambda = lambda;
this.checkPopulationConstraints();
// this.checkPopulationConstraints(); // do this on init only
}
public int getLambda() {
return this.m_Lambda;

View File

@ -45,13 +45,21 @@ public class EvolutionStrategyIPOP extends EvolutionStrategies implements Interf
LinkedList<AbstractEAIndividual> bestList = null;
AbstractEAIndividual best = null;
public EvolutionStrategyIPOP(int mu, int lambda, boolean usePlus) {
super(mu, lambda, usePlus);
setForceOrigPopSize(false);
setInitialLambda(lambda);
}
public EvolutionStrategyIPOP() {
super();
setForceOrigPopSize(false);
setMu(5);
setLambda(10);
}
public EvolutionStrategyIPOP(EvolutionStrategyIPOP other) {
super(other);
dim = other.dim;
initialLambda = other.initialLambda;
incPopSizeFact = other.incPopSizeFact;
@ -109,6 +117,7 @@ public class EvolutionStrategyIPOP extends EvolutionStrategies implements Interf
// increase by at least one
int newLambda = Math.max((int)(getLambda()*incPopSizeFact), getLambda() + 1);
setLambda(newLambda);
checkPopulationConstraints();
// update the stagnation time in the terminator
if (!isStagnationTimeUserDef() && (fitConvTerm != null)) {
fitConvTerm.setStagnationTime(calcDefaultStagnationTime());
@ -136,9 +145,12 @@ public class EvolutionStrategyIPOP extends EvolutionStrategies implements Interf
public void init() {
// setMu(initialMu);
if (getMu()>initialLambda) {
System.err.println("mu is " + getMu() + ", initial lambda was "+initialLambda);
setMu((initialLambda/2)+1);
System.err.println("Warning, too small initial lambda, adapting mu to " + getMu());
}
checkPopulationConstraints();
setForceOrigPopSize(false);
super.setLambda(initialLambda);
getPopulation().setNotifyEvalInterval(initialLambda);
super.init();
@ -233,12 +245,18 @@ public class EvolutionStrategyIPOP extends EvolutionStrategies implements Interf
return "An ES with increasing population size.";
}
protected void checkPopulationConstraints() {
if (getLambda()!=initialLambda) setLambda(initialLambda);
if (getMu()>getLambda()) System.err.println("Invalid mu/lambda ratio!");
super.checkPopulationConstraints();
}
/** 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);
// if (initialLambda < getMu()) setMu((initialLambda/2)+1); // do this on init
}
public int getInitialLambda() {

View File

@ -160,6 +160,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
this.m_Problem.initPopulation(this.m_Population);
tracedVelocity = null;
// evaluation needs to be done here now, as its omitted if reset is false
initDefaults(this.m_Population);
this.evaluatePopulation(this.m_Population);
initByPopulation(m_Population, false);
}
@ -211,7 +212,10 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
*/
protected void traceEMA(Population population) {
if (population.get(0) instanceof InterfaceDataTypeDouble) {
double[] curAvVelAndSpeed = getPopulationVelSpeed(population, 3);
double[] curAvVelAndSpeed;
if (population.getGeneration() == 0) return;
curAvVelAndSpeed = getPopulationVelSpeed(population, 3);
double[][] range = ((InterfaceDataTypeDouble)population.get(0)).getDoubleRange();
if (tracedVelocity == null) {
tracedVelocity = new double[((InterfaceDataTypeDouble)population.get(0)).getDoubleData().length];
@ -362,16 +366,9 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
if (reset) this.m_Population.init();
AbstractEAIndividual indy;
// double[] tmpD, writeData;
// double sum;
for (int i = 0; i < this.m_Population.size(); i++) {
indy = (AbstractEAIndividual) this.m_Population.get(i);
if (indy instanceof InterfaceDataTypeDouble) {
initIndividualDefaults(indy);
}
indy.SetData(indexKey, i);
indy.setIndividualIndex(i);
}
if (!defaultsDone(m_Population.getEAIndividual(0))) initDefaults(m_Population);
if (reset) this.evaluatePopulation(this.m_Population);
for (int i = 0; i < this.m_Population.size(); i++) {
@ -391,6 +388,27 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
treeOrphans = pop.size()-getMaxNodes(treeBranchDeg, treeLevels-1);
treeLastFullLevelNodeCnt = (int)Math.pow(treeBranchDeg, treeLevels-1);
}
private boolean defaultsDone(AbstractEAIndividual individual) {
return individual.hasData(indexKey);
}
/**
* Initialize individual defaults for the given population.
*
* @param pop
*/
protected void initDefaults(Population pop) {
AbstractEAIndividual indy;
for (int i = 0; i < pop.size(); i++) {
indy = (AbstractEAIndividual) pop.get(i);
if (indy instanceof InterfaceDataTypeDouble) {
initIndividualDefaults(indy);
}
indy.SetData(indexKey, i);
indy.setIndividualIndex(i);
}
}
/**
* Return the number of nodes of a complete n-ary tree with given branching factor and depth.
@ -727,7 +745,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
return accel;
}
public static void main(String[] args) {
// public static void main(String[] args) {
// ParticleSwarmOptimization pso = new ParticleSwarmOptimization();
// GVector tmp, vec = new GVector(5);
// GVector vecSum = new GVector(5);
@ -750,7 +768,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
// }
// //vecSum.normalize();
// //System.out.println(vec.toString() + " -> " + vecSum.toString());
}
// }
/**
* Return a random vector after a gaussian distribution oriented along dir, meaning that
@ -1120,6 +1138,17 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
this.firePropertyChangedEvent("NextGenerationPerformed");
if (sleepTime > 0 ) try { Thread.sleep(sleepTime); } catch(Exception e) {}
maybeClearPlot();
}
protected void maybeClearPlot() {
if (((m_Population.getGeneration() % 23) == 0) && isShow() && (m_Plot != null)) {
m_Plot.clearAll();
InterfaceDataTypeDouble indy = (InterfaceDataTypeDouble)this.m_Population.get(0);
double[][] range = indy.getDoubleRange();
m_Plot.setCornerPoints(range, 0);
}
}
/**
@ -1312,9 +1341,6 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
if (this.m_Plot == null) {
InterfaceDataTypeDouble indy = (InterfaceDataTypeDouble)this.m_Population.get(0);
double[][] range = indy.getDoubleRange();
double[] tmpD = new double[2];
tmpD[0] = 0;
tmpD[1] = 0;
this.m_Plot = new eva2.gui.Plot("PSO "+ m_Population.getGeneration(), "x1", "x2", range[0], range[1]);
// this.m_Plot.setUnconnectedPoint(range[0][0], range[1][0], 0);
// this.m_Plot.setUnconnectedPoint(range[0][1], range[1][1], 0);
@ -1399,9 +1425,11 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
}
public void setPopulation(Population pop){
this.m_Population = pop;
for (int i=0; i<pop.size(); i++) {
if (pop.size() != pop.getPopulationSize()) { // new particle count!
init();
} else for (int i=0; i<pop.size(); i++) {
AbstractEAIndividual indy = pop.getEAIndividual(i);
if (indy.getData(partTypeKey) == null) {
if (indy.hasData(partTypeKey)) {
initIndividualDefaults(indy);
initIndividualMemory(indy);
indy.SetData(indexKey, i);

View File

@ -363,8 +363,7 @@ public class Tribes implements InterfaceOptimizer, java.io.Serializable {
// tmpD[0] = 0;
// tmpD[1] = 0;
this.m_Plot = new eva2.gui.Plot("TRIBES "+ population.getGeneration(), "x1", "x2", range[0], range[1]);
// this.m_Plot.setUnconnectedPoint(range[0][0], range[1][0], 0);
// this.m_Plot.setUnconnectedPoint(range[0][1], range[1][1], 0);
// this.m_Plot.setCornerPoints(range, 0);
}
}

View File

@ -4,17 +4,12 @@ package eva2.server.modules;
import java.io.Serializable;
import eva2.server.go.InterfaceGOParameters;
import eva2.server.go.InterfacePopulationChangedEventListener;
import eva2.server.go.InterfaceTerminator;
import eva2.server.go.operators.selection.InterfaceSelection;
import eva2.server.go.enums.DETypeEnum;
import eva2.server.go.operators.terminators.EvaluationTerminator;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.F1Problem;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.server.go.strategies.DifferentialEvolution;
import eva2.server.go.strategies.GeneticAlgorithm;
import eva2.server.go.strategies.InterfaceOptimizer;
import eva2.tools.SelectedTag;
import eva2.tools.Serializer;
/** The class gives access to all DE parameters for the EvA
@ -132,10 +127,10 @@ public class DEParameters extends AbstractGOParameters implements InterfaceGOPar
/** This method allows you to choose the type of Differential Evolution.
* @param s The type.
*/
public void setDEType(SelectedTag s) {
public void setDEType(DETypeEnum s) {
((DifferentialEvolution)this.m_Optimizer).setDEType(s);
}
public SelectedTag getDEType() {
public DETypeEnum getDEType() {
return ((DifferentialEvolution)this.m_Optimizer).getDEType();
}
public String dETypeTipText() {

View File

@ -189,9 +189,6 @@ public class PSOParameters extends AbstractGOParameters implements InterfaceGOPa
public void setTopology(SelectedTag s) {
((ParticleSwarmOptimization)this.m_Optimizer).setTopology(s);
((ParticleSwarmOptimization)this.m_Optimizer).setGOEShowProperties(getClass());
// GenericObjectEditor.setHideProperty(getClass(), "topologyRange", (s.getSelectedTag().getID() >= 2));
// GenericObjectEditor.setHideProperty(getClass(), "subSwarmRadius", (s.getSelectedTag().getID() != 3));
// GenericObjectEditor.setHideProperty(getClass(), "subSwarmSize", (s.getSelectedTag().getID() != 3));
}
public SelectedTag getTopology() {
return ((ParticleSwarmOptimization)this.m_Optimizer).getTopology();

View File

@ -687,4 +687,30 @@ public class Mathematics {
for (int i=1; i<vals.length; i++) minVal = Math.min(minVal, vals[i]);
return minVal;
}
/**
* Project the values in x to the range given. The range must be an vector of 2d-arrays
* each of which containing lower and upper bound in the i-th dimension.
* x must not be longer than the available ranges.
* Values exceeding the bounds are set on the bound.
* The number of bound violations is returned.
*
* @param x
* @param range
* @return
*/
public static int projectToRange(double[] x, double[][] range) {
int viols = 0;
if (x.length>range.length) System.err.println("Invalid vector length, x is longer than range! (Mathematics.projectToRange)");
for (int i=0; i<x.length; i++) {
if (x[i]<range[i][0]) {
viols++;
x[i]=range[i][0];
} else if (x[i]>range[i][1]) {
viols++;
x[i]=range[i][1];
}
}
return viols;
}
}

View File

@ -307,5 +307,37 @@ public class RNG extends Random {
Mathematics.normVect(result, result);
return result;
}
/**
* Create a uniform random double vector within the given bounds (inclusive) in every dimension.
*
* @param n
* @param lower
* @param upper
* @return
*/
public static double[] randomVector(int n, double lower, double upper) {
double[] result = new double[n];
for (int i = 0; i < result.length; i++) {
result[i] = RNG.randomDouble(lower, upper);
}
return result;
}
/**
* Create a uniform random integer vector within the given bounds (inclusive) in every dimension.
*
* @param n
* @param lower
* @param upper
* @return
*/
public static int[] randomVector(int n, int lower, int upper) {
int[] result = new int[n];
for (int i = 0; i < result.length; i++) {
result[i] = RNG.randomInt(lower, upper);
}
return result;
}
}