Merging mk branch revs. 587:589 (tool tips for statistics data fields)

This commit is contained in:
Marcel Kronfeld 2010-08-06 11:17:56 +00:00
parent 050af6e8e0
commit 85732ec88d
10 changed files with 147 additions and 24 deletions

View File

@ -67,6 +67,16 @@ public abstract class AbstractListSelectionEditor extends JPanel implements Prop
*/
protected abstract String getElementName(int i);
/**
* Get the tool tip of an element or null if none is available.
*
* @param i
* @return
*/
protected String getElementToolTip(int i) {
return null;
}
/**
* Get the selection state of an element.
*
@ -85,6 +95,7 @@ public abstract class AbstractListSelectionEditor extends JPanel implements Prop
this.m_BlackCheck = new JCheckBox[getElementCount()];
for (int i = 0; i < getElementCount(); i++) {
this.m_BlackCheck[i] = new JCheckBox(getElementName(i), isElementSelected(i));
this.m_BlackCheck[i].setToolTipText(getElementToolTip(i));
this.m_BlackCheck[i].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
if (actionOnSelect()) m_Support.firePropertyChange("AbstractListSelectionEditor", null, this);

View File

@ -6,7 +6,7 @@ public class StringSelectionEditor extends AbstractListSelectionEditor {
StringSelection strs;
public StringSelectionEditor() {
strs = new StringSelection(new String[]{});
strs = new StringSelection(new String[]{}, null);
}
@Override
@ -27,6 +27,11 @@ public class StringSelectionEditor extends AbstractListSelectionEditor {
return strs.getElement(i);
}
@Override
protected String getElementToolTip(int i) {
return strs.getElementInfo(i);
}
@Override
public Object getValue() {
return strs;

View File

@ -32,7 +32,6 @@ import eva2.server.go.operators.terminators.EvaluationTerminator;
import eva2.server.go.operators.terminators.PhenotypeConvergenceTerminator;
import eva2.server.go.populations.Population;
import eva2.server.go.strategies.InterfaceOptimizer;
import eva2.tools.math.Mathematics;
/**
* Created by IntelliJ IDEA.
@ -244,6 +243,18 @@ implements InterfaceOptimizationProblem /*, InterfaceParamControllable*/, Serial
else return new String[]{"Solution"};
}
/** This method returns the header for the additional data that is to be written into a file
* @param pop The population that is to be refined.
* @return String
*/
public String[] getAdditionalFileStringInfo(PopulationInterface pop) {
if (this instanceof InterfaceInterestingHistogram)
return new String[]{"Representation of the current best individual",
"Fitness histogram of the current population",
"Fitness threshold based score of the current population"};
else return new String[]{"Representation of the current best individual"};
}
/** This method returns the additional data that is to be written into a file
* @param pop The population that is to be refined.
* @return String
@ -251,8 +262,16 @@ implements InterfaceOptimizationProblem /*, InterfaceParamControllable*/, Serial
public Object[] getAdditionalFileStringValue(PopulationInterface pop) {
String solStr = AbstractEAIndividual.getDefaultDataString(pop.getBestIndividual());
if (this instanceof InterfaceInterestingHistogram) {
int fitCrit=0;
SolutionHistogram hist = ((InterfaceInterestingHistogram)this).getHistogram();
Population sols = PostProcess.clusterBestUpdateHistogram((Population)pop, this, hist, 0, getDefaultAccuracy());
if (pop.getBestFitness()[fitCrit] < hist.getUpperBound()) {
Population maybeFiltered = (Population)pop;
if (pop.size()>100) { // for efficiency reasons...
maybeFiltered = maybeFiltered.filterByFitness(hist.getUpperBound(), fitCrit);
// System.out.println("Reduced " + pop.size() + " to " + maybeFiltered.size());
}
Population sols = PostProcess.clusterBestUpdateHistogram((Population)maybeFiltered, this, hist, fitCrit, getDefaultAccuracy());
}
return new Object[]{solStr, hist, hist.getScore()};
} else return new Object[]{solStr};
}
@ -341,13 +360,15 @@ implements InterfaceOptimizationProblem /*, InterfaceParamControllable*/, Serial
* @param epsilonPhenoSpace maximal allowed improvement of an individual before considered premature (given as distance in the search space)
* @param epsilonFitConv if positive: additional absolute convergence criterion (fitness space) as termination criterion of the local search
* @param clusterSigma minimum cluster distance
* @param maxEvalsPerIndy
* @param maxEvalsPerIndy maximum number of evaluations or -1 to take the maximum
* @see #isPotentialOptimumNMS(AbstractEAIndividual, double, double, int)
* @return
*/
public static Population extractPotentialOptima(AbstractOptimizationProblem prob, Population pop, double epsilonPhenoSpace, double epsilonFitConv, double clusterSigma, int maxEvalsPerIndy) {
public static Population extractPotentialOptima(AbstractOptimizationProblem prob, Population pop,
double epsilonPhenoSpace, double epsilonFitConv, double clusterSigma, int maxEvalsPerIndy) {
Population potOptima = new Population();
for (int i = 0; i < pop.size(); ++i){
//System.out.println("Refining " + i + " of " + pop.size());
AbstractEAIndividual indy = pop.getEAIndividual(i);
// System.out.println("bef: " + indy.toString());
boolean isConverged = AbstractOptimizationProblem.isPotentialOptimumNMS(prob, indy, epsilonPhenoSpace, epsilonFitConv, maxEvalsPerIndy);
@ -429,7 +450,8 @@ implements InterfaceOptimizationProblem /*, InterfaceParamControllable*/, Serial
* distance from the original individual in phenotype space. The maxEvaluations parameter gives the maximum evaluations
* for the local search. Using the epsilonFitConv parameter one may define a convergence criterion as PhenotypeConvergenceTerminator
* which is combined (using OR) with the evaluation counter.
* If maxEvaluations is smaller than zero, 100*dim is used. Be aware that this may cost quite some runtime depending on the target
* If maxEvaluations is smaller than zero, a maximum of 500*dim evaluations is employed.
* Be aware that this may cost quite some runtime depending on the target
* function.
* A double value for the distance by which it was moved is added to the individual using the key PostProcess.movedDistanceKey.
*
@ -452,7 +474,7 @@ implements InterfaceOptimizationProblem /*, InterfaceParamControllable*/, Serial
// initPerturb = epsilonPhenoSpace/(2*(Mathematics.getAvgRange(((InterfaceDataTypeDouble)orig).getDoubleRange())));
initRelPerturb = epsilonPhenoSpace*0.5;
dim=((InterfaceDataTypeDouble)orig).getDoubleRange().length;
if (maxEvaluations<0) maxEvaluations = 100*AbstractEAIndividual.getDoublePositionShallow(prob.m_Template).length; // scales the effort with the number of problem dimensions
if (maxEvaluations<0) maxEvaluations = 500*AbstractEAIndividual.getDoublePositionShallow(prob.m_Template).length; // scales the effort with the number of problem dimensions
} else {
System.err.println("Cannot initialize NMS on non-double valued individuals!");
return false;
@ -461,9 +483,10 @@ 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, 10*dim, true, true), term, false);
if (epsilonFitConv > 0) term = new CombinedTerminator(new PhenotypeConvergenceTerminator(epsilonFitConv, 100*dim, true, 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);
// System.out.println("aft: " + pop.getBestEAIndividual().toString() + ", evals performed: " + evalsPerf + ", opt moved by " + overallDist);
// System.out.println("terminated because: " + term.lastTerminationMessage());
orig.putData(PostProcess.movedDistanceKey, overallDist);
@ -471,6 +494,14 @@ implements InterfaceOptimizationProblem /*, InterfaceParamControllable*/, Serial
// if (overallDist==0) {
// PostProcess.processSingleCandidatesNMCMA(PostProcessMethod.nelderMead, pop, term, initPerturb, this);
// }
// System.out.println("Checked "+ indy.getStringRepresentation());
// String msg = "----discarding ";
// if (overallDist <= epsilonPhenoSpace) msg= "++++keeping ";
// System.out.println(msg + BeanInspector.toString(indy.getDoublePosition()));
// System.out.println("which moved to " + BeanInspector.toString(pop.getBestEAIndividual().getDoublePosition()));
// System.out.println(" by " + overallDist + " > " + epsilonPhenoSpace);
return (overallDist < epsilonPhenoSpace);
}

View File

@ -255,7 +255,8 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
// rotation = new Matrix(dim, dim);
// rotation = Mathematics.getRotationMatrix(vec).transpose();
rotation = Mathematics.getRotationMatrix((rotAngle*Math.PI/180.), dim).transpose();
// System.out.println(BeanInspector.toString(eval(vec.getColumnPackedCopy())));
//double[] t= new double[dim]; Arrays.fill(t, 1.);
//System.out.println(BeanInspector.toString(rotation.times(t)));
return rotation;
}
@ -354,7 +355,9 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
}
public double functionValue(double[] point) {
return eval(project2DPoint(point))[0];
double[] x=project2DPoint(point);
double v = eval(x)[0];
return v;
}
/**
@ -498,6 +501,16 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
else return superHeader;
}
@Override
public String[] getAdditionalFileStringInfo(PopulationInterface pop) {
String[] superInfo = super.getAdditionalFileStringInfo(pop);
if (isWithConstraints())
return ToolBox.appendArrays(superInfo, new String[]{"Raw fitness (unpenalized) of the current best individual",
"The number of constraints violated by the current best individual",
"The sum of constraint violations of the current best individual"});
else return superInfo;
}
@Override
public Object[] getAdditionalFileStringValue(PopulationInterface pop) {
Object[] superVal = super.getAdditionalFileStringValue(pop);

View File

@ -19,6 +19,14 @@ public interface InterfaceAdditionalPopulationInformer {
*/
public String[] getAdditionalFileStringHeader(PopulationInterface pop);
/**
* Optionally return informative descriptions of the data fields.
*
* @param pop
* @return
*/
public String[] getAdditionalFileStringInfo(PopulationInterface pop);
/**
* This method returns additional statistical data.
* @param pop The population that is to be refined.

View File

@ -1143,7 +1143,23 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis
}
public String[] getAdditionalFileStringHeader(PopulationInterface pop) {
return new String[]{"Undiff.","#Act.spec.","Avg.Spec.Meas.","#Archived."};
return new String[]{"numUndiff","numActSpec","avgSpecMeas","numArchived",
"archivedMedCorr", "archivedMeanDist"
// , "numCollisions", "clustSig"
};
}
public String[] getAdditionalFileStringInfo(PopulationInterface pop) { // TODO use these as Tool Tip Texts???
return new String[] {
"The number of exploring individuals in the main population",
"The number of active species (sub-populations)",
"The average of the mean distance of individuals within a species",
"The number of stored potential local optima",
"The median correlation of archived solutions",
"The mean distance of archived solutions",
// "The number of collisions events that happened so far",
// "The clustering distance"
};
}
public Object[] getAdditionalFileStringValue(PopulationInterface pop) {
@ -1152,7 +1168,12 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis
m_Undifferentiated.size(),
m_Species.size(),
getAvgSpeciesMeasures()[0],
m_Archive.size()};
m_Archive.size(),
m_Archive.getCorrelations()[3],
m_Archive.getPopulationMeasures()[0],
// collisions,
// getClusterDiffDist()
};
// return m_Undifferentiated.size() + " \t " + m_Species.size() + " \t " + BeanInspector.toString(getAvgSpeciesMeasures()[0]) + " \t " + (m_Archive.size());
}

View File

@ -419,7 +419,11 @@ public class ClusteringHillClimbing implements InterfacePopulationChangedEventLi
}
public String[] getAdditionalFileStringHeader(PopulationInterface pop) {
return new String[]{"#Indies"};
return new String[]{"numIndies"};
}
public String[] getAdditionalFileStringInfo(PopulationInterface pop) {
return new String[]{"The current population size"};
}
public Object[] getAdditionalFileStringValue(PopulationInterface pop) {

View File

@ -2060,10 +2060,14 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
// public void setDoLocalSearch(boolean doLocalSearch) {
// this.doLocalSearch = doLocalSearch;
// }
public String[] getAdditionalFileStringHeader(PopulationInterface pop) {
if (emaPeriods > 0) return new String[]{"MeanCurSpeed","MeanEMASpeed"};
else return new String[]{"MeanCurSpeed"};
if (emaPeriods > 0) return new String[]{"meanEMASpeed", "meanCurSpeed"};
else return new String[]{"meanCurSpeed"};
}
public String[] getAdditionalFileStringInfo(PopulationInterface pop) {
if (emaPeriods > 0) return new String[]{"Exponential moving average of the (range-relative) speed of all particles", "The mean (range-relative) current speed of all particles"};
else return new String[]{"The mean (range-relative) current speed of all particles"};
}
public Object[] getAdditionalFileStringValue(PopulationInterface pop) {

View File

@ -11,7 +11,26 @@ import eva2.tools.StringSelection;
*/
public enum GraphSelectionEnum {
// DONT change this order, or the relation to AbstractStatistics will be lost
currentBest, meanFit, currentWorst, runBest, currentBestFeasible, runBestFeasible, avgPopDistance, maxPopDistance;
currentBest, meanFit, currentWorst, runBest, currentBestFeasible, runBestFeasible,
avgPopDistance, maxPopDistance;
private static String[] toolTips = {
"The current best fitness within the population",
"The mean fitness within the population",
"The current worst fitness within the population",
"The best fitness up to the current generation",
"The best feasible fitness within the population",
"The best feasible fitness up to the current generation",
"The average phenotypic distance of individuals in the population",
"The maximum phenotypic distance of individuals in the population"
};
public static String[] getInfoStrings() {
if (GraphSelectionEnum.values().length != toolTips.length) {
System.err.println("Error, mismatching length of info strings in GraphSelectionEnum");
return null;
} else return toolTips;
}
// public static boolean doPlotCurrentBest(StringSelection sel) {
// return sel.isSelected(GraphSelectionEnum.currentBest.ordinal());

View File

@ -52,7 +52,7 @@ public class StatsParameter implements InterfaceStatisticsParameter, InterfaceNo
private boolean showAdditionalProblemInfo = false;
private double m_ConvergenceRateThreshold=0.001;
private StringSelection graphSel = new StringSelection(GraphSelectionEnum.currentBest);
private StringSelection graphSel = new StringSelection(GraphSelectionEnum.currentBest, GraphSelectionEnum.getInfoStrings());
/**
*
@ -381,14 +381,21 @@ public class StatsParameter implements InterfaceStatisticsParameter, InterfaceNo
public void setInformers(
List<InterfaceAdditionalPopulationInformer> informers) {
ArrayList<String> headerFields = new ArrayList<String>();
ArrayList<String> infoFields = new ArrayList<String>();
// parse list of header elements, show additional Strings according to names.
for (InterfaceAdditionalPopulationInformer inf : informers) {
headerFields.addAll(Arrays.asList(inf.getAdditionalFileStringHeader(null)));
if (infoFields.size()<headerFields.size()) { // add info strings for tool tips - fill up with null if none have been returned.
String[] infos = inf.getAdditionalFileStringInfo(null);
if (infos!=null) infoFields.addAll(Arrays.asList(infos));
while (infoFields.size()<headerFields.size()) infoFields.add(null);
}
// header += inf.getAdditionalFileStringHeader(null); // lets hope this works with a null
}
// create additional fields to be selectable by the user, defined by the informer headers
// StringSelection ss = new StringSelection(GraphSelectionEnum.getAndAppendArray(headerFields.toArray(new String[headerFields.size()])));
StringSelection ss = new StringSelection(GraphSelectionEnum.currentBest, headerFields);
StringSelection ss = new StringSelection(GraphSelectionEnum.currentBest, GraphSelectionEnum.getInfoStrings(),
headerFields, infoFields.toArray(new String[infoFields.size()]));
ss.takeOverSelection(graphSel);
// System.out.println("In " + this + ": setting new informers: " + BeanInspector.toString(ss.getStrings()));
// This works!