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:
parent
e12ab22e31
commit
aa3c903645
@ -21,7 +21,6 @@ import java.util.Comparator;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class AbstractEAIndividualComparator implements Comparator<Object>, Serializable {
|
public class AbstractEAIndividualComparator implements Comparator<Object>, Serializable {
|
||||||
|
|
||||||
// flag whether a data field should be used.
|
// flag whether a data field should be used.
|
||||||
private String indyDataKey = "";
|
private String indyDataKey = "";
|
||||||
private int fitCriterion = -1;
|
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.
|
* For comparison, only the given fitness criterion is used if it is >= 0.
|
||||||
*
|
*
|
||||||
* @param fitnessCriterion
|
* @param fitnessCriterion
|
||||||
@ -60,10 +59,34 @@ public class AbstractEAIndividualComparator implements Comparator<Object>, Seria
|
|||||||
this("", fitnessCriterion, true);
|
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) {
|
public AbstractEAIndividualComparator(int fitIndex, boolean preferFeasible) {
|
||||||
this("", fitIndex, 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.
|
* Generic constructor.
|
||||||
*
|
*
|
||||||
|
@ -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());
|
||||||
|
// }
|
||||||
|
}
|
@ -2,6 +2,7 @@ package eva2.server.go.operators.cluster;
|
|||||||
|
|
||||||
import eva2.gui.BeanInspector;
|
import eva2.gui.BeanInspector;
|
||||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
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.InterfaceDistanceMetric;
|
||||||
import eva2.server.go.operators.distancemetric.PhenotypeMetric;
|
import eva2.server.go.operators.distancemetric.PhenotypeMetric;
|
||||||
import eva2.server.go.populations.Population;
|
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) {
|
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 peaks = performDynPeakIdent(metric, sorted, numNiches, nicheRadius);
|
||||||
Population[] clusters = new Population[peaks.size()+1];
|
Population[] clusters = new Population[peaks.size()+1];
|
||||||
for (int i=0; i<clusters.length; i++) clusters[i]=new Population();
|
for (int i=0; i<clusters.length; i++) clusters[i]=new Population();
|
||||||
|
@ -192,6 +192,11 @@ public class PhenotypeMetric implements InterfaceDistanceMetric, java.io.Seriali
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the 2 norm of a given vector.
|
||||||
|
* @param v1
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public static double norm(double[] v1) {
|
public static double norm(double[] v1) {
|
||||||
double result = 0;
|
double result = 0;
|
||||||
for (int i = 0; i < v1.length; i++) {
|
for (int i = 0; i < v1.length; i++) {
|
||||||
|
@ -8,6 +8,7 @@ import eva2.gui.GenericObjectEditor;
|
|||||||
import eva2.server.go.InterfacePopulationChangedEventListener;
|
import eva2.server.go.InterfacePopulationChangedEventListener;
|
||||||
import eva2.server.go.enums.ESMutationInitialSigma;
|
import eva2.server.go.enums.ESMutationInitialSigma;
|
||||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||||
|
import eva2.server.go.individuals.AbstractEAIndividualComparator;
|
||||||
import eva2.server.go.individuals.InterfaceDataTypeDouble;
|
import eva2.server.go.individuals.InterfaceDataTypeDouble;
|
||||||
import eva2.server.go.operators.distancemetric.EuclideanMetric;
|
import eva2.server.go.operators.distancemetric.EuclideanMetric;
|
||||||
import eva2.server.go.populations.Population;
|
import eva2.server.go.populations.Population;
|
||||||
@ -306,7 +307,7 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
|
|||||||
* @param selectedP
|
* @param selectedP
|
||||||
*/
|
*/
|
||||||
public void adaptAfterSelection(Population oldGen, Population selectedP) {
|
public void adaptAfterSelection(Population oldGen, Population selectedP) {
|
||||||
Population selectedSorted = selectedP.getSortedBestFirst();
|
Population selectedSorted = selectedP.getSortedBestFirst(new AbstractEAIndividualComparator(-1));
|
||||||
|
|
||||||
int mu,lambda;
|
int mu,lambda;
|
||||||
mu = selectedP.size();
|
mu = selectedP.size();
|
||||||
|
@ -215,6 +215,6 @@ public class MetricS implements InterfaceParetoFrontMetric, java.io.Serializable
|
|||||||
* @return description
|
* @return description
|
||||||
*/
|
*/
|
||||||
public static String globalInfo() {
|
public static String globalInfo() {
|
||||||
return "Calculating the hybervolume UNDER the given Pareto-front.";
|
return "Calculating the hypervolume UNDER the given Pareto-front.";
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -203,7 +203,7 @@ public class PostProcess {
|
|||||||
int n = Math.max(1, (int)(returnQuota*clusters[j].size())); // return at least one per cluster!
|
int n = Math.max(1, (int)(returnQuota*clusters[j].size())); // return at least one per cluster!
|
||||||
switch (takeOverMode) {
|
switch (takeOverMode) {
|
||||||
case BEST_ONLY: // another easy case
|
case BEST_ONLY: // another easy case
|
||||||
result.addAll((Collection<AbstractEAIndividual>)(clusters[j].getBestNIndividuals(n)));
|
result.addAll((Collection<AbstractEAIndividual>)(clusters[j].getBestNIndividuals(n, -1)));
|
||||||
break;
|
break;
|
||||||
case BEST_RAND:
|
case BEST_RAND:
|
||||||
Population exclude = new Population();
|
Population exclude = new Population();
|
||||||
@ -1075,7 +1075,7 @@ public class PostProcess {
|
|||||||
//////////// multimodal data output
|
//////////// multimodal data output
|
||||||
evaluateMultiModal(outputPop, problem, listener);
|
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() + ")") ));
|
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
|
//////////// output some individual data
|
||||||
if (listener != null) for (int i=0; i<nBestPop.size(); i++) {
|
if (listener != null) for (int i=0; i<nBestPop.size(); i++) {
|
||||||
|
@ -1,235 +1,51 @@
|
|||||||
package eva2.server.go.operators.terminators;
|
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 java.io.Serializable;
|
||||||
|
|
||||||
import eva2.gui.BeanInspector;
|
|
||||||
import eva2.server.go.InterfaceTerminator;
|
import eva2.server.go.InterfaceTerminator;
|
||||||
import eva2.server.go.PopulationInterface;
|
import eva2.server.go.PopulationInterface;
|
||||||
import eva2.server.go.operators.distancemetric.EuclideanMetric;
|
import eva2.tools.math.Mathematics;
|
||||||
import eva2.server.go.operators.distancemetric.PhenotypeMetric;
|
|
||||||
import eva2.server.go.populations.InterfaceSolutionSet;
|
|
||||||
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
|
||||||
import eva2.tools.SelectedTag;
|
|
||||||
|
|
||||||
|
|
||||||
/*==========================================================================*
|
|
||||||
* 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,
|
public class FitnessConvergenceTerminator extends PopulationMeasureTerminator
|
||||||
Serializable {
|
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 FitnessConvergenceTerminator() {
|
public FitnessConvergenceTerminator() {
|
||||||
pMetric = new PhenotypeMetric();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FitnessConvergenceTerminator(double thresh, int stagnPeriod, boolean bFitCallBased, boolean bAbsolute) {
|
public FitnessConvergenceTerminator(double thresh, int stagnPeriod, boolean bFitCallBased, boolean bAbsolute, boolean bImprovement) {
|
||||||
pMetric = new PhenotypeMetric();
|
super(thresh, stagnPeriod, bFitCallBased, ChangeTypeEnum.absoluteChange, bImprovement);
|
||||||
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(FitnessConvergenceTerminator other) {
|
public FitnessConvergenceTerminator(FitnessConvergenceTerminator other) {
|
||||||
pMetric = new PhenotypeMetric();
|
super(other);
|
||||||
convThresh = other.convThresh;
|
|
||||||
this.m_stagTime = other.m_stagTime;
|
|
||||||
stagnationMeasure.setSelectedTag(other.getStagnationMeasure().getSelectedTagID());
|
|
||||||
convergenceCondition.setSelectedTag(other.getConvergenceCondition().getSelectedTagID());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public static String globalInfo() {
|
public static String globalInfo() {
|
||||||
return "Stop if a fitness convergence criterion has been met.";
|
return "Stop if a fitness convergence criterion has been met.";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(InterfaceOptimizationProblem prob) {
|
@Override
|
||||||
if (pMetric == null) pMetric = new PhenotypeMetric();
|
protected double calcInitialMeasure(PopulationInterface pop) {
|
||||||
firstTime = true;
|
return Mathematics.norm(pop.getBestFitness());
|
||||||
msg = "Not terminated.";
|
|
||||||
tagString = "Fitness converged";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTerminated(InterfaceSolutionSet solSet) {
|
@Override
|
||||||
return isTerminated(solSet.getCurrentPopulation());
|
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) {
|
@Override
|
||||||
if (!firstTime && isStillConverged(Pop)) {
|
protected String getMeasureName() {
|
||||||
if (stagnationTimeHasPassed(Pop)) {
|
return "Fitness";
|
||||||
// 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";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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";
|
||||||
|
}
|
||||||
|
}
|
@ -1,53 +1,64 @@
|
|||||||
package eva2.server.go.operators.terminators;
|
package eva2.server.go.operators.terminators;
|
||||||
|
|
||||||
import eva2.gui.BeanInspector;
|
|
||||||
import eva2.server.go.IndividualInterface;
|
|
||||||
import eva2.server.go.InterfaceTerminator;
|
import eva2.server.go.InterfaceTerminator;
|
||||||
import eva2.server.go.PopulationInterface;
|
import eva2.server.go.PopulationInterface;
|
||||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||||
import eva2.server.go.operators.distancemetric.PhenotypeMetric;
|
import eva2.server.go.operators.distancemetric.PhenotypeMetric;
|
||||||
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
||||||
|
|
||||||
public class PhenotypeConvergenceTerminator extends FitnessConvergenceTerminator implements InterfaceTerminator {
|
public class PhenotypeConvergenceTerminator extends PopulationMeasureTerminator implements InterfaceTerminator {
|
||||||
AbstractEAIndividual oldIndy = null;
|
AbstractEAIndividual oldIndy = null;
|
||||||
double oldPhenNorm = 0;
|
private PhenotypeMetric pMetric = null;
|
||||||
|
// double oldPhenNorm = 0;
|
||||||
|
|
||||||
public PhenotypeConvergenceTerminator() {
|
public PhenotypeConvergenceTerminator() {
|
||||||
super();
|
super();
|
||||||
tagString = "Phenotype converged";
|
pMetric = new PhenotypeMetric();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhenotypeConvergenceTerminator(double thresh, int stagnTime, boolean bFitCallBased, boolean bAbsolute) {
|
public PhenotypeConvergenceTerminator(double thresh, int stagnTime, boolean bFitCallBased, ChangeTypeEnum changeType, boolean bImprovement) {
|
||||||
super(thresh, stagnTime, bFitCallBased, bAbsolute);
|
super(thresh, stagnTime, bFitCallBased, changeType, bImprovement);
|
||||||
|
pMetric = new PhenotypeMetric();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PhenotypeConvergenceTerminator(PhenotypeConvergenceTerminator o) {
|
||||||
|
super(o);
|
||||||
|
oldIndy = (AbstractEAIndividual)o.oldIndy.clone();
|
||||||
|
pMetric = (PhenotypeMetric)o.pMetric.clone();
|
||||||
|
// oldPhenNorm = o.oldPhenNorm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(InterfaceOptimizationProblem prob) {
|
public void init(InterfaceOptimizationProblem prob) {
|
||||||
super.init(prob);
|
super.init(prob);
|
||||||
tagString = "Phenotype converged";
|
// oldPhenNorm = 0;
|
||||||
|
oldIndy = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Return true if |oldPhen - curPhen| < |oldPhen| * thresh (relative case)
|
protected double calcInitialMeasure(PopulationInterface pop) {
|
||||||
* and if |oldFit - curFit| < thresh (absolute case).
|
oldIndy = (AbstractEAIndividual)((AbstractEAIndividual)pop.getBestIndividual()).clone();
|
||||||
*
|
// oldPhenNorm = PhenotypeMetric.norm(oldIndy);
|
||||||
* @param curFit
|
return Double.MAX_VALUE;
|
||||||
* @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 calcPopulationMeasure(PopulationInterface pop) {
|
||||||
|
return pMetric.distance(oldIndy, (AbstractEAIndividual)pop.getBestIndividual());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void saveState(PopulationInterface Pop) {
|
protected void saveState(PopulationInterface Pop) {
|
||||||
super.saveState(Pop);
|
super.saveState(Pop);
|
||||||
oldIndy = (AbstractEAIndividual)((AbstractEAIndividual)Pop.getBestIndividual()).clone();
|
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.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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).";
|
||||||
|
}
|
||||||
|
}
|
@ -70,7 +70,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
|||||||
private int lastQModCount = -1;
|
private int lastQModCount = -1;
|
||||||
// a sorted queue (for efficiency)
|
// a sorted queue (for efficiency)
|
||||||
transient private ArrayList<AbstractEAIndividual> sortedArr = null;
|
transient private ArrayList<AbstractEAIndividual> sortedArr = null;
|
||||||
private int lastFitCrit = -1;
|
private Comparator<Object> lastSortingComparator = null;
|
||||||
// private AbstractEAIndividualComparator historyComparator = null;
|
// private AbstractEAIndividualComparator historyComparator = null;
|
||||||
|
|
||||||
public static final String funCallIntervalReached = "FunCallIntervalReached";
|
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
|
* 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.
|
* population. A given comparator is employed for individual comparisons.
|
||||||
* 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).
|
|
||||||
*
|
*
|
||||||
* @param bBest if true, smallest fitness (regarded best) index is returned, else the highest one
|
* @param bBest if true, the best (first) index is returned, else the worst (last) one
|
||||||
* @param indicate whether constraints should be regarded
|
* @param comparator indicate whether constraints should be regarded
|
||||||
* @return The index of the best (worst) individual.
|
* @return The index of the best (worst) individual.
|
||||||
*/
|
*/
|
||||||
public int getIndexOfBestOrWorstIndividual(boolean bBest, AbstractEAIndividualComparator comparator) {
|
public int getIndexOfBestOrWorstIndividual(boolean bBest, Comparator<Object> comparator) {
|
||||||
ArrayList<AbstractEAIndividual> sorted = getSorted(comparator);
|
ArrayList<?> sorted = sortBy(comparator);
|
||||||
if (bBest) return indexOf(sorted.get(0));
|
if (bBest) return indexOf(sorted.get(0));
|
||||||
else return indexOfInstance(sorted.get(sorted.size()-1));
|
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) {
|
public int getIndexOfBestOrWorstIndy(boolean bBest, boolean checkConstraints, int fitIndex) {
|
||||||
return getIndexOfBestOrWorstIndividual(bBest, new AbstractEAIndividualComparator(fitIndex, checkConstraints));
|
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
|
* @return The m best individuals, where m <= n
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public Population getBestNIndividuals(int n) {
|
public Population getBestNIndividuals(int n, int fitIndex) {
|
||||||
return getSortedNIndividuals(n, true);
|
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
|
* This method returns a clone of the population instance with sorted individuals, where
|
||||||
* the sorting criterion is delivered by an AbstractEAIndividualComparator.
|
* the sorting criterion is delivered by a Comparator.
|
||||||
* @see #getSortedNIndividuals(int, boolean, Population)
|
* @see #getSortedNIndividuals(int, boolean, Population, Comparator)
|
||||||
*
|
*
|
||||||
* @return a clone of the population instance with sorted individuals, best fitness first
|
* @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();
|
Population result = this.cloneWithoutInds();
|
||||||
getSortedNIndividuals(size(), true, result);
|
getSortedNIndividuals(size(), true, result, comp);
|
||||||
result.synchSize();
|
result.synchSize();
|
||||||
return result;
|
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
|
* @return The m sorted best or worst individuals, where m <= n
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public Population getSortedNIndividuals(int n, boolean bBestOrWorst) {
|
// public Population getSortedNIndividuals(int n, boolean bBestOrWorst) {
|
||||||
Population result = new Population((n > 0) ? n : this.size());
|
// Population result = new Population((n > 0) ? n : this.size());
|
||||||
getSortedNIndividuals(n, bBestOrWorst, result);
|
// getSortedNIndividuals(n, bBestOrWorst, result);
|
||||||
return result;
|
// return result;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the n current best individuals from the population, where
|
* 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.
|
* There are less than n individuals returned if the population is smaller than n.
|
||||||
* This does not check constraints!
|
* This does not check constraints!
|
||||||
*
|
*
|
||||||
* @param n number of individuals to look out for
|
* @param n number of individuals to look out for
|
||||||
* @param bBestOrWorst if true, the best n are returned, else the worst n individuals
|
* @param bBestOrWorst if true, the best n are returned, else the worst n individuals
|
||||||
* @param res sorted result population, will be cleared
|
* @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
|
* @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())) {
|
if ((n < 0) || (n>super.size())) {
|
||||||
// this may happen, treat it gracefully
|
// this may happen, treat it gracefully
|
||||||
//System.err.println("invalid request to getSortedNIndividuals: n="+n + ", size is " + super.size());
|
//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;
|
int skip = 0;
|
||||||
if (!bBestOrWorst) skip = super.size()-n;
|
if (!bBestOrWorst) skip = super.size()-n;
|
||||||
|
|
||||||
ArrayList<AbstractEAIndividual> sorted = getSorted(lastFitCrit);
|
// hier getSorted aufrufen
|
||||||
|
ArrayList<AbstractEAIndividual> sorted = getSorted(comp);
|
||||||
res.clear();
|
res.clear();
|
||||||
for (int i = skip; i < skip+n; i++) {
|
for (int i = skip; i < skip+n; i++) {
|
||||||
res.add(sorted.get(i));
|
res.add(sorted.get(i));
|
||||||
@ -1044,6 +1066,18 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
|||||||
res.synchSize();
|
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.
|
* From the given list, remove all but the first n elements.
|
||||||
* @param n
|
* @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
|
* @param fitIndex
|
||||||
*/
|
*/
|
||||||
public void setSortingFitnessCriterion(int 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.
|
* @param comp A comparator by which sorting is performed - it should work on AbstractEAIndividual instances.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public ArrayList<AbstractEAIndividual> getSorted(Comparator<Object> comp) {
|
protected ArrayList<AbstractEAIndividual> sortBy(Comparator<Object> comp) {
|
||||||
if (super.size()==0) return new ArrayList<AbstractEAIndividual>();
|
if (super.size()==0) return new ArrayList<AbstractEAIndividual>();
|
||||||
PriorityQueue<AbstractEAIndividual> sQueue = new PriorityQueue<AbstractEAIndividual>(super.size(), comp);
|
PriorityQueue<AbstractEAIndividual> sQueue = new PriorityQueue<AbstractEAIndividual>(super.size(), comp);
|
||||||
for (int i = 0; i < super.size(); i++) {
|
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.
|
* Return a sorted list of individuals. The order is based on the
|
||||||
* The returned array should not be modified!
|
* 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
|
* @param fitIndex the fitness criterion to be used or -1 for pareto dominance
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected ArrayList<AbstractEAIndividual> getSorted(int fitIndex) {
|
public ArrayList<AbstractEAIndividual> getSorted(Comparator<Object> comp) {
|
||||||
if ((fitIndex != lastFitCrit) || (sortedArr == null) || (super.modCount != lastQModCount)) {
|
// Comparator<Object> comp = new AbstractEAIndividualComparator(fitIndex);
|
||||||
lastFitCrit=fitIndex;
|
// if (!comp.equals(lastSortingComparator)) return sortedArr;
|
||||||
ArrayList<AbstractEAIndividual> sArr = getSorted(new AbstractEAIndividualComparator(fitIndex));
|
if (!comp.equals(lastSortingComparator) || (sortedArr == null) || (super.modCount != lastQModCount)) {
|
||||||
|
// lastFitCrit=fitIndex;lastSortingComparator
|
||||||
|
ArrayList<AbstractEAIndividual> sArr = sortBy(comp);
|
||||||
if (sortedArr==null) sortedArr = sArr;
|
if (sortedArr==null) sortedArr = sArr;
|
||||||
else {
|
else {
|
||||||
sortedArr.clear();
|
sortedArr.clear();
|
||||||
sortedArr.addAll(sArr);
|
sortedArr.addAll(sArr);
|
||||||
}
|
}
|
||||||
|
lastSortingComparator = (Comparator<Object>) Serializer.deepClone(comp);
|
||||||
lastQModCount = super.modCount;
|
lastQModCount = super.modCount;
|
||||||
}
|
}
|
||||||
return sortedArr;
|
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
|
* This method retrieves n random individuals from the population and
|
||||||
* returns them within a new population.
|
* returns them within a new population.
|
||||||
|
@ -3,8 +3,6 @@ package eva2.server.go.problems;
|
|||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
import javax.swing.JFrame;
|
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.InterfaceParetoFrontMetric;
|
||||||
import eva2.server.go.operators.paretofrontmetrics.MetricS;
|
import eva2.server.go.operators.paretofrontmetrics.MetricS;
|
||||||
import eva2.server.go.populations.Population;
|
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.Chart2DDPointIconCircle;
|
||||||
import eva2.tools.chart2d.Chart2DDPointIconText;
|
import eva2.tools.chart2d.Chart2DDPointIconText;
|
||||||
import eva2.tools.chart2d.DPoint;
|
import eva2.tools.chart2d.DPoint;
|
||||||
@ -353,65 +352,6 @@ public abstract class AbstractMultiObjectiveOptimizationProblem extends Abstract
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// /** 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
|
* This method will plot a reference solutions or something like it
|
||||||
* @param plot The plot where you can draw your stuff.
|
* @param plot The plot where you can draw your stuff.
|
||||||
@ -536,25 +476,33 @@ public abstract class AbstractMultiObjectiveOptimizationProblem extends Abstract
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getAdditionalFileStringHeader(PopulationInterface pop) {
|
public String[] getAdditionalFileStringHeader(PopulationInterface pop) {
|
||||||
String[] result = new String[1];
|
String[] superHd = super.getAdditionalFileStringHeader(pop);
|
||||||
if (AbstractMultiObjectiveOptimizationProblem.isPopulationMultiObjective((Population)pop))
|
return ToolBox.appendArrays(new String[]{"paretoMetricCurrent","paretoMetricFront"}, superHd);
|
||||||
result[0] = "SMetric";
|
|
||||||
else
|
|
||||||
result[0] = "BestFitness";
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] getAdditionalFileStringValue(PopulationInterface pop) {
|
public Object[] getAdditionalFileStringValue(PopulationInterface pop) {
|
||||||
Object[] result = new Object[1];
|
Object[] result = new Object[2];
|
||||||
if (AbstractMultiObjectiveOptimizationProblem.isPopulationMultiObjective((Population)pop))
|
result[0] = this.calculateMetric((Population)pop);
|
||||||
result[0] = this.calculateMetric((Population)pop);
|
result[1] = this.calculateMetric(getLocalParetoFront());
|
||||||
else
|
return ToolBox.appendArrays(result, super.getAdditionalFileStringValue(pop));
|
||||||
result[0] = ((Population)pop).getBestEAIndividual().getFitness()[0];
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public double calculateMetric(Population 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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);
|
return this.m_Metric.calculateMetricOn(pop, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ import eva2.server.go.operators.postprocess.SolutionHistogram;
|
|||||||
import eva2.server.go.operators.terminators.CombinedTerminator;
|
import eva2.server.go.operators.terminators.CombinedTerminator;
|
||||||
import eva2.server.go.operators.terminators.EvaluationTerminator;
|
import eva2.server.go.operators.terminators.EvaluationTerminator;
|
||||||
import eva2.server.go.operators.terminators.PhenotypeConvergenceTerminator;
|
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.populations.Population;
|
||||||
import eva2.server.go.strategies.InterfaceOptimizer;
|
import eva2.server.go.strategies.InterfaceOptimizer;
|
||||||
|
|
||||||
@ -483,7 +484,7 @@ implements InterfaceOptimizationProblem /*, InterfaceParamControllable*/, Serial
|
|||||||
Population pop = new Population(1);
|
Population pop = new Population(1);
|
||||||
pop.add(orig);
|
pop.add(orig);
|
||||||
InterfaceTerminator term = new EvaluationTerminator(maxEvaluations);
|
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);
|
int evalsPerf = PostProcess.processSingleCandidatesNMCMA(PostProcessMethod.nelderMead, pop, term, initRelPerturb, prob);
|
||||||
overallDist = metric.distance(indy, pop.getBestEAIndividual());
|
overallDist = metric.distance(indy, pop.getBestEAIndividual());
|
||||||
//System.out.println(System.currentTimeMillis() + " in " + evalsPerf + " evals moved by "+ overallDist);
|
//System.out.println(System.currentTimeMillis() + " in " + evalsPerf + " evals moved by "+ overallDist);
|
||||||
|
@ -396,7 +396,7 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
|
|||||||
tmpIndy.SetDoubleGenotype(pos);
|
tmpIndy.SetDoubleGenotype(pos);
|
||||||
((AbstractEAIndividual)tmpIndy).SetFitness(prob.eval(pos));
|
((AbstractEAIndividual)tmpIndy).SetFitness(prob.eval(pos));
|
||||||
pop.add(tmpIndy);
|
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);
|
int calls = PostProcess.processSingleCandidatesNMCMA(PostProcessMethod.nelderMead, pop, convTerm, 0.001, prob);
|
||||||
return ((InterfaceDataTypeDouble)pop.getBestEAIndividual()).getDoubleData();
|
return ((InterfaceDataTypeDouble)pop.getBestEAIndividual()).getDoubleData();
|
||||||
}
|
}
|
||||||
|
@ -156,8 +156,7 @@ public class EvolutionStrategyIPOP extends EvolutionStrategies implements Interf
|
|||||||
bestList = new LinkedList<AbstractEAIndividual>();
|
bestList = new LinkedList<AbstractEAIndividual>();
|
||||||
best = getPopulation().getBestEAIndividual();
|
best = getPopulation().getBestEAIndividual();
|
||||||
dim = AbstractEAIndividual.getDoublePositionShallow(getPopulation().getEAIndividual(0)).length;
|
dim = AbstractEAIndividual.getDoublePositionShallow(getPopulation().getEAIndividual(0)).length;
|
||||||
|
fitConvTerm = new FitnessConvergenceTerminator(stagThreshold, (isStagnationTimeUserDef()) ? stagTimeArbitrary : calcDefaultStagnationTime(), false, true, true); // gen. based, absolute
|
||||||
fitConvTerm = new FitnessConvergenceTerminator(stagThreshold, (isStagnationTimeUserDef()) ? stagTimeArbitrary : calcDefaultStagnationTime(), false, true); // gen. based, absolute
|
|
||||||
getPopulation().addPopulationChangedEventListener(this);
|
getPopulation().addPopulationChangedEventListener(this);
|
||||||
getPopulation().setNotifyEvalInterval(initialLambda);
|
getPopulation().setNotifyEvalInterval(initialLambda);
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
|||||||
|
|
||||||
// hole die n-1 besten individuen der fitness dimension fitIndex
|
// hole die n-1 besten individuen der fitness dimension fitIndex
|
||||||
subpop.setSortingFitnessCriterion(fitIndex);
|
subpop.setSortingFitnessCriterion(fitIndex);
|
||||||
Population bestpop = subpop.getBestNIndividuals(subpop.size()-1);
|
Population bestpop = subpop.getBestNIndividuals(subpop.size()-1, fitIndex);
|
||||||
// und das schlechteste
|
// und das schlechteste
|
||||||
AbstractEAIndividual worst = subpop.getWorstEAIndividual(fitIndex);
|
AbstractEAIndividual worst = subpop.getWorstEAIndividual(fitIndex);
|
||||||
AbstractEAIndividual best=subpop.getBestEAIndividual(fitIndex);
|
AbstractEAIndividual best=subpop.getBestEAIndividual(fitIndex);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user