Restructured Terminators, added ParetoFrontTerminator (may terminate on a pareto metric) and an alternative comparator using weighted recombinations of the individual fitness (and a terminator that employs this).

This commit is contained in:
Marcel Kronfeld 2010-08-13 14:05:51 +00:00
parent e12ab22e31
commit aa3c903645
18 changed files with 816 additions and 355 deletions

View File

@ -21,7 +21,6 @@ import java.util.Comparator;
*
*/
public class AbstractEAIndividualComparator implements Comparator<Object>, Serializable {
// flag whether a data field should be used.
private String indyDataKey = "";
private int fitCriterion = -1;
@ -51,7 +50,7 @@ public class AbstractEAIndividualComparator implements Comparator<Object>, Seria
}
/**
* Constructor for a specific fitness criterion in the multiobjective case.
* Constructor for a specific fitness criterion in the multi-objective case.
* For comparison, only the given fitness criterion is used if it is >= 0.
*
* @param fitnessCriterion
@ -60,10 +59,34 @@ public class AbstractEAIndividualComparator implements Comparator<Object>, Seria
this("", fitnessCriterion, true);
}
/**
* Constructor for a specific fitness criterion in the multi-objective case.
* For comparison, only the given fitness criterion is used if it is >= 0.
* If preferFeasible is true, feasible individuals will always be prefered.
*
* @param fitIndex
* @param preferFeasible
*/
public AbstractEAIndividualComparator(int fitIndex, boolean preferFeasible) {
this("", fitIndex, preferFeasible);
}
@Override
public boolean equals(Object other) {
if (other instanceof AbstractEAIndividualComparator) {
AbstractEAIndividualComparator o = (AbstractEAIndividualComparator)other;
if ((indyDataKey==o.indyDataKey) || (indyDataKey!=null && (indyDataKey.equals(o.indyDataKey)))) {
if ((fitCriterion == o.fitCriterion) && (preferFeasible == o.preferFeasible)) return true;
}
}
return false;
}
@Override
public int hashCode() {
return indyDataKey.hashCode()+100+fitCriterion+(preferFeasible ? 7 : 13);
}
/**
* Generic constructor.
*

View File

@ -0,0 +1,110 @@
package eva2.server.go.individuals;
import java.io.Serializable;
import java.util.Comparator;
import eva2.tools.EVAERROR;
/**
* Compare two individuals based on a linear combination of the fitness values.
*
* @author mkron
*
*/
public class IndividualWeightedFitnessComparator implements Comparator<Object>, Serializable {
private double [] fitWeights = null;
public IndividualWeightedFitnessComparator(double[] weights) {
setFitWeights(weights);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof IndividualWeightedFitnessComparator) {
IndividualWeightedFitnessComparator o = (IndividualWeightedFitnessComparator)obj;
if (fitWeights==null && (o.fitWeights==null)) return true;
if (fitWeights==null || o.fitWeights==null) return false;
// now both are non null:
if (fitWeights.length==o.fitWeights.length) {
for (int i=0; i<fitWeights.length; i++) {
if (fitWeights[i]!=o.fitWeights[i]) return false;
}
return true;
}
}
return false;
}
@Override
public int hashCode() {
if (fitWeights==null) return super.hashCode();
int code=0;
for (int i=0; i<fitWeights.length; i++) {
code+=(int)(fitWeights[i]*10000)%(10000*(i+1));
}
return code;
}
@Override
public int compare(Object o1, Object o2) {
double[] f1 = ((AbstractEAIndividual) o1).getFitness();
double[] f2 = ((AbstractEAIndividual) o2).getFitness();
double score1 = calcScore(f1);
double score2 = calcScore(f2);
if (score1 < score2) return -1;
else if (score1 > score2) return 1;
else return 0;
}
private double calcScore(double[] f) {
if (f==null || fitWeights==null) throw new RuntimeException("Error, missing information in " + this.getClass());
if (f.length!=fitWeights.length) {
if (f.length<fitWeights.length) EVAERROR.errorMsgOnce("Warning, fitness vector has less dimensions than the weights... some weights are ignored, in " + this.getClass());
else EVAERROR.errorMsgOnce("Warning, fitness vector has more dimensions than the weights... some fitness values are ignored, in " + this.getClass());
}
double s = 0;
for (int i=0; i<Math.min(f.length, fitWeights.length); i++) {
s += f[i]*fitWeights[i];
}
return s;
}
public double calcScore(AbstractEAIndividual indy) {
double[] f = indy.getFitness();
return calcScore(f);
}
public void setAllWeights(int dim, double v) {
fitWeights = new double[dim];
for (int i = 0; i < fitWeights.length; i++) {
fitWeights[i]=v;
}
}
public void setFitWeights(double [] fitWeights) {
this.fitWeights = fitWeights;
}
public double [] getFitWeights() {
return fitWeights;
}
public String fitWeightsTipText() {
return "Weights of the fitness values in the linear combination";
}
// public static void main(String[] args) {
// TF1Problem prob = new TF1Problem();
// Population pop = new Population(10);
// prob.initPopulation(pop);
// prob.evaluate(pop);
// System.out.println(pop.getStringRepresentation());
// System.out.println("***");
// IndividualWeightedFitnessComparator wfComp = new IndividualWeightedFitnessComparator(new double[]{0.5,0.5});
// System.out.println("***"); System.out.println(pop.getSortedPop(wfComp).getStringRepresentation());
// wfComp.setFitWeights(new double[] {0.1, 0.9});
// System.out.println("***"); System.out.println(pop.getSortedPop(wfComp).getStringRepresentation());
// wfComp.setFitWeights(new double[] {0.9, 0.1});
// System.out.println("***"); System.out.println(pop.getSortedPop(wfComp).getStringRepresentation());
// }
}

View File

@ -2,6 +2,7 @@ package eva2.server.go.operators.cluster;
import eva2.gui.BeanInspector;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.AbstractEAIndividualComparator;
import eva2.server.go.operators.distancemetric.InterfaceDistanceMetric;
import eva2.server.go.operators.distancemetric.PhenotypeMetric;
import eva2.server.go.populations.Population;
@ -72,7 +73,8 @@ public class ClusteringDynPeakIdent implements InterfaceClustering, java.io.Seri
}
public Population[] cluster(Population pop, Population referenceSet) {
Population sorted = pop.getSortedBestFirst();
AbstractEAIndividualComparator eaComparator = new AbstractEAIndividualComparator(-1);
Population sorted = pop.getSortedBestFirst(eaComparator);
Population peaks = performDynPeakIdent(metric, sorted, numNiches, nicheRadius);
Population[] clusters = new Population[peaks.size()+1];
for (int i=0; i<clusters.length; i++) clusters[i]=new Population();

View File

@ -191,7 +191,12 @@ public class PhenotypeMetric implements InterfaceDistanceMetric, java.io.Seriali
System.err.println("error: unknown individual interface in PhenotypeMetric::norm " + BeanInspector.toString(indy));
return 0;
}
/**
* Calculates the 2 norm of a given vector.
* @param v1
* @return
*/
public static double norm(double[] v1) {
double result = 0;
for (int i = 0; i < v1.length; i++) {

View File

@ -8,6 +8,7 @@ import eva2.gui.GenericObjectEditor;
import eva2.server.go.InterfacePopulationChangedEventListener;
import eva2.server.go.enums.ESMutationInitialSigma;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.AbstractEAIndividualComparator;
import eva2.server.go.individuals.InterfaceDataTypeDouble;
import eva2.server.go.operators.distancemetric.EuclideanMetric;
import eva2.server.go.populations.Population;
@ -306,7 +307,7 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
* @param selectedP
*/
public void adaptAfterSelection(Population oldGen, Population selectedP) {
Population selectedSorted = selectedP.getSortedBestFirst();
Population selectedSorted = selectedP.getSortedBestFirst(new AbstractEAIndividualComparator(-1));
int mu,lambda;
mu = selectedP.size();

View File

@ -215,6 +215,6 @@ public class MetricS implements InterfaceParetoFrontMetric, java.io.Serializable
* @return description
*/
public static String globalInfo() {
return "Calculating the hybervolume UNDER the given Pareto-front.";
return "Calculating the hypervolume UNDER the given Pareto-front.";
}
}

View File

@ -203,7 +203,7 @@ public class PostProcess {
int n = Math.max(1, (int)(returnQuota*clusters[j].size())); // return at least one per cluster!
switch (takeOverMode) {
case BEST_ONLY: // another easy case
result.addAll((Collection<AbstractEAIndividual>)(clusters[j].getBestNIndividuals(n)));
result.addAll((Collection<AbstractEAIndividual>)(clusters[j].getBestNIndividuals(n, -1)));
break;
case BEST_RAND:
Population exclude = new Population();
@ -1075,7 +1075,7 @@ public class PostProcess {
//////////// multimodal data output
evaluateMultiModal(outputPop, problem, listener);
Population nBestPop = outputPop.getBestNIndividuals(params.getPrintNBest()); // n individuals are returned and sorted, all of them if n<=0
Population nBestPop = outputPop.getBestNIndividuals(params.getPrintNBest(), -1); // n individuals are returned and sorted, all of them if n<=0
if (listener != null) listener.println("Best after post process:" + ((outputPop.size()>nBestPop.size()) ? ( " (first " + nBestPop.size() + " of " + outputPop.size() + ")") : (" (" + nBestPop.size() + ")") ));
//////////// output some individual data
if (listener != null) for (int i=0; i<nBestPop.size(); i++) {

View File

@ -1,235 +1,51 @@
package eva2.server.go.operators.terminators;
/*
* Title: EvA2
* Description:
* Copyright: Copyright (c) 2003
* Company: University of Tuebingen, Computer Architecture
* @author Holger Ulmer, Felix Streichert, Hannes Planatscher
* @version: $Revision: 319 $
* $Date: 2007-12-05 11:29:32 +0100 (Wed, 05 Dec 2007) $
* $Author: mkron $
*/
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.io.Serializable;
import eva2.gui.BeanInspector;
import eva2.server.go.InterfaceTerminator;
import eva2.server.go.PopulationInterface;
import eva2.server.go.operators.distancemetric.EuclideanMetric;
import eva2.server.go.operators.distancemetric.PhenotypeMetric;
import eva2.server.go.populations.InterfaceSolutionSet;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.tools.SelectedTag;
import eva2.tools.math.Mathematics;
/*==========================================================================*
* CLASS DECLARATION
*==========================================================================*/
/**
*
* Fitness convergence is measured as the norm of the best fitness of the population.
* The PopulationMeasureTerminator is then used with this measure.
*
* @see PopulationMeasureTerminator
*/
public class FitnessConvergenceTerminator implements InterfaceTerminator,
Serializable {
private static final long serialVersionUID = 5749620193474954959L;
protected static boolean TRACE = false;
protected double convThresh = 0.01;
protected int m_stagTime = 100;
protected int popFitCalls = 1000;
protected int popGens = 1000;
protected boolean firstTime = true;
protected double[] oldFit;
protected double oldNorm;
private SelectedTag stagnationMeasure = new SelectedTag("Fitness calls", "Generations");
private SelectedTag convergenceCondition = new SelectedTag("Relative", "Absolute");
private String msg="";
protected String tagString = "Fitness converged";
PhenotypeMetric pMetric = null;
public class FitnessConvergenceTerminator extends PopulationMeasureTerminator
implements InterfaceTerminator, Serializable {
public FitnessConvergenceTerminator() {
pMetric = new PhenotypeMetric();
super();
}
public FitnessConvergenceTerminator(double thresh, int stagnPeriod, boolean bFitCallBased, boolean bAbsolute) {
pMetric = new PhenotypeMetric();
convThresh = thresh;
this.m_stagTime = stagnPeriod;
if (bFitCallBased) stagnationMeasure.setSelectedTag("Fitness calls");
else stagnationMeasure.setSelectedTag("Generations");
if (bAbsolute) convergenceCondition.setSelectedTag("Absolute");
else convergenceCondition.setSelectedTag("Relative");
public FitnessConvergenceTerminator(double thresh, int stagnPeriod, boolean bFitCallBased, boolean bAbsolute, boolean bImprovement) {
super(thresh, stagnPeriod, bFitCallBased, ChangeTypeEnum.absoluteChange, bImprovement);
}
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());
super(other);
}
/**
*
*/
public static String globalInfo() {
return "Stop if a fitness convergence criterion has been met.";
}
public void init(InterfaceOptimizationProblem prob) {
if (pMetric == null) pMetric = new PhenotypeMetric();
firstTime = true;
msg = "Not terminated.";
tagString = "Fitness converged";
@Override
protected double calcInitialMeasure(PopulationInterface pop) {
return Mathematics.norm(pop.getBestFitness());
}
public boolean isTerminated(InterfaceSolutionSet solSet) {
return isTerminated(solSet.getCurrentPopulation());
@Override
protected double calcPopulationMeasure(PopulationInterface pop) {
// if (oldFit==null) return Double.MAX_VALUE;
// return EuclideanMetric.euclideanDistance(oldFit, pop.getBestFitness());
return Mathematics.norm(pop.getBestFitness());
}
public boolean isTerminated(PopulationInterface Pop) {
if (!firstTime && isStillConverged(Pop)) {
if (stagnationTimeHasPassed(Pop)) {
// population hasnt changed much for max time, criterion is met
msg = getTerminationMessage(tagString);
return true;
} else {
// population hasnt changed much for i<max time, keep running
return false;
}
} else {
// first call at all - or population improved more than "allowed" to terminate
saveState(Pop);
return false;
}
}
public String lastTerminationMessage() {
return msg;
}
protected String getTerminationMessage(String prefix) {
StringBuffer sb = new StringBuffer(prefix);
if (convergenceCondition.isSelectedString("Relative")) sb.append(" relatively below ");
else sb.append(" absolutely below ");
sb.append(convThresh);
sb.append(" for ");
sb.append(m_stagTime);
if (stagnationMeasure.isSelectedString("Generations")) sb.append(" generations.");
else sb.append(" function calls.");
return sb.toString();
}
protected void saveState(PopulationInterface Pop) {
oldFit = Pop.getBestFitness().clone();
oldNorm = PhenotypeMetric.norm(oldFit);
popFitCalls = Pop.getFunctionCalls();
popGens = Pop.getGeneration();
firstTime = false;
}
/**
* Return true if |oldFit - curFit| < |oldFit| * thresh (relative case)
* and if |oldFit - curFit| < thresh (absolute case).
*
* @param curFit
* @return
*/
protected boolean isStillConverged(PopulationInterface pop) {
double[] curFit = pop.getBestFitness();
double dist = EuclideanMetric.euclideanDistance(oldFit, curFit);
boolean ret;
if (convergenceCondition.isSelectedString("Relative")) {
ret = (dist < (oldNorm * convThresh));
} else {
ret = (dist < convThresh);
}
if (TRACE) System.out.println("isStillConverged returns " + ret + ", dist " + dist + ", old fit " + BeanInspector.toString(oldFit) + ", curFit " + BeanInspector.toString(curFit));
return ret;
}
private boolean stagnationTimeHasPassed(PopulationInterface pop) {
if (stagnationMeasure.isSelectedString("Fitness calls")) { // by fitness calls
// System.out.println("stagnationTimeHasPassed returns " + ((pop.getFunctionCalls() - popFitCalls) >= m_stagTime) + " after " + (pop.getFunctionCalls() - popFitCalls));
return (pop.getFunctionCalls() - popFitCalls) >= m_stagTime;
} else {// by generation
// System.out.println("stagnationTimeHasPassed returns " + ((pop.getFunctionCalls() - popGens) >= m_stagTime) + " after " + (pop.getFunctionCalls() - popGens));
return (pop.getGeneration() - popGens) >= m_stagTime;
}
}
/**
*
*/
public void setConvergenceThreshold(double x) {
convThresh = x;
}
/**
*
*/
public double getConvergenceThreshold() {
return convThresh;
}
public String convergenceThresholdTipText() {
return "Terminate if the fitness has not improved by this percentage / absolute value for a whole stagnation time period";
}
/**
*
*/
public void setStagnationTime(int k) {
m_stagTime = k;
}
/**
*
*/
public int getStagnationTime() {
return m_stagTime;
}
public String stagnationTimeTipText() {
return "Terminate if the population has not improved for this time";
}
/**
* @return the stagnationTimeIn
*/
public SelectedTag getStagnationMeasure() {
return stagnationMeasure;
}
/**
* @param stagnationTimeIn the stagnationTimeIn to set
*/
public void setStagnationMeasure(SelectedTag stagnationTimeIn) {
this.stagnationMeasure = stagnationTimeIn;
}
public String stagnationMeasureTipText() {
return "Stagnation time is measured in fitness calls or generations, to be selected here.";
}
/**
* @return the convergenceCondition
*/
public SelectedTag getConvergenceCondition() {
return convergenceCondition;
}
/**
* @param convergenceCondition the convergenceCondition to set
*/
public void setConvergenceCondition(SelectedTag convergenceCondition) {
this.convergenceCondition = convergenceCondition;
}
public String convergenceConditionTipText() {
return "Select between absolute and relative convergence condition";
@Override
protected String getMeasureName() {
return "Fitness";
}
}

View File

@ -0,0 +1,102 @@
package eva2.server.go.operators.terminators;
import java.io.Serializable;
import eva2.gui.BeanInspector;
import eva2.server.go.PopulationInterface;
import eva2.server.go.operators.paretofrontmetrics.InterfaceParetoFrontMetric;
import eva2.server.go.operators.paretofrontmetrics.MetricS;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.AbstractMultiObjectiveOptimizationProblem;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.tools.EVAERROR;
/**
* Employ a pareto metric to determine convergence of a population. Requires to be run
* with a AbstractMultiObjectiveOptimizationProblem instance since the metric depend
* on the fitness range.
* The metric may be employed on the current population or the current pareto front
* maintained by the problem instance.
*
* @author mkron
*
*/
public class ParetoMetricTerminator extends PopulationMeasureTerminator implements Serializable {
private InterfaceParetoFrontMetric pMetric = new MetricS();
AbstractMultiObjectiveOptimizationProblem moProb=null;
private boolean useCurrentPop = false;
public ParetoMetricTerminator() {
moProb=null;
}
//public PopulationMeasureTerminator(double convergenceThreshold, int stagnationTime, boolean bFitCallBased, ChangeTypeEnum detectChangeType, boolean bImprovement) {
public ParetoMetricTerminator(InterfaceParetoFrontMetric metric, boolean useCurrentPop, double convergenceThreshold, int stagnationTime, boolean bFitCallBased, ChangeTypeEnum detectChangeType, boolean bImprovement) {
super(convergenceThreshold, stagnationTime, bFitCallBased, detectChangeType, bImprovement);
this.pMetric = metric;
this.useCurrentPop = useCurrentPop;
}
public ParetoMetricTerminator(ParetoMetricTerminator o) {
super(o);
this.pMetric = (InterfaceParetoFrontMetric)o.pMetric.clone();
this.moProb = o.moProb;
this.useCurrentPop = o.useCurrentPop;
}
@Override
public void init(InterfaceOptimizationProblem prob) {
super.init(prob);
if (prob instanceof AbstractMultiObjectiveOptimizationProblem) moProb = (AbstractMultiObjectiveOptimizationProblem)prob;
else {
moProb = null;
EVAERROR.errorMsgOnce("Error, " + this.getClass() + " works only with problems inheriting from " + AbstractMultiObjectiveOptimizationProblem.class + "!");
}
}
@Override
protected double calcInitialMeasure(PopulationInterface pop) {
if (moProb==null) return Double.MAX_VALUE;
else {
if (isUseCurrentPop()) return getParetoMetric().calculateMetricOn((Population)pop, moProb);
else return getParetoMetric().calculateMetricOn(moProb.getLocalParetoFront(), moProb);
}
}
@Override
protected double calcPopulationMeasure(PopulationInterface pop) {
return calcInitialMeasure(pop);
}
@Override
protected String getMeasureName() {
String metricName=null;
try {
metricName = (String)BeanInspector.callIfAvailable(getParetoMetric(), "getName", null);
} catch(ClassCastException e) {metricName=null;}
if (metricName==null) return "ParetoMetric";
else return metricName;
}
public void setParetoMetric(InterfaceParetoFrontMetric pMetric) {
this.pMetric = pMetric;
}
public InterfaceParetoFrontMetric getParetoMetric() {
return pMetric;
}
public String paretoMetricTipText() {
return "The pareto metric to use";
}
public void setUseCurrentPop(boolean useCurrentPop) {
this.useCurrentPop = useCurrentPop;
}
public boolean isUseCurrentPop() {
return useCurrentPop;
}
public String useCurrentPopTipText() {
return "If true, the current population is used, otherwise the pareto front of the multi-objective problem instance is used";
}
}

View File

@ -1,53 +1,64 @@
package eva2.server.go.operators.terminators;
import eva2.gui.BeanInspector;
import eva2.server.go.IndividualInterface;
import eva2.server.go.InterfaceTerminator;
import eva2.server.go.PopulationInterface;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.operators.distancemetric.PhenotypeMetric;
import eva2.server.go.problems.InterfaceOptimizationProblem;
public class PhenotypeConvergenceTerminator extends FitnessConvergenceTerminator implements InterfaceTerminator {
public class PhenotypeConvergenceTerminator extends PopulationMeasureTerminator implements InterfaceTerminator {
AbstractEAIndividual oldIndy = null;
double oldPhenNorm = 0;
private PhenotypeMetric pMetric = null;
// double oldPhenNorm = 0;
public PhenotypeConvergenceTerminator() {
super();
tagString = "Phenotype converged";
pMetric = new PhenotypeMetric();
}
public PhenotypeConvergenceTerminator(double thresh, int stagnTime, boolean bFitCallBased, ChangeTypeEnum changeType, boolean bImprovement) {
super(thresh, stagnTime, bFitCallBased, changeType, bImprovement);
pMetric = new PhenotypeMetric();
}
public PhenotypeConvergenceTerminator(double thresh, int stagnTime, boolean bFitCallBased, boolean bAbsolute) {
super(thresh, stagnTime, bFitCallBased, bAbsolute);
public PhenotypeConvergenceTerminator(PhenotypeConvergenceTerminator o) {
super(o);
oldIndy = (AbstractEAIndividual)o.oldIndy.clone();
pMetric = (PhenotypeMetric)o.pMetric.clone();
// oldPhenNorm = o.oldPhenNorm;
}
public void init(InterfaceOptimizationProblem prob) {
super.init(prob);
tagString = "Phenotype converged";
// oldPhenNorm = 0;
oldIndy = null;
}
/**
* Return true if |oldPhen - curPhen| < |oldPhen| * thresh (relative case)
* and if |oldFit - curFit| < thresh (absolute case).
*
* @param curFit
* @return
*/
protected boolean isStillConverged(PopulationInterface pop) {
double dist = pMetric.distance(oldIndy, (AbstractEAIndividual)pop.getBestIndividual());
boolean ret;
if (getConvergenceCondition().isSelectedString("Relative")) {
ret = (dist < (oldPhenNorm * convThresh));
} else {
ret = (dist < convThresh);
}
if (TRACE) System.out.println("isStillConverged returns " + ret + ", dist " + dist + ", old indy " + BeanInspector.toString(oldIndy) + ", cur indy" + BeanInspector.toString(pop.getBestIndividual()));
return ret;
@Override
protected double calcInitialMeasure(PopulationInterface pop) {
oldIndy = (AbstractEAIndividual)((AbstractEAIndividual)pop.getBestIndividual()).clone();
// oldPhenNorm = PhenotypeMetric.norm(oldIndy);
return Double.MAX_VALUE;
}
@Override
protected double calcPopulationMeasure(PopulationInterface pop) {
return pMetric.distance(oldIndy, (AbstractEAIndividual)pop.getBestIndividual());
}
@Override
protected void saveState(PopulationInterface Pop) {
super.saveState(Pop);
oldIndy = (AbstractEAIndividual)((AbstractEAIndividual)Pop.getBestIndividual()).clone();
oldPhenNorm = PhenotypeMetric.norm(oldIndy);
// oldPhenNorm = PhenotypeMetric.norm(oldIndy);
}
@Override
protected String getMeasureName() {
return "Phenotype";
}
public static String globalInfo() {
return "Terminate if the best individual of the current population moved less than a threshold within phenotypic space.";
}
}

View File

@ -0,0 +1,64 @@
package eva2.server.go.operators.terminators;
import eva2.server.go.PopulationInterface;
import eva2.server.go.individuals.IndividualWeightedFitnessComparator;
import eva2.server.go.populations.Population;
/**
* Terminate if a score based on the archive of the population converges.
* Note that this only works if the archive is filled with sensible data.
*
* @author mkron
*
*/
public class PopulationArchiveTerminator extends PopulationMeasureTerminator {
IndividualWeightedFitnessComparator wfComp = new IndividualWeightedFitnessComparator(null);
// private boolean isStillConverged(PopulationInterface pop) {
// Population archive = ((Population)pop).getArchive();
// if (archive==null || (archive.size()<1)) {
// System.err.println("Error, population had no archive in " + this.getClass());
// return false;
// } else {
// double bestScore = Population.getScore(archive.getEAIndividual(0), fitWeights);
// for (int i=1; i<archive.size(); i++) {
// double tmpScore = Population.getScore(archive.getEAIndividual(i), fitWeights);
// if (tmpScore<bestScore) bestScore=tmpScore;
// }
// if (bestScore>=oldScore) return true;
// else {
// oldScore=bestScore;
// return false;
// }
// }
// }
@Override
protected double calcInitialMeasure(PopulationInterface pop) {
Population archive = ((Population)pop).getArchive();
if (archive==null || (archive.size()<1)) return Double.MAX_VALUE;
else return wfComp.calcScore(archive.getBestEAIndividual(wfComp));
}
@Override
protected double calcPopulationMeasure(PopulationInterface pop) {
Population archive = ((Population)pop).getArchive();
if (archive==null || (archive.size()<1)) return Double.MAX_VALUE;
else return wfComp.calcScore(archive.getBestEAIndividual(wfComp));
}
@Override
protected String getMeasureName() {
return "Archive Weighted Score";
}
public double[] getFitWeights() {
return wfComp.getFitWeights();
}
public void setFitWeights(double[] fWeights) {
wfComp.setFitWeights(fWeights);
}
public String fitWeightsTipText() {
return wfComp.fitWeightsTipText();
}
}

View File

@ -0,0 +1,326 @@
package eva2.server.go.operators.terminators;
import java.io.Serializable;
import eva2.gui.BeanInspector;
import eva2.server.go.InterfaceTerminator;
import eva2.server.go.PopulationInterface;
import eva2.server.go.populations.InterfaceSolutionSet;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.tools.SelectedTag;
/**
* Abstract class giving the framework for a terminator that is based on
* a population measure converging for a given time (number of evaluations or
* generations).
* The class detects changes of a population measure over time and may signal convergence
* if the measure m(P) behaved in a certain way for a given time. Convergence may
* be signaled
* - if the measure reached absolute values below convThresh (absolute value),
* - if the measure remained within m(P)+/-convThresh (absolute change),
* - if the measure remained above m(P)-convThresh (absolute change and regard improvement only),
* - if the measure remained within m(P)*[1-convThresh, 1+convThresh] (relative change),
* - if the measure remained above m(P)*(1-convThresh) (relative change and regard improvement only).
*
* @author mkron
*
*/
public abstract class PopulationMeasureTerminator implements InterfaceTerminator,
Serializable {
public enum ChangeTypeEnum {relativeChange, absoluteChange, absoluteValue};
protected static boolean TRACE = false;
private double convThresh = 0.01; //, convThreshLower=0.02;
private double oldMeasure = -1;
private int stagTime = 1000;
private int oldPopFitCalls = 1000;
private int oldPopGens = 1000;
private boolean firstTime = true;
private SelectedTag stagnationMeasure = new SelectedTag("Fitness calls", "Generations");
// private SelectedTag convCondition = new SelectedTag("Relative change", "Absolute change", "Absolute value");
private ChangeTypeEnum changeType = ChangeTypeEnum.relativeChange;
private SelectedTag condImprovementOrChange = new SelectedTag("Improvement", "Improvement and Deterioration");
protected String msg="Not terminated.";
public PopulationMeasureTerminator() {}
public PopulationMeasureTerminator(double convergenceThreshold, int stagnationTime, boolean bFitCallBased, ChangeTypeEnum detectChangeType, boolean bImprovement) {
convThresh = convergenceThreshold;
stagTime = stagnationTime;
stagnationMeasure.setSelectedTag(bFitCallBased ? 0 : 1);
// convergenceCondition.setSelectedTag(bAbsolute ? 1 : 0);
changeType = detectChangeType;
condImprovementOrChange.setSelectedTag(bImprovement ? 0 : 1);
}
public PopulationMeasureTerminator(PopulationMeasureTerminator o) {
convThresh = o.convThresh;
stagTime = o.stagTime;
oldPopFitCalls = o.oldPopFitCalls;
oldPopGens = o.oldPopGens;
firstTime = o.firstTime;
// oldFit = o.oldFit.clone();
// oldNorm = o.oldNorm;
msg = o.msg;
this.stagnationMeasure.setSelectedTag(o.stagnationMeasure.getSelectedTagID());
// this.convergenceCondition.setSelectedTag(o.convergenceCondition.getSelectedTagID());
this.changeType = o.changeType;
this.condImprovementOrChange.setSelectedTag(o.condImprovementOrChange.getSelectedTagID());
}
// public void hideHideable() {
// setConvergenceCondition(getConvergenceCondition());
// }
// public PopulationMeasureTerminator() {
// pMetric = new PhenotypeMetric();
// }
//
// public PopulationMeasureTerminator(double thresh, int stagnPeriod, boolean bFitCallBased, boolean bAbsolute) {
// pMetric = new PhenotypeMetric();
// convThresh = thresh;
// this.m_stagTime = stagnPeriod;
// if (bFitCallBased) stagnationMeasure.setSelectedTag("Fitness calls");
// else stagnationMeasure.setSelectedTag("Generations");
// if (bAbsolute) convergenceCondition.setSelectedTag("Absolute");
// else convergenceCondition.setSelectedTag("Relative");
// }
//
// public PopulationMeasureTerminator(PopulationMeasureTerminator other) {
// pMetric = new PhenotypeMetric();
// convThresh = other.convThresh;
// this.m_stagTime = other.m_stagTime;
// stagnationMeasure.setSelectedTag(other.getStagnationMeasure().getSelectedTagID());
// convergenceCondition.setSelectedTag(other.getConvergenceCondition().getSelectedTagID());
// }
public static String globalInfo() {
return "Stop if a convergence criterion has been met.";
}
public void init(InterfaceOptimizationProblem prob) {
firstTime = true;
msg = "Not terminated.";
// oldFit = null;
// oldNorm=-1;
oldPopFitCalls=-1;
oldPopGens=-1;
}
public boolean isTerminated(InterfaceSolutionSet solSet) {
return isTerminated(solSet.getCurrentPopulation());
}
public boolean isTerminated(PopulationInterface pop) {
if (!firstTime && isStillConverged(pop)) {
if (TRACE) System.out.println("Converged at " + pop.getGeneration() + "/" + pop.getFunctionCalls() + ", measure " + calcPopulationMeasure(pop));
if (stagnationTimeHasPassed(pop)) {
// population hasnt changed much for max time, criterion is met
msg = getTerminationMessage();
return true;
} else {
// population hasnt changed much for i<max time, keep running
return false;
}
} else {
// first call at all - or population improved more than "allowed" to terminate
oldMeasure = calcInitialMeasure(pop);
saveState(pop);
return false;
}
}
/**
* Calculate the initial measure (on the initial population).
* @return
*/
protected abstract double calcInitialMeasure(PopulationInterface pop);
public String lastTerminationMessage() {
return msg;
}
/**
* Build a standard termination message based on the configuration.
* @return
*/
protected String getTerminationMessage() {
StringBuffer sb = new StringBuffer(getMeasureName());
// if (convergenceCondition.isSelectedString("Relative")) sb.append(" converged relatively ");
switch (changeType) {
case absoluteChange: sb.append(" changed absolutely "); break;
case absoluteValue: sb.append(" reached absolute values "); break;
case relativeChange: sb.append(" changed relatively "); break;
}
if (doCheckImprovement()) {
sb.append("less than ");
sb.append(convThresh);
} else {
sb.append("within +/-");
// sb.append(convThreshLower);
// sb.append("/");
sb.append(convThresh);
}
sb.append(" for ");
sb.append(stagTime);
if (stagnationMeasure.isSelectedString("Generations")) sb.append(" generations.");
else sb.append(" function calls.");
return sb.toString();
}
/**
* Give a String description of the name of the population measure.
* @return
*/
protected abstract String getMeasureName();
/**
* Save the population state if a change has been detected.
* When overriding, make sure to call the superclass method.
*
* @param pop
*/
protected void saveState(PopulationInterface pop) {
// oldFit = pop.getBestFitness().clone();
oldMeasure = calcPopulationMeasure(pop);
oldPopFitCalls = pop.getFunctionCalls();
oldPopGens = pop.getGeneration();
firstTime = false;
}
/**
* Calculate the population measure on which the termination
* criterion is based.
*
* @param pop
* @return
*/
protected abstract double calcPopulationMeasure(PopulationInterface pop);
/**
* Return true if the population measure did not exceed the
* threshold for convergence since the last saved state.
*
* @param curFit
* @return
*/
protected boolean isStillConverged(PopulationInterface pop) {
double measure = calcPopulationMeasure(pop);
double allowedLower=Double.MIN_VALUE, allowedUpper=Double.MAX_VALUE;
boolean ret;
switch (changeType) {
case absoluteChange:
allowedLower=oldMeasure-convThresh;
if (!doCheckImprovement()) allowedUpper=oldMeasure+convThresh;
break;
case absoluteValue:
allowedLower=convThresh;
// if (!doCheckImprovement()) allowedUpper = convThreshUpper;
break;
case relativeChange:
double delta = oldMeasure*convThresh;
allowedLower = oldMeasure-delta;
if (!doCheckImprovement()) allowedUpper = oldMeasure+delta;
break;
}
ret = (measure <= allowedUpper) && (measure >= allowedLower);
// Old Version:
// if (isRelativeConvergence()) {
// double delta = oldMeasure*convThresh;
// if (doCheckImprovement()) ret = (measure >= (oldMeasure - delta));
// else ret = ((measure >= (oldMeasure-delta)) && (measure <= (oldMeasure+delta))); // check for rel. change which must be within +/- thresh
// } else { // check absolute values
// if (doCheckImprovement()) ret = (measure < oldMeasure+convThresh); // absolute improvement below fixed number
// else ret = ((measure < oldMeasure+convThresh) && (measure > oldMeasure-convThresh)); // absolute change within fixed range
// }
if (TRACE) System.out.println("isStillConverged returns " + ret + ", measure " + measure + ", old measure " + BeanInspector.toString(oldMeasure) + ", bounds: [" + allowedLower + " , " + allowedUpper + "]");
return ret;
}
public boolean doCheckImprovement() {
return condImprovementOrChange.isSelectedString("Improvement");
}
public boolean isRelativeConvergence() {
return changeType==ChangeTypeEnum.relativeChange;
}
/**
* Return true if the defined stagnation time (function calls or generations) has passed
* since the last noteable change.
*
* @param pop
* @return
*/
private boolean stagnationTimeHasPassed(PopulationInterface pop) {
if (stagnationMeasure.isSelectedString("Fitness calls")) { // by fitness calls
// System.out.println("stagnationTimeHasPassed returns " + ((pop.getFunctionCalls() - popFitCalls) >= m_stagTime) + " after " + (pop.getFunctionCalls() - popFitCalls));
return (pop.getFunctionCalls() - oldPopFitCalls) >= stagTime;
} else {// by generation
// System.out.println("stagnationTimeHasPassed returns " + ((pop.getFunctionCalls() - popGens) >= m_stagTime) + " after " + (pop.getFunctionCalls() - popGens));
return (pop.getGeneration() - oldPopGens) >= stagTime;
}
}
public void setConvergenceThreshold(double x) {
convThresh = x;
}
public double getConvergenceThreshold() {
return convThresh;
}
public String convergenceThresholdTipText() {
return "Ratio of improvement or absolute value of improvement or change to determine convergence.";
}
// public void setConvergenceThresholdLower(double x) {
// convThreshLower = x;
// }
// public double getConvergenceThresholdLower() {
// return convThreshLower;
// }
// public String convergenceThresholdUpperTipText() {
// return "Lower threshold value in case of detecting absolute change, meaning the bounds [measure-convThresh,measure+convThresh] must be kept to assume convergence.";
// }
public void setStagnationTime(int k) {
stagTime = k;
}
public int getStagnationTime() {
return stagTime;
}
public String stagnationTimeTipText() {
return "Terminate if the population has not improved for this time";
}
public SelectedTag getStagnationMeasure() {
return stagnationMeasure;
}
public void setStagnationMeasure(SelectedTag stagnationTimeIn) {
this.stagnationMeasure = stagnationTimeIn;
}
public String stagnationMeasureTipText() {
return "Stagnation time is measured in fitness calls or generations, to be selected here.";
}
public ChangeTypeEnum getConvergenceCondition() {
return changeType;
}
public void setConvergenceCondition(ChangeTypeEnum convergenceCondition) {
this.changeType = convergenceCondition;
// GenericObjectEditor.setHideProperty(this.getClass(), "convergenceThresholdUpper", isRelativeConvergence() || doCheckImprovement());
}
public String convergenceConditionTipText() {
return "Select between absolute and relative convergence condition";
}
public SelectedTag getCheckType() {
return condImprovementOrChange;
}
public void setCheckType(SelectedTag ct) {
this.condImprovementOrChange = ct;
// GenericObjectEditor.setHideProperty(this.getClass(), "convergenceThresholdUpper", isRelativeConvergence() || doCheckImprovement());
}
public String checkTypeTipText() {
return "Detect improvement only (one-directional change) or improvement and deterioration (two-directional change).";
}
}

View File

@ -70,7 +70,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
private int lastQModCount = -1;
// a sorted queue (for efficiency)
transient private ArrayList<AbstractEAIndividual> sortedArr = null;
private int lastFitCrit = -1;
private Comparator<Object> lastSortingComparator = null;
// private AbstractEAIndividualComparator historyComparator = null;
public static final String funCallIntervalReached = "FunCallIntervalReached";
@ -807,21 +807,39 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
/**
* This method will return the index of the current best (worst) individual from the
* population. If indicated, only those are regarded which do not violate the constraints.
* If all violate the constraints, the smallest (largest) violation is selected.
* Comparisons are done multicriterial, but note that for incomparable sets (pareto fronts)
* this selection will not be fair (always the lowest index of incomparable sets will be returned).
* population. A given comparator is employed for individual comparisons.
*
* @param bBest if true, smallest fitness (regarded best) index is returned, else the highest one
* @param indicate whether constraints should be regarded
* @param bBest if true, the best (first) index is returned, else the worst (last) one
* @param comparator indicate whether constraints should be regarded
* @return The index of the best (worst) individual.
*/
public int getIndexOfBestOrWorstIndividual(boolean bBest, AbstractEAIndividualComparator comparator) {
ArrayList<AbstractEAIndividual> sorted = getSorted(comparator);
public int getIndexOfBestOrWorstIndividual(boolean bBest, Comparator<Object> comparator) {
ArrayList<?> sorted = sortBy(comparator);
if (bBest) return indexOf(sorted.get(0));
else return indexOfInstance(sorted.get(sorted.size()-1));
}
public int getIndexOfBestEAIndividual(AbstractEAIndividualComparator comparator) {
return getIndexOfBestOrWorstIndividual(true, comparator);
}
public AbstractEAIndividual getBestEAIndividual(Comparator<Object> comparator) {
int index = getIndexOfBestOrWorstIndividual(true, comparator);
return getEAIndividual(index);
}
/**
* Return the index of the best (or worst) indy using an AbstractEAIndividualComparator
* that checks the constraints first and then for the given fitness criterion (or
* a pareto criterion if it is -1).
*
* @param bBest if true, the best (first) index is returned, else the worst (last) one
* @param checkConstraints
* @param fitIndex
* @see #getIndexOfBestOrWorstIndividual(boolean, Comparator)
* @see AbstractEAIndividualComparator
* @return
*/
public int getIndexOfBestOrWorstIndy(boolean bBest, boolean checkConstraints, int fitIndex) {
return getIndexOfBestOrWorstIndividual(bBest, new AbstractEAIndividualComparator(fitIndex, checkConstraints));
}
@ -981,20 +999,22 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
* @return The m best individuals, where m <= n
*
*/
public Population getBestNIndividuals(int n) {
return getSortedNIndividuals(n, true);
public Population getBestNIndividuals(int n, int fitIndex) {
Population pop = new Population(n);
getSortedNIndividuals(n, true, pop, new AbstractEAIndividualComparator(fitIndex));
return pop;
}
/**
* This method returns a clone of the population instance with sorted individuals, where
* the sorting criterion is delivered by an AbstractEAIndividualComparator.
* @see #getSortedNIndividuals(int, boolean, Population)
* the sorting criterion is delivered by a Comparator.
* @see #getSortedNIndividuals(int, boolean, Population, Comparator)
*
* @return a clone of the population instance with sorted individuals, best fitness first
*/
public Population getSortedBestFirst() {
public Population getSortedBestFirst(Comparator<Object> comp) {
Population result = this.cloneWithoutInds();
getSortedNIndividuals(size(), true, result);
getSortedNIndividuals(size(), true, result, comp);
result.synchSize();
return result;
}
@ -1009,25 +1029,26 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
* @return The m sorted best or worst individuals, where m <= n
*
*/
public Population getSortedNIndividuals(int n, boolean bBestOrWorst) {
Population result = new Population((n > 0) ? n : this.size());
getSortedNIndividuals(n, bBestOrWorst, result);
return result;
}
// public Population getSortedNIndividuals(int n, boolean bBestOrWorst) {
// Population result = new Population((n > 0) ? n : this.size());
// getSortedNIndividuals(n, bBestOrWorst, result);
// return result;
// }
/**
* This method returns the n current best individuals from the population, where
* the sorting criterion is delivered by an AbstractEAIndividualComparator.
* the sorting criterion is delivered by a Comparator instance.
* There are less than n individuals returned if the population is smaller than n.
* This does not check constraints!
*
* @param n number of individuals to look out for
* @param bBestOrWorst if true, the best n are returned, else the worst n individuals
* @param res sorted result population, will be cleared
* @param comparator the Comparator to use with individuals
* @return The m sorted best or worst individuals, where m <= n
*
*/
public void getSortedNIndividuals(int n, boolean bBestOrWorst, Population res) {
public void getSortedNIndividuals(int n, boolean bBestOrWorst, Population res, Comparator<Object> comp) {
if ((n < 0) || (n>super.size())) {
// this may happen, treat it gracefully
//System.err.println("invalid request to getSortedNIndividuals: n="+n + ", size is " + super.size());
@ -1036,7 +1057,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
int skip = 0;
if (!bBestOrWorst) skip = super.size()-n;
ArrayList<AbstractEAIndividual> sorted = getSorted(lastFitCrit);
// hier getSorted aufrufen
ArrayList<AbstractEAIndividual> sorted = getSorted(comp);
res.clear();
for (int i = skip; i < skip+n; i++) {
res.add(sorted.get(i));
@ -1044,6 +1066,18 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
res.synchSize();
}
// /**
// * Get the n best (or worst) individuals from the population. The last comparator
// * is reused, or if none has been employed yet, a standard comparator is used.
// *
// * @param n
// * @param bBestOrWorst
// * @param res
// */
// public void getSortedNIndividuals(int n, boolean bBestOrWorst, Population res) {
// getSortedNIndividuals(n, bBestOrWorst, res, lastSortingComparator);
// }
/**
* From the given list, remove all but the first n elements.
* @param n
@ -1076,11 +1110,13 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
}
/**
* Set a fitness criterion for sorting procedures. This also affects getBest
* Set a fitness criterion for sorting procedures. This sorts the
* population once and influences further getBest* methods if no
* specific comparator is given.
* @param fitIndex
*/
public void setSortingFitnessCriterion(int fitIndex) {
getSorted(fitIndex);
getSorted(new AbstractEAIndividualComparator(fitIndex));
}
// /**
@ -1100,7 +1136,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
* @param comp A comparator by which sorting is performed - it should work on AbstractEAIndividual instances.
* @return
*/
public ArrayList<AbstractEAIndividual> getSorted(Comparator<Object> comp) {
protected ArrayList<AbstractEAIndividual> sortBy(Comparator<Object> comp) {
if (super.size()==0) return new ArrayList<AbstractEAIndividual>();
PriorityQueue<AbstractEAIndividual> sQueue = new PriorityQueue<AbstractEAIndividual>(super.size(), comp);
for (int i = 0; i < super.size(); i++) {
@ -1114,26 +1150,43 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
}
/**
* Avoids having to sort again in several calls without modifications in between.
* The returned array should not be modified!
* Return a sorted list of individuals. The order is based on the
* given comparator. Repeated calls do not resort the population every
* time as long as an equal comparator is used (implement the equals() method!)
* and the population has not been modified.
* The returned array must not be altered!
*
* @param fitIndex the fitness criterion to be used or -1 for pareto dominance
* @return
*/
protected ArrayList<AbstractEAIndividual> getSorted(int fitIndex) {
if ((fitIndex != lastFitCrit) || (sortedArr == null) || (super.modCount != lastQModCount)) {
lastFitCrit=fitIndex;
ArrayList<AbstractEAIndividual> sArr = getSorted(new AbstractEAIndividualComparator(fitIndex));
public ArrayList<AbstractEAIndividual> getSorted(Comparator<Object> comp) {
// Comparator<Object> comp = new AbstractEAIndividualComparator(fitIndex);
// if (!comp.equals(lastSortingComparator)) return sortedArr;
if (!comp.equals(lastSortingComparator) || (sortedArr == null) || (super.modCount != lastQModCount)) {
// lastFitCrit=fitIndex;lastSortingComparator
ArrayList<AbstractEAIndividual> sArr = sortBy(comp);
if (sortedArr==null) sortedArr = sArr;
else {
sortedArr.clear();
sortedArr.addAll(sArr);
}
}
lastSortingComparator = (Comparator<Object>) Serializer.deepClone(comp);
lastQModCount = super.modCount;
}
return sortedArr;
}
/**
* Returns the sorted population as a new population instance.
* @see getSorted(Comparator)
*/
public Population getSortedPop(Comparator<Object> comp) {
Population pop = this.cloneWithoutInds();
ArrayList<AbstractEAIndividual> sortedIndies = getSorted(comp);
pop.addAll(sortedIndies);
return pop;
}
/**
* This method retrieves n random individuals from the population and
* returns them within a new population.

View File

@ -3,8 +3,6 @@ package eva2.server.go.problems;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import javax.swing.JFrame;
@ -21,7 +19,8 @@ import eva2.server.go.operators.moso.MOSONoConvert;
import eva2.server.go.operators.paretofrontmetrics.InterfaceParetoFrontMetric;
import eva2.server.go.operators.paretofrontmetrics.MetricS;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.AbstractOptimizationProblem.EvalThread;
import eva2.server.go.strategies.InterfaceOptimizer;
import eva2.tools.ToolBox;
import eva2.tools.chart2d.Chart2DDPointIconCircle;
import eva2.tools.chart2d.Chart2DDPointIconText;
import eva2.tools.chart2d.DPoint;
@ -352,65 +351,6 @@ public abstract class AbstractMultiObjectiveOptimizationProblem extends Abstract
moProblem.drawAdditionalData(plot, p, 10);
}
}
// /** This method will draw the current state of the optimization process
// * @param p The current population
// */
// public static void drawProblem(Population p, Plot plot, AbstractMultiObjectiveOptimizationProblem moProblem) {
// ArchivingAllDominating tmpArch = new ArchivingAllDominating();
// Population tmpPop = null;
//
// if (p.getGeneration() > 2) {
//// m_Plot = new eva2.gui.Plot("Multiobjective Optimization", "Y1", "Y2");
// // i want to plot the pareto front for MOEA and other strategies
// // but i have to differentiate between the case where
// // there is a true MOEA at work and where the
// // MOOpt was converted into a SOOpt
// if (AbstractMultiObjectiveOptimizationProblem.isPopulationMultiObjective(p)) {
// // in this case i have to use my local archive
// tmpPop = moProblem.m_ParetoFront;
// } else {
// // in this case i use the population of the optimizer
// // and eventually the pop.archive if there is one
// tmpPop = new Population();
// tmpPop.addPopulation(p);
// if (p.getArchive() != null) tmpPop.addPopulation(p.getArchive());
// tmpArch.addElementsToArchive(tmpPop);
// tmpPop = tmpPop.getArchive();
// }
// if (tmpPop != null) {
// // i got either a multiobjective population or a multiobjective local population
// plot.clearAll();
// tmpArch.plotParetoFront(tmpPop, plot);
// if ((true) && (p.getArchive() != null)) {
// GraphPointSet mySet = new GraphPointSet(10, plot.getFunctionArea());
// DPoint myPoint;
// Chart2DDPointIconCircle icon;
// double[] tmpD;
// mySet.setConnectedMode(false);
// tmpPop = p.getArchive();
// for (int i = 0; i < tmpPop.size(); i++) {
// icon = new Chart2DDPointIconCircle();
// tmpD = ((AbstractEAIndividual)tmpPop.get(i)).getFitness();
// myPoint = new DPoint(tmpD[0], tmpD[1]);
// if (((AbstractEAIndividual)tmpPop.get(i)).getConstraintViolation() > 0) {
// icon.setBorderColor(Color.RED);
// icon.setFillColor(Color.RED);
// } else {
// icon.setBorderColor(Color.BLACK);
// icon.setFillColor(Color.BLACK);
// }
// myPoint.setIcon(icon);
// mySet.addDPoint(myPoint);
// }
// }
// } else {
//// // in this case i got a single objective optimization problem
// }
// // draw additional data
// moProblem.drawAdditionalData(plot, p, 10);
// }
// }
/**
* This method will plot a reference solutions or something like it
@ -536,25 +476,33 @@ public abstract class AbstractMultiObjectiveOptimizationProblem extends Abstract
@Override
public String[] getAdditionalFileStringHeader(PopulationInterface pop) {
String[] result = new String[1];
if (AbstractMultiObjectiveOptimizationProblem.isPopulationMultiObjective((Population)pop))
result[0] = "SMetric";
else
result[0] = "BestFitness";
return result;
String[] superHd = super.getAdditionalFileStringHeader(pop);
return ToolBox.appendArrays(new String[]{"paretoMetricCurrent","paretoMetricFront"}, superHd);
}
@Override
public Object[] getAdditionalFileStringValue(PopulationInterface pop) {
Object[] result = new Object[1];
if (AbstractMultiObjectiveOptimizationProblem.isPopulationMultiObjective((Population)pop))
result[0] = this.calculateMetric((Population)pop);
else
result[0] = ((Population)pop).getBestEAIndividual().getFitness()[0];
return result;
Object[] result = new Object[2];
result[0] = this.calculateMetric((Population)pop);
result[1] = this.calculateMetric(getLocalParetoFront());
return ToolBox.appendArrays(result, super.getAdditionalFileStringValue(pop));
}
@Override
public String[] getAdditionalFileStringInfo(PopulationInterface pop) {
String[] superInfo = super.getAdditionalFileStringInfo(pop);
return ToolBox.appendArrays(new String[]{"Pareto metric on the current population (per generation)",
"Pareto metric on the collected pareto front"}, superInfo);
}
public double calculateMetric(Population pop) {
@Override
public String getStringRepresentationForProblem(InterfaceOptimizer opt) {
// TODO Auto-generated method stub
return null;
}
public double calculateMetric(Population pop) {
if (pop==null) return Double.NaN;
return this.m_Metric.calculateMetricOn(pop, this);
}

View File

@ -30,6 +30,7 @@ import eva2.server.go.operators.postprocess.SolutionHistogram;
import eva2.server.go.operators.terminators.CombinedTerminator;
import eva2.server.go.operators.terminators.EvaluationTerminator;
import eva2.server.go.operators.terminators.PhenotypeConvergenceTerminator;
import eva2.server.go.operators.terminators.PopulationMeasureTerminator.ChangeTypeEnum;
import eva2.server.go.populations.Population;
import eva2.server.go.strategies.InterfaceOptimizer;
@ -483,7 +484,7 @@ implements InterfaceOptimizationProblem /*, InterfaceParamControllable*/, Serial
Population pop = new Population(1);
pop.add(orig);
InterfaceTerminator term = new EvaluationTerminator(maxEvaluations);
if (epsilonFitConv > 0) term = new CombinedTerminator(new PhenotypeConvergenceTerminator(epsilonFitConv, 100*dim, true, true), term, false);
if (epsilonFitConv > 0) term = new CombinedTerminator(new PhenotypeConvergenceTerminator(epsilonFitConv, 100*dim, true, ChangeTypeEnum.absoluteChange, true), term, false);
int evalsPerf = PostProcess.processSingleCandidatesNMCMA(PostProcessMethod.nelderMead, pop, term, initRelPerturb, prob);
overallDist = metric.distance(indy, pop.getBestEAIndividual());
//System.out.println(System.currentTimeMillis() + " in " + evalsPerf + " evals moved by "+ overallDist);

View File

@ -396,7 +396,7 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
tmpIndy.SetDoubleGenotype(pos);
((AbstractEAIndividual)tmpIndy).SetFitness(prob.eval(pos));
pop.add(tmpIndy);
FitnessConvergenceTerminator convTerm = new FitnessConvergenceTerminator(1e-25, 10, false, true);
FitnessConvergenceTerminator convTerm = new FitnessConvergenceTerminator(1e-25, 10, false, true, true);
int calls = PostProcess.processSingleCandidatesNMCMA(PostProcessMethod.nelderMead, pop, convTerm, 0.001, prob);
return ((InterfaceDataTypeDouble)pop.getBestEAIndividual()).getDoubleData();
}

View File

@ -156,8 +156,7 @@ public class EvolutionStrategyIPOP extends EvolutionStrategies implements Interf
bestList = new LinkedList<AbstractEAIndividual>();
best = getPopulation().getBestEAIndividual();
dim = AbstractEAIndividual.getDoublePositionShallow(getPopulation().getEAIndividual(0)).length;
fitConvTerm = new FitnessConvergenceTerminator(stagThreshold, (isStagnationTimeUserDef()) ? stagTimeArbitrary : calcDefaultStagnationTime(), false, true); // gen. based, absolute
fitConvTerm = new FitnessConvergenceTerminator(stagThreshold, (isStagnationTimeUserDef()) ? stagTimeArbitrary : calcDefaultStagnationTime(), false, true, true); // gen. based, absolute
getPopulation().addPopulationChangedEventListener(this);
getPopulation().setNotifyEvalInterval(initialLambda);
}

View File

@ -126,7 +126,7 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
// hole die n-1 besten individuen der fitness dimension fitIndex
subpop.setSortingFitnessCriterion(fitIndex);
Population bestpop = subpop.getBestNIndividuals(subpop.size()-1);
Population bestpop = subpop.getBestNIndividuals(subpop.size()-1, fitIndex);
// und das schlechteste
AbstractEAIndividual worst = subpop.getWorstEAIndividual(fitIndex);
AbstractEAIndividual best=subpop.getBestEAIndividual(fitIndex);