Merging MK branch revs. 214,447-448,451,452,456-459.

This commit is contained in:
Marcel Kronfeld 2010-02-24 16:22:16 +00:00
parent edbaf50447
commit 2f33a002e2
69 changed files with 2318 additions and 623 deletions

View File

@ -21,9 +21,11 @@ import eva2.server.go.operators.archiving.InformationRetrievalInserting;
import eva2.server.go.operators.archiving.InterfaceArchiving; import eva2.server.go.operators.archiving.InterfaceArchiving;
import eva2.server.go.operators.archiving.InterfaceInformationRetrieval; import eva2.server.go.operators.archiving.InterfaceInformationRetrieval;
import eva2.server.go.operators.cluster.ClusteringDensityBased; import eva2.server.go.operators.cluster.ClusteringDensityBased;
import eva2.server.go.operators.cluster.InterfaceClustering;
import eva2.server.go.operators.crossover.CrossoverESDefault; import eva2.server.go.operators.crossover.CrossoverESDefault;
import eva2.server.go.operators.crossover.InterfaceCrossover; import eva2.server.go.operators.crossover.InterfaceCrossover;
import eva2.server.go.operators.crossover.NoCrossover; import eva2.server.go.operators.crossover.NoCrossover;
import eva2.server.go.operators.distancemetric.IndividualDataMetric;
import eva2.server.go.operators.mutation.InterfaceMutation; import eva2.server.go.operators.mutation.InterfaceMutation;
import eva2.server.go.operators.mutation.MutateESCovarianceMatrixAdaption; import eva2.server.go.operators.mutation.MutateESCovarianceMatrixAdaption;
import eva2.server.go.operators.mutation.MutateESFixedStepSize; import eva2.server.go.operators.mutation.MutateESFixedStepSize;
@ -50,6 +52,7 @@ import eva2.server.go.strategies.HillClimbing;
import eva2.server.go.strategies.InterfaceOptimizer; import eva2.server.go.strategies.InterfaceOptimizer;
import eva2.server.go.strategies.MonteCarloSearch; import eva2.server.go.strategies.MonteCarloSearch;
import eva2.server.go.strategies.MultiObjectiveEA; import eva2.server.go.strategies.MultiObjectiveEA;
import eva2.server.go.strategies.NelderMeadSimplex;
import eva2.server.go.strategies.ParticleSwarmOptimization; import eva2.server.go.strategies.ParticleSwarmOptimization;
import eva2.server.go.strategies.PopulationBasedIncrementalLearning; import eva2.server.go.strategies.PopulationBasedIncrementalLearning;
import eva2.server.go.strategies.SimulatedAnnealing; import eva2.server.go.strategies.SimulatedAnnealing;
@ -117,6 +120,12 @@ public class OptimizerFactory {
private static OptimizerRunnable lastRunnable = null; private static OptimizerRunnable lastRunnable = null;
private static final int cbnDefaultHaltingWindowLength=new ClusterBasedNichingEA().getHaltingWindow();
private static final double cbnDefaultHaltingWindowEpsilon=new ClusterBasedNichingEA().getEpsilonBound();
private static final double cbnDefaultClusterSigma = 0.1;
private static final int cbnDefaultMinGroupSize = 5;
private static final int cbnDefaultMaxGroupSize = -1;
/** /**
* This method optimizes the given problem using differential evolution. * This method optimizes the given problem using differential evolution.
* *
@ -424,7 +433,7 @@ public class OptimizerFactory {
* @param popsize * @param popsize
* @param phi1 * @param phi1
* @param phi2 * @param phi2
* @param k * @param speedLim
* @param listener * @param listener
* @param topology * @param topology
* @see ParticleSwarmOpimization * @see ParticleSwarmOpimization
@ -433,9 +442,8 @@ public class OptimizerFactory {
*/ */
public static final ParticleSwarmOptimization createParticleSwarmOptimization( public static final ParticleSwarmOptimization createParticleSwarmOptimization(
AbstractOptimizationProblem problem, int popsize, double phi1, AbstractOptimizationProblem problem, int popsize, double phi1,
double phi2, double k, double phi2, double speedLim, PSOTopologyEnum selectedTopology, int topologyRange,
InterfacePopulationChangedEventListener listener, InterfacePopulationChangedEventListener listener) {
PSOTopologyEnum selectedTopology) {
problem.initProblem(); problem.initProblem();
@ -450,9 +458,10 @@ public class OptimizerFactory {
pso.getPopulation().setTargetSize(popsize); pso.getPopulation().setTargetSize(popsize);
pso.setPhi1(phi1); pso.setPhi1(phi1);
pso.setPhi2(phi2); pso.setPhi2(phi2);
pso.setSpeedLimit(k); pso.setSpeedLimit(speedLim);
// pso.getTopology().setSelectedTag(selectedTopology); // pso.getTopology().setSelectedTag(selectedTopology);
pso.setTopology(selectedTopology); pso.setTopology(selectedTopology);
pso.setTopologyRange(topologyRange);
pso.addPopulationChangedEventListener(listener); pso.addPopulationChangedEventListener(listener);
pso.init(); pso.init();
@ -581,13 +590,13 @@ public class OptimizerFactory {
case HILLCL: case HILLCL:
return hillClimbing(problem); return hillClimbing(problem);
case CBN_ES: case CBN_ES:
return cbnES(problem); return standardCbnES(problem);
case CL_HILLCL: case CL_HILLCL:
return stdClusteringHillClimbing(problem); return stdClusteringHillClimbing(problem);
case CMA_ES_IPOP: case CMA_ES_IPOP:
return cmaESIPOP(problem); return cmaESIPOP(problem);
case CBN_GA: case CBN_GA:
return cbnGA(problem); return standardCbnGA(problem);
case PBIL: case PBIL:
return standardPBIL(problem); return standardPBIL(problem);
default: default:
@ -1171,31 +1180,99 @@ public class OptimizerFactory {
return makeParams(new MonteCarloSearch(), 50, problem, randSeed, makeDefaultTerminator()); return makeParams(new MonteCarloSearch(), 50, problem, randSeed, makeDefaultTerminator());
} }
public static final GOParameters cbnES(AbstractOptimizationProblem problem) { /**
* Create a generic Clustering-based Niching EA with given parameters. Uses ClusteringDensityBased as
* a default clustering algorithm.
*
* @param problem
* @param opt
* @param clusterSigma
* @param minClustSize
* @param haltingWindowLength
* @param haltingWindowEpsilon
* @param popSize
* @return
*/
public static final GOParameters createCbn(AbstractOptimizationProblem problem, InterfaceOptimizer opt,
double clusterSigma, int minClustSize, int maxSpecSize, int haltingWindowLength, double haltingWindowEpsilon, int popSize) {
return createCbn(problem, opt, new ClusteringDensityBased(clusterSigma, minClustSize), maxSpecSize,
new ClusteringDensityBased(clusterSigma, minClustSize), haltingWindowLength, haltingWindowEpsilon, popSize);
}
/**
* Create a generic Clustering-based Niching EA with given parameters.
*
* @param problem
* @param opt
* @param clustDifferentiate
* @param clustMerge
* @param haltingWindowLength
* @param haltingWindowEpsilon
* @param popSize
* @return
*/
public static final GOParameters createCbn(AbstractOptimizationProblem problem, InterfaceOptimizer opt,
InterfaceClustering clustDifferentiate, int maxSpecSize, InterfaceClustering clustMerge, int haltingWindowLength,
double haltingWindowEpsilon, int popSize) {
ClusterBasedNichingEA cbn = new ClusterBasedNichingEA(); ClusterBasedNichingEA cbn = new ClusterBasedNichingEA();
cbn.setOptimizer(opt);
cbn.setMergingCA(clustMerge);
cbn.setMaxSpeciesSize(maxSpecSize);
cbn.setDifferentiationCA(clustDifferentiate);
if (clustMerge!=null) cbn.setUseMerging(true);
cbn.setShowCycle(0); // don't do graphical output
cbn.setHaltingWindow(haltingWindowLength);
cbn.setEpsilonBound(haltingWindowEpsilon);
return makeParams(cbn, popSize, problem, randSeed, makeDefaultTerminator());
}
/**
* A standard CBNES which employs a (15,50)-ES with further parameters as set by the EvA2 framework.
*
* @param problem
* @return
*/
public static final GOParameters standardCbnES(AbstractOptimizationProblem problem) {
EvolutionStrategies es = new EvolutionStrategies(); EvolutionStrategies es = new EvolutionStrategies();
es.setMu(15); es.setMu(15);
es.setLambda(50); es.setLambda(50);
es.setPlusStrategy(false); es.setPlusStrategy(false);
cbn.setOptimizer(es); return createCbn(problem, es, cbnDefaultClusterSigma, cbnDefaultMinGroupSize, cbnDefaultMaxGroupSize, cbnDefaultHaltingWindowLength, cbnDefaultHaltingWindowEpsilon, 100);
ClusteringDensityBased clustering = new ClusteringDensityBased(0.1);
cbn.setMergingCA((ClusteringDensityBased) clustering.clone());
cbn.setDifferentiationCA(clustering);
cbn.setShowCycle(0); // don't do graphical output
return makeParams(cbn, 100, problem, randSeed, makeDefaultTerminator());
} }
public static final GOParameters cbnGA(AbstractOptimizationProblem problem) { /**
ClusterBasedNichingEA cbn = new ClusterBasedNichingEA(); * A standard CBNES which employs a CMA-ES, see {@link #cmaES(AbstractOptimizationProblem)}.
GeneticAlgorithm ga = new GeneticAlgorithm(); *
cbn.setOptimizer(ga); * @param problem
ClusteringDensityBased clustering = new ClusteringDensityBased(0.1); * @return
cbn.setMergingCA((ClusteringDensityBased) clustering.clone()); */
cbn.setDifferentiationCA(clustering); public static final GOParameters standardCbnCmaES(AbstractOptimizationProblem problem) {
cbn.setShowCycle(0); // don't do graphical output GOParameters cmaEsParams = cmaES(problem);
EvolutionStrategies cmaES = (EvolutionStrategies)cmaEsParams.getOptimizer();
return makeParams(cbn, 100, problem, randSeed, makeDefaultTerminator()); return createCbn(problem, cmaES, cbnDefaultClusterSigma, cbnDefaultMinGroupSize, cbnDefaultMaxGroupSize, cbnDefaultHaltingWindowLength, cbnDefaultHaltingWindowEpsilon, 100);
}
/**
* A standard CBNGA with a GA and further parameters as set by the EvA2 framework.
* @param problem
* @return
*/
public static final GOParameters standardCbnGA(AbstractOptimizationProblem problem) {
GeneticAlgorithm ga = new GeneticAlgorithm();
return createCbn(problem, ga, cbnDefaultClusterSigma, cbnDefaultMinGroupSize, cbnDefaultMaxGroupSize, cbnDefaultHaltingWindowLength, cbnDefaultHaltingWindowEpsilon, 100);
}
/**
* A standard CBNPSO with density based clustering working on personal best positions.
*
* @param problem
* @return
*/
public static final GOParameters standardCbnPSO(AbstractOptimizationProblem problem) {
GOParameters psoParams = standardPSO(problem);
ParticleSwarmOptimization pso = (ParticleSwarmOptimization)psoParams.getOptimizer();
ClusteringDensityBased clust = new ClusteringDensityBased(cbnDefaultClusterSigma, cbnDefaultMinGroupSize, new IndividualDataMetric(ParticleSwarmOptimization.partBestPosKey));
return createCbn(problem, pso, clust, cbnDefaultMaxGroupSize, new ClusteringDensityBased(clust), cbnDefaultHaltingWindowLength, cbnDefaultHaltingWindowEpsilon, 100);
} }
public static final GOParameters standardPBIL(AbstractOptimizationProblem problem) { public static final GOParameters standardPBIL(AbstractOptimizationProblem problem) {
@ -1306,6 +1383,10 @@ public class OptimizerFactory {
* @return * @return
*/ */
public static final GOParameters cmaESIPOP(AbstractOptimizationProblem problem) { public static final GOParameters cmaESIPOP(AbstractOptimizationProblem problem) {
return createCmaEsIPop(problem, 2.);
}
public static final GOParameters createCmaEsIPop(AbstractOptimizationProblem problem, double incLambdaFact) {
EvolutionStrategies es = new EvolutionStrategyIPOP(); EvolutionStrategies es = new EvolutionStrategyIPOP();
AbstractEAIndividual indyTemplate = problem.getIndividualTemplate(); AbstractEAIndividual indyTemplate = problem.getIndividualTemplate();
@ -1317,6 +1398,7 @@ public class OptimizerFactory {
int lambda = (int) (4.0 + 3.0 * Math.log(dim)); int lambda = (int) (4.0 + 3.0 * Math.log(dim));
es.setGenerationStrategy((int)Math.floor(lambda/2.),lambda, false); es.setGenerationStrategy((int)Math.floor(lambda/2.),lambda, false);
es.setForceOrigPopSize(false); es.setForceOrigPopSize(false);
((EvolutionStrategyIPOP)es).setIncPopSizeFact(incLambdaFact);
// Set CMA operator for mutation // Set CMA operator for mutation
AbstractEAIndividual indy = (AbstractEAIndividual) indyTemplate; AbstractEAIndividual indy = (AbstractEAIndividual) indyTemplate;
MutateESRankMuCMA cmaMut = new MutateESRankMuCMA(); MutateESRankMuCMA cmaMut = new MutateESRankMuCMA();
@ -1330,6 +1412,11 @@ public class OptimizerFactory {
return makeESParams(es, problem); return makeESParams(es, problem);
} }
public static final GOParameters standardNMS(AbstractOptimizationProblem problem) {
NelderMeadSimplex nms = NelderMeadSimplex.createNelderMeadSimplex(problem, null);
return makeParams(nms, 50, problem, randSeed, makeDefaultTerminator());
}
public static final GOParameters standardDE( public static final GOParameters standardDE(
AbstractOptimizationProblem problem) { AbstractOptimizationProblem problem) {
DifferentialEvolution de = new DifferentialEvolution(); DifferentialEvolution de = new DifferentialEvolution();
@ -1370,13 +1457,14 @@ public class OptimizerFactory {
return makeParams(ga, 100, problem, randSeed, makeDefaultTerminator()); return makeParams(ga, 100, problem, randSeed, makeDefaultTerminator());
} }
public static final GOParameters standardPSO( public static final GOParameters standardPSO(
AbstractOptimizationProblem problem) { AbstractOptimizationProblem problem) {
ParticleSwarmOptimization pso = new ParticleSwarmOptimization(); ParticleSwarmOptimization pso = new ParticleSwarmOptimization();
pso.setPhiValues(2.05, 2.05); pso.setPhiValues(2.05, 2.05);
// pso.getTopology().setSelectedTag("Grid"); // pso.getTopology().setSelectedTag("Grid");
pso.setTopology(PSOTopologyEnum.grid); pso.setTopology(PSOTopologyEnum.grid);
pso.setTopologyRange(1);
return makeParams(pso, 30, problem, randSeed, makeDefaultTerminator()); return makeParams(pso, 30, problem, randSeed, makeDefaultTerminator());
} }

View File

@ -37,6 +37,7 @@ public class OptimizerRunnable implements Runnable {
private boolean doRestart = false; // indicate whether start or restart should be done --> whether pop will be reinitialized. private boolean doRestart = false; // indicate whether start or restart should be done --> whether pop will be reinitialized.
private boolean postProcessOnly = false; private boolean postProcessOnly = false;
private InterfaceTextListener listener = null; private InterfaceTextListener listener = null;
private String ident="OptimizerRunnable";
/** /**
* Construct an OptimizerRunnable with given parameters and a StatisticsStandalone instance without restart, * Construct an OptimizerRunnable with given parameters and a StatisticsStandalone instance without restart,
@ -87,6 +88,14 @@ public class OptimizerRunnable implements Runnable {
doRestart = restart; doRestart = restart;
} }
public void setIdentifier(String id) {
ident=id;
}
public String getIdentifier() {
return ident;
}
public InterfaceGOParameters getGOParams() { public InterfaceGOParameters getGOParams() {
return proc.getGOParams(); return proc.getGOParams();
} }

View File

@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import eva2.server.go.populations.Population; import eva2.server.go.populations.Population;
import eva2.tools.Pair;
import eva2.tools.SelectedTag; import eva2.tools.SelectedTag;
import eva2.tools.Tag; import eva2.tools.Tag;
@ -131,7 +132,9 @@ public class BeanInspector {
return true; return true;
} }
public static String toString(Object Target) {
return toString(Target, ';', false);
}
/** /**
* Collect the accessible properties of an object and their values in a string. * Collect the accessible properties of an object and their values in a string.
* Special cases: Arrays and Lists are concatenations of their elements, Population is excepted from lists. * Special cases: Arrays and Lists are concatenations of their elements, Population is excepted from lists.
@ -141,7 +144,7 @@ public class BeanInspector {
* @param Target Description of the Parameter * @param Target Description of the Parameter
* @return Description of the Return Value * @return Description of the Return Value
*/ */
public static String toString(Object Target) { public static String toString(Object Target, char delim, boolean tight) {
String ret = ""; String ret = "";
if (Target == null) return "null"; if (Target == null) return "null";
// try the object itself // try the object itself
@ -149,13 +152,18 @@ public class BeanInspector {
Class<? extends Object> type = Target.getClass(); Class<? extends Object> type = Target.getClass();
if (type.isArray()) { // handle the array case if (type.isArray()) { // handle the array case
StringBuffer sbuf = new StringBuffer("[ "); StringBuffer sbuf = new StringBuffer("[");
if (!tight) sbuf.append(" ");
int len = Array.getLength(Target); int len = Array.getLength(Target);
for (int i=0; i<len; i++) { for (int i=0; i<len; i++) {
sbuf.append(toString(Array.get(Target, i))); sbuf.append(toString(Array.get(Target, i)));
if (i<len-1) sbuf.append("; "); if (i<len-1) {
sbuf.append(delim);
if (!tight) sbuf.append(" ");
}
} }
sbuf.append(" ]"); if (!tight) sbuf.append(" ");
sbuf.append("]");
return sbuf.toString(); return sbuf.toString();
} }
@ -164,13 +172,15 @@ public class BeanInspector {
} }
if (Target instanceof List && !(Target instanceof Population)) { // handle the list case if (Target instanceof List && !(Target instanceof Population)) { // handle the list case
StringBuffer sbuf = new StringBuffer("[ "); StringBuffer sbuf = new StringBuffer("[");
if (!tight) sbuf.append(" ");
List<?> lst = (List<?>)Target; List<?> lst = (List<?>)Target;
for (Object o : lst) { for (Object o : lst) {
sbuf.append(o.toString()); sbuf.append(o.toString());
sbuf.append("; "); sbuf.append(delim);
if (!tight) sbuf.append(" ");
} }
sbuf.setCharAt(sbuf.length()-2, ' '); if (!tight) sbuf.setCharAt(sbuf.length()-2, ' ');
sbuf.setCharAt(sbuf.length()-1, ']'); sbuf.setCharAt(sbuf.length()-1, ']');
return sbuf.toString(); return sbuf.toString();
} }
@ -192,20 +202,48 @@ public class BeanInspector {
} }
// otherwise try introspection and collect all public properties as strings // otherwise try introspection and collect all public properties as strings
Pair<String[],Object[]> nameVals = getPublicPropertiesOf(Target, true);
StringBuffer sbuf = new StringBuffer(type.getName());
sbuf.append("{");
for (int i=0; i<nameVals.head.length; i++) {
if (nameVals.head[i]!=null) {
sbuf.append(nameVals.head[i]);
sbuf.append("=");
sbuf.append(toString(nameVals.tail[i]));
sbuf.append(delim);
if (!tight) sbuf.append(" ");
}
}
sbuf.append("}");
return sbuf.toString();
}
/**
* Retrieve names and values of instance fields which are accessible by getter method, optionally
* by both getter and setter method. The returned arrays may contain null entries.
* Properties marked as hidden or expert are skipped.
*
* @param target
* @return
*/
public static Pair<String[],Object[]> getPublicPropertiesOf(Object target, boolean requireSetter) {
BeanInfo Info = null; BeanInfo Info = null;
PropertyDescriptor[] Properties = null; PropertyDescriptor[] Properties = null;
// MethodDescriptor[] Methods = null; // MethodDescriptor[] Methods = null;
try { try {
Info = Introspector.getBeanInfo(Target.getClass()); Info = Introspector.getBeanInfo(target.getClass());
Properties = Info.getPropertyDescriptors(); Properties = Info.getPropertyDescriptors();
Info.getMethodDescriptors(); Info.getMethodDescriptors();
} catch (IntrospectionException ex) { } catch (IntrospectionException ex) {
System.err.println("BeanTest: Couldn't introspect"); System.err.println("BeanTest: Couldn't introspect");
return ret; return null;
} }
StringBuffer sbuf = new StringBuffer(type.getName()); String[] nameArray = new String[Properties.length];
sbuf.append("{"); Object[] valArray = new Object[Properties.length];
for (int i = 0; i < Properties.length; i++) { for (int i = 0; i < Properties.length; i++) {
if (Properties[i].isHidden() || Properties[i].isExpert()) { if (Properties[i].isHidden() || Properties[i].isExpert()) {
continue; continue;
@ -217,7 +255,7 @@ public class BeanInspector {
Method getter = Properties[i].getReadMethod(); Method getter = Properties[i].getReadMethod();
Method setter = Properties[i].getWriteMethod(); Method setter = Properties[i].getWriteMethod();
// Only display read/write properties. // Only display read/write properties.
if (getter == null || setter == null) { if (getter == null || (setter == null && requireSetter)) {
continue; continue;
} }
//System.out.println("name = "+name ); //System.out.println("name = "+name );
@ -226,20 +264,16 @@ public class BeanInspector {
//System.out.println("m_Target"+m_Target.toString()); //System.out.println("m_Target"+m_Target.toString());
try { try {
Object value = getter.invoke(Target, args); nameArray[i]=name;
sbuf.append(name); valArray[i] = getter.invoke(target, args);
sbuf.append("=");
sbuf.append(toString(value));
sbuf.append("; ");
} catch (Exception e) { } catch (Exception e) {
System.err.println("BeanTest ERROR +"+ e.getMessage()); System.err.println("BeanTest ERROR +"+ e.getMessage());
return sbuf.toString();
} }
} }
sbuf.append("}"); Pair<String[],Object[]> nameVals = new Pair<String[],Object[]>(nameArray, valArray);
return sbuf.toString(); return nameVals;
} }
/** /**
*@param Target Description of the Parameter *@param Target Description of the Parameter

View File

@ -20,6 +20,7 @@ import java.awt.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.FontMetrics; import java.awt.FontMetrics;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Insets; import java.awt.Insets;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
@ -31,7 +32,6 @@ import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeSupport;
import java.beans.PropertyEditor; import java.beans.PropertyEditor;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Method;
import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel; import javax.swing.DefaultListModel;
@ -71,15 +71,26 @@ implements PropertyEditor {
private JButton m_DeleteBut = new JButton("Delete"); private JButton m_DeleteBut = new JButton("Delete");
/** Click to add the current object configuration to the array */ /** Click to add the current object configuration to the array */
private JButton m_AddBut = new JButton("Add"); private JButton m_AddBut = new JButton("Add");
private JButton m_SetBut = new JButton("Set");
private JButton m_SetAllBut = new JButton("Set all");
private Component m_View = null;
/** Listens to buttons being pressed and taking the appropriate action */ /** Listens to buttons being pressed and taking the appropriate action */
private ActionListener m_InnerActionListener = private ActionListener m_InnerActionListener =
new ActionListener() { new ActionListener() {
// //
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
boolean consistentView = true; // be optimistic...
if (m_View instanceof PropertyText) { // check consistency!
consistentView = ((PropertyText)m_View).checkConsistency();
if (!consistentView) {
// System.err.println("Warning, inconsistent view!");
((PropertyText)m_View).updateFromEditor();
}
}
if (e.getSource() == m_DeleteBut) { if (e.getSource() == m_DeleteBut) {
int [] selected = m_ElementList.getSelectedIndices(); int [] selected = m_ElementList.getSelectedIndices();
if (selected != null) { if (selected != null) {
for (int i = 0; i < selected.length; i++) { for (int i = selected.length-1; i>=0; i--) {
int current = selected[i]; int current = selected[i];
m_ListModel.removeElementAt(current); m_ListModel.removeElementAt(current);
if (m_ListModel.size() > current) { if (m_ListModel.size() > current) {
@ -113,6 +124,27 @@ implements PropertyEditor {
} catch (Exception ex) { } catch (Exception ex) {
JOptionPane.showMessageDialog(GenericArrayEditor.this,"Could not create an object copy",null,JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(GenericArrayEditor.this,"Could not create an object copy",null,JOptionPane.ERROR_MESSAGE);
} }
} else if (e.getSource() == m_SetAllBut) {
Object addObj = m_ElementEditor.getValue();
for (int i=0; i<m_ListModel.size(); i++) {
try {
m_ListModel.setElementAt(new SerializedObject(addObj).getObject(), i);
} catch (Exception e1) {
JOptionPane.showMessageDialog(GenericArrayEditor.this,"Could not create an object copy",null,JOptionPane.ERROR_MESSAGE);
}
}
m_Support.firePropertyChange("", null, null);
} else if (e.getSource() == m_SetBut) {
int selected = m_ElementList.getSelectedIndex();
Object addObj = m_ElementEditor.getValue();
if (selected>=0 && (selected <m_ListModel.size())) {
try {
m_ListModel.setElementAt(new SerializedObject(addObj).getObject(), selected);
} catch (Exception e1) {
JOptionPane.showMessageDialog(GenericArrayEditor.this,"Could not create an object copy",null,JOptionPane.ERROR_MESSAGE);
}
m_Support.firePropertyChange("", null, null);
}
} }
} }
}; };
@ -136,6 +168,7 @@ implements PropertyEditor {
if (m_ElementList.getSelectedIndex() != -1) { if (m_ElementList.getSelectedIndex() != -1) {
m_DeleteBut.setEnabled(true); m_DeleteBut.setEnabled(true);
m_ElementEditor.setValue(m_ElementList.getSelectedValue()); m_ElementEditor.setValue(m_ElementList.getSelectedValue());
if (m_View instanceof PropertyText) ((PropertyText)m_View).updateFromEditor();
} }
} }
} }
@ -150,6 +183,8 @@ implements PropertyEditor {
add(m_Label, BorderLayout.CENTER); add(m_Label, BorderLayout.CENTER);
m_DeleteBut.addActionListener(m_InnerActionListener); m_DeleteBut.addActionListener(m_InnerActionListener);
m_AddBut.addActionListener(m_InnerActionListener); m_AddBut.addActionListener(m_InnerActionListener);
m_SetAllBut.addActionListener(m_InnerActionListener);
m_SetBut.addActionListener(m_InnerActionListener);
m_ElementList.addListSelectionListener(m_InnerSelectionListener); m_ElementList.addListSelectionListener(m_InnerSelectionListener);
m_AddBut.setToolTipText("Add the current item to the list"); m_AddBut.setToolTipText("Add the current item to the list");
m_DeleteBut.setToolTipText("Delete the selected list item"); m_DeleteBut.setToolTipText("Delete the selected list item");
@ -248,7 +283,7 @@ implements PropertyEditor {
Class elementClass = arrayInstance.getClass().getComponentType(); Class elementClass = arrayInstance.getClass().getComponentType();
PropertyEditor editor = PropertyEditorProvider.findEditor(elementClass); PropertyEditor editor = PropertyEditorProvider.findEditor(elementClass);
if (editor instanceof EnumEditor) editor.setValue(obj); if (editor instanceof EnumEditor) editor.setValue(obj);
Component view = null; m_View = null;
ListCellRenderer lcr = new DefaultListCellRenderer(); ListCellRenderer lcr = new DefaultListCellRenderer();
if (editor != null) { if (editor != null) {
if (editor instanceof GenericObjectEditor) { if (editor instanceof GenericObjectEditor) {
@ -256,15 +291,15 @@ implements PropertyEditor {
((GenericObjectEditor) editor).setClassType(elementClass); ((GenericObjectEditor) editor).setClassType(elementClass);
} }
if (editor.isPaintable() && editor.supportsCustomEditor()) { if (editor.isPaintable() && editor.supportsCustomEditor()) {
view = new PropertyPanel(editor); m_View = new PropertyPanel(editor);
lcr = new EditorListCellRenderer(editor.getClass(), elementClass); lcr = new EditorListCellRenderer(editor.getClass(), elementClass);
} else if (editor.getTags() != null) { } else if (editor.getTags() != null) {
view = new PropertyValueSelector(editor); m_View = new PropertyValueSelector(editor);
} else if (editor.getAsText() != null) { } else if (editor.getAsText() != null) {
view = new PropertyText(editor); m_View = new PropertyText(editor);
} }
} }
if (view == null) { if (m_View == null) {
System.err.println("No property editor for class: " System.err.println("No property editor for class: "
+ elementClass.getName()); + elementClass.getName());
} else { } else {
@ -296,12 +331,18 @@ implements PropertyEditor {
} }
} }
setPreferredSize(new Dimension(300,300)); setPreferredSize(new Dimension(300,400));
JPanel panel = new JPanel(); // JPanel panel = new JPanel();
panel.setLayout(new BorderLayout()); // panel.setLayout(new BorderLayout());
panel.add(view, BorderLayout.CENTER); // panel.add(view, BorderLayout.CENTER);
panel.add(m_AddBut, BorderLayout.EAST); // panel.add(m_AddBut, BorderLayout.EAST);
add(panel, BorderLayout.NORTH); // JPanel buttonPanel=new JPanel(new FlowLayout());
JPanel combinedPanel = new JPanel(new GridLayout(1,3));
combinedPanel.add(m_View );
combinedPanel.add(m_AddBut);
combinedPanel.add(m_SetBut);
combinedPanel.add(m_SetAllBut);
add(combinedPanel, BorderLayout.NORTH);
add(new JScrollPane(m_ElementList), BorderLayout.CENTER); add(new JScrollPane(m_ElementList), BorderLayout.CENTER);
add(m_DeleteBut, BorderLayout.SOUTH); add(m_DeleteBut, BorderLayout.SOUTH);
m_ElementEditor.addPropertyChangeListener(new PropertyChangeListener() { m_ElementEditor.addPropertyChangeListener(new PropertyChangeListener() {
@ -454,7 +495,7 @@ implements PropertyEditor {
editor.setValue(initial); editor.setValue(initial);
PropertyDialog pd = new PropertyDialog(editor,EVAHELP.cutClassName(editor.getClass().getName()) PropertyDialog pd = new PropertyDialog(editor,EVAHELP.cutClassName(editor.getClass().getName())
, 100, 100); , 100, 100);
pd.setSize(200,200); // pd.setSize(200,200);
pd.addWindowListener(new WindowAdapter() { pd.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) { public void windowClosing(WindowEvent e) {
System.exit(0); System.exit(0);

View File

@ -15,8 +15,6 @@ package eva2.gui;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Component; import java.awt.Component;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyEditor; import java.beans.PropertyEditor;
import eva2.EvAInfo; import eva2.EvAInfo;
@ -55,7 +53,9 @@ public class PropertyDialog extends JEFrame {
} }
protected static String getFrameNameFromEditor(PropertyEditor editor) { protected static String getFrameNameFromEditor(PropertyEditor editor) {
return EVAHELP.cutClassName(editor.getValue().getClass().getName()); if (editor.getValue().getClass().isArray()) {
return "Array of " + EVAHELP.cutClassName(editor.getValue().getClass().getComponentType().getName());
} else return EVAHELP.cutClassName(editor.getValue().getClass().getName());
} }
/** /**

View File

@ -84,6 +84,7 @@ public class TopoPlot extends Plot {
double deltaY = sizeXY[1]/gridy; double deltaY = sizeXY[1]/gridy;
double maxDeriv=0; double maxDeriv=0;
double[] pos = new double[2]; double[] pos = new double[2];
boolean TRACEMETH=false;
//double fitRange = java.lang.Math.abs(problem.getMinFitness()-problem.getMaxFitness() ); //double fitRange = java.lang.Math.abs(problem.getMinFitness()-problem.getMaxFitness() );
double fitRange = 0, max = -Double.MAX_VALUE, min = Double.MAX_VALUE, tmp; double fitRange = 0, max = -Double.MAX_VALUE, min = Double.MAX_VALUE, tmp;
for (int x=0; x<gridx; x++) { for (int x=0; x<gridx; x++) {
@ -91,12 +92,14 @@ public class TopoPlot extends Plot {
pos[0] = border[0][0]+x*deltaX; pos[0] = border[0][0]+x*deltaX;
pos[1] = border[1][0]+y*deltaY; pos[1] = border[1][0]+y*deltaY;
tmp = (float)(problem.functionValue(pos)); tmp = (float)(problem.functionValue(pos));
if (TRACEMETH) System.out.println(pos[0] + " " + pos[1] + " " + tmp);
if (tmp < min) min = tmp; if (tmp < min) min = tmp;
if (tmp > max) max = tmp; if (tmp > max) max = tmp;
if (problem instanceof InterfaceFirstOrderDerivableProblem) { if (withGradientsIfAvailable && (problem instanceof InterfaceFirstOrderDerivableProblem)) {
double[] deriv = ((InterfaceFirstOrderDerivableProblem)problem).getFirstOrderGradients(pos); double[] deriv = ((InterfaceFirstOrderDerivableProblem)problem).getFirstOrderGradients(pos);
for (int i=0; i<2;i++) maxDeriv=Math.max(maxDeriv, Math.abs(deriv[i])); // maximum deriv of first 2 dims for (int i=0; i<2;i++) maxDeriv=Math.max(maxDeriv, Math.abs(deriv[i])); // maximum deriv of first 2 dims
} }
} // for y } // for y
} // for x } // for x
fitRange = java.lang.Math.abs(max - min); fitRange = java.lang.Math.abs(max - min);

View File

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

View File

@ -48,7 +48,7 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
protected double[] m_Fitness = new double[1]; protected double[] m_Fitness = new double[1];
private double m_ConstraintViolation = 0; private double m_ConstraintViolation = 0;
public boolean m_AreaConst4ParallelViolated = false; public boolean m_AreaConst4ParallelViolated = false; // no idea what felix used this for...
public boolean m_Marked = false; // is for GUI only! public boolean m_Marked = false; // is for GUI only!
public boolean m_isPenalized = false; // may be set true for penalty based constraints public boolean m_isPenalized = false; // may be set true for penalty based constraints
@ -143,7 +143,7 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
// m_Name = new String(individual.m_Name); // m_Name = new String(individual.m_Name);
m_dataHash = (HashMap<String,Object>)(individual.m_dataHash.clone()); m_dataHash = (HashMap<String,Object>)(individual.m_dataHash.clone());
m_ConstraintViolation = individual.m_ConstraintViolation; m_ConstraintViolation = individual.m_ConstraintViolation;
m_AreaConst4ParallelViolated = individual.m_AreaConst4ParallelViolated; // m_AreaConst4ParallelViolated = individual.m_AreaConst4ParallelViolated;
m_Marked = individual.m_Marked; m_Marked = individual.m_Marked;
m_isPenalized = individual.m_isPenalized; m_isPenalized = individual.m_isPenalized;
individualIndex = individual.individualIndex; individualIndex = individual.individualIndex;
@ -181,7 +181,7 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
// checking in mutation/crossover operators // checking in mutation/crossover operators
if (!this.m_MutationOperator.equals(indy.m_MutationOperator)) return false; if (!this.m_MutationOperator.equals(indy.m_MutationOperator)) return false;
if (!this.m_CrossoverOperator.equals(indy.m_CrossoverOperator)) return false; if (!this.m_CrossoverOperator.equals(indy.m_CrossoverOperator)) return false;
System.err.println("Check whether this is semantically meant by equality!!! (AbstractEAIndividual.equals())");
return true; return true;
} else { } else {
return false; return false;
@ -640,6 +640,28 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
return result; return result;
} }
/**
* This method will allow you to compare two individuals regarding the constraint violation only,
* and only if the specific tag has been set. (For, e.g., additive penalty there is no way of discriminating
* fitness and penalty after assigning).
* The one with lesser violation is regarded better. If the instance is better than the given
* indy, 1 is returned. If it is worse than the given indy, -1 is returned.
* If they both violate them equally, 0 is returned.
* This means that if both do not violate the constraints, 0 is returned.
*
* @param indy The individual to compare to.
* @return 1 if the instance is better (regarding constraints only), -1 if is worse, 0 if they are equal in that respect.
*/
public int compareConstraintViolation(AbstractEAIndividual indy) {
if ((this.m_ConstraintViolation > 0) && (indy.m_ConstraintViolation <= 0)) return -1;
if ((this.m_ConstraintViolation <= 0) && (indy.m_ConstraintViolation > 0)) return 1;
else { // both violate: ((this.m_ConstraintViolation > 0) && (indy.m_ConstraintViolation > 0)) {
if (this.m_ConstraintViolation < indy.m_ConstraintViolation) return 1 ;
else if (this.m_ConstraintViolation > indy.m_ConstraintViolation) return -1;
else return 0;
}
}
/** This method will allow you to compare two individuals regarding the dominance. /** This method will allow you to compare two individuals regarding the dominance.
* Note this is dominance! If the individuals are not comparable this method will * Note this is dominance! If the individuals are not comparable this method will
* return false! * return false!
@ -647,16 +669,9 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
* @return True if the own fitness dominates the other indy's * @return True if the own fitness dominates the other indy's
*/ */
public boolean isDominatingDebConstraints(AbstractEAIndividual indy) { public boolean isDominatingDebConstraints(AbstractEAIndividual indy) {
double[] tmpFitness = indy.getFitness(); int constrViolComp = compareConstraintViolation(indy);
if (this.m_AreaConst4ParallelViolated) return false; if (constrViolComp==0) return isDominatingFitness(getFitness(), indy.getFitness());
if (indy.m_AreaConst4ParallelViolated) return true; else return (constrViolComp > 0);
if ((this.m_ConstraintViolation > 0) && (indy.m_ConstraintViolation == 0)) return false;
if ((this.m_ConstraintViolation == 0) && (indy.m_ConstraintViolation > 0)) return true;
if ((this.m_ConstraintViolation > 0) && (indy.m_ConstraintViolation > 0)) {
if (this.m_ConstraintViolation > indy.m_ConstraintViolation) return false;
else return true;
}
return isDominatingFitness(getFitness(), tmpFitness);
// for (int i = 0; (i < this.m_Fitness.length) && (i < tmpFitness.length); i++) { // for (int i = 0; (i < this.m_Fitness.length) && (i < tmpFitness.length); i++) {
// if (this.m_Fitness[i] <= tmpFitness[i]) result &= true; // if (this.m_Fitness[i] <= tmpFitness[i]) result &= true;
// else result &= false; // else result &= false;
@ -677,7 +692,8 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
return isDominatingFitnessNotEqual(getFitness(), indy.getFitness()); return isDominatingFitnessNotEqual(getFitness(), indy.getFitness());
} }
/** This method will allow you to compare two individuals regarding the dominance. /**
* This method will allow you to compare two individuals regarding the dominance.
* Note this is dominance! If the individuals are not comparable this method will * Note this is dominance! If the individuals are not comparable this method will
* return false! * return false!
* *
@ -686,19 +702,10 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
*/ */
public boolean isDominatingDebConstraintsEqual(AbstractEAIndividual indy) { public boolean isDominatingDebConstraintsEqual(AbstractEAIndividual indy) {
// TODO: should this method really be called "..Equal"? // TODO: should this method really be called "..Equal"?
if (this.m_AreaConst4ParallelViolated) return false; int constrViolComp = compareConstraintViolation(indy);
if (indy.m_AreaConst4ParallelViolated) return true; if (constrViolComp==0) return isDominatingFitnessNotEqual(getFitness(), indy.getFitness());
if ((this.m_ConstraintViolation > 0) && (indy.m_ConstraintViolation == 0)) return false; else return (constrViolComp > 0);
if ((this.m_ConstraintViolation == 0) && (indy.m_ConstraintViolation > 0)) return true; // return isDominatingFitnessNotEqual(getFitness(), indy.getFitness());
if ((this.m_ConstraintViolation > 0) && (indy.m_ConstraintViolation > 0)) {
if (this.m_ConstraintViolation > indy.m_ConstraintViolation) return false;
else return true;
}
// for (int i = 0; (i < this.m_Fitness.length) && (i < tmpFitness.length); i++) {
// if (this.m_Fitness[i] < tmpFitness[i]) result &= true;
// else result &= false;
// }
return isDominatingFitnessNotEqual(getFitness(), indy.getFitness());
} }
/** This method can be used to read the current selection probability of the individual. /** This method can be used to read the current selection probability of the individual.
@ -869,14 +876,15 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
public static String getDefaultStringRepresentation(AbstractEAIndividual individual) { public static String getDefaultStringRepresentation(AbstractEAIndividual individual) {
// Note that changing this method might change the hashcode of an individual // Note that changing this method might change the hashcode of an individual
// which might interfere with some functionality. // which might interfere with some functionality.
StringBuffer sb = new StringBuffer(getDefaultDataString(individual)); StringBuffer sb = new StringBuffer("Fit.: ");
sb.append(", fitness: ");
sb.append(BeanInspector.toString(individual.getFitness())); sb.append(BeanInspector.toString(individual.getFitness()));
if (individual.isMarkedPenalized() || individual.violatesConstraint()) if (individual.isMarkedPenalized() || individual.violatesConstraint())
sb.append(", X"); sb.append(", X");
sb.append(", ID: "); sb.append(", ID: ");
sb.append(individual.getIndyID()); sb.append(individual.getIndyID());
sb.append(", ");
sb.append(getDefaultDataString(individual));
if (individual.getParentIDs()!=null) { if (individual.getParentIDs()!=null) {
sb.append(", parents: "); sb.append(", parents: ");
sb.append(BeanInspector.toString(individual.getParentIDs())); sb.append(BeanInspector.toString(individual.getParentIDs()));
@ -996,10 +1004,35 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
for (int i=0; i<intData.length; i++) pos[i] = (double)intData[i]; for (int i=0; i<intData.length; i++) pos[i] = (double)intData[i];
return pos; return pos;
} // TODO check some more types here? } // TODO check some more types here?
EVAERROR.errorMsgOnce("Unhandled case in AbstractEAIndividual.getPosition()!"); EVAERROR.errorMsgOnce("Unhandled case in AbstractEAIndividual.getDoublePosition()!");
return null; return null;
} }
/**
* For any AbstractEAIndividual try to convert its position to double[] and return it.
* Returns null if there is no conversion available.
*
* @param indy
* @return double valued position of an individual or null
*/
public static boolean setDoublePosition(AbstractEAIndividual indy, double[] pos) {
if (indy instanceof InterfaceESIndividual) {
((InterfaceESIndividual)indy).SetDGenotype(pos);
return true;
} else if (indy instanceof InterfaceDataTypeDouble) {
((InterfaceDataTypeDouble)indy).SetDoubleGenotype(pos);
return true;
} else if (indy instanceof InterfaceDataTypeInteger) {
EVAERROR.errorMsgOnce("Warning, double position truncated to integer! (AbstractEAIndividual.setDoublePosition)");
int[] intData = new int[pos.length];
for (int i=0; i<intData.length; i++) intData[i] = (int)pos[i];
((InterfaceDataTypeInteger)indy).SetIntGenotype(intData);
return true;
} // TODO check some more types here?
EVAERROR.errorMsgOnce("Unhandled case in AbstractEAIndividual.setDoublePosition()!");
return false;
}
/** /**
* Try to convert the individuals position to double[] and return it. * Try to convert the individuals position to double[] and return it.
* Returns null if there is no conversion available. * Returns null if there is no conversion available.

View File

@ -23,31 +23,31 @@ 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.
String indyDataKey = ""; private String indyDataKey = "";
int fitCriterion = -1; private int fitCriterion = -1;
private boolean preferFeasible = true;
/** /**
* Comparator implementation which compares two individuals based on their fitness. * Comparator implementation which compares two individuals based on their fitness.
* The default version calls isDominatingDebConstraints() of the AbstractEAIndividual * The default version calls compares based on dominance with priority of feasibility if there are constraints.
* class and assigns -1 if first is dominant, 1 if second is dominant, 0 if the two ind.s * It assigns -1 if first is better, 1 if second is better, 0 if the two ind.s are not comparable.
* are not comparable.
* *
*/ */
public AbstractEAIndividualComparator() { public AbstractEAIndividualComparator() {
this("", -1); this("", -1, true);
} }
/** /**
* Constructor with data key. A data field of the individuals may be used to retrieve * Constructor with data key. A data field of the individuals may be used to retrieve
* the double array used for comparison. Both individuals must have a data field with * the double array used for comparison. Both individuals must have a data field with
* the given key and return a double array of the same dimension. No constraints are * the given key and return a double array of the same dimension. Constraints are
* regarded for this comparison. * also regarded by default.
* If indyDataKey is null, the default comparison is used. * If indyDataKey is null, the default comparison is used.
* *
* @param indyDataKey * @param indyDataKey
*/ */
public AbstractEAIndividualComparator(String indyDataKey) { public AbstractEAIndividualComparator(String indyDataKey) {
this(indyDataKey, -1); this(indyDataKey, -1, true);
} }
/** /**
@ -57,7 +57,11 @@ public class AbstractEAIndividualComparator implements Comparator<Object>, Seria
* @param fitnessCriterion * @param fitnessCriterion
*/ */
public AbstractEAIndividualComparator(int fitnessCriterion) { public AbstractEAIndividualComparator(int fitnessCriterion) {
this("", fitnessCriterion); this("", fitnessCriterion, true);
}
public AbstractEAIndividualComparator(int fitIndex, boolean preferFeasible) {
this("", fitIndex, preferFeasible);
} }
/** /**
@ -67,16 +71,20 @@ public class AbstractEAIndividualComparator implements Comparator<Object>, Seria
* @see #AbstractEAIndividualComparator(String) * @see #AbstractEAIndividualComparator(String)
* @param indyDataKey * @param indyDataKey
* @param fitnessCriterion * @param fitnessCriterion
* @param priorizeConstraints
*/ */
public AbstractEAIndividualComparator(String indDataKey, int fitnessCriterion) { public AbstractEAIndividualComparator(String indDataKey, int fitnessCriterion, boolean preferFeasible) {
indyDataKey = indDataKey; this.indyDataKey = indDataKey;
fitCriterion = fitnessCriterion; this.fitCriterion = fitnessCriterion;
this.preferFeasible = preferFeasible;
} }
public AbstractEAIndividualComparator(AbstractEAIndividualComparator other) { public AbstractEAIndividualComparator(AbstractEAIndividualComparator other) {
indyDataKey = other.indyDataKey; indyDataKey = other.indyDataKey;
fitCriterion = other.fitCriterion;
preferFeasible = other.preferFeasible;
} }
public Object clone() { public Object clone() {
return new AbstractEAIndividualComparator(this); return new AbstractEAIndividualComparator(this);
} }
@ -92,9 +100,16 @@ public class AbstractEAIndividualComparator implements Comparator<Object>, Seria
public int compare(Object o1, Object o2) { public int compare(Object o1, Object o2) {
boolean o1domO2, o2domO1; boolean o1domO2, o2domO1;
if (indyDataKey != null && (indyDataKey.length()>0)) { if (preferFeasible) { // check constraint violation first?
int constrViolComp = ((AbstractEAIndividual) o1).compareConstraintViolation((AbstractEAIndividual) o2);
if (constrViolComp>0) return -1;
else if (constrViolComp < 0) return 1;
// otherwise both do not violate, so regard fitness
}
if (indyDataKey != null && (indyDataKey.length()>0)) { // check specific key
double[] fit1 = (double[])((AbstractEAIndividual)o1).getData(indyDataKey); double[] fit1 = (double[])((AbstractEAIndividual)o1).getData(indyDataKey);
double[] fit2 = (double[])((AbstractEAIndividual)o2).getData(indyDataKey); double[] fit2 = (double[])((AbstractEAIndividual)o2).getData(indyDataKey);
if ((fit1==null) || (fit2==null)) throw new RuntimeException("Unknown individual data key " + indyDataKey + ", unable to compare individuals ("+this.getClass().getSimpleName()+")");
if (fitCriterion < 0) { if (fitCriterion < 0) {
o1domO2 = AbstractEAIndividual.isDominatingFitness(fit1, fit2); o1domO2 = AbstractEAIndividual.isDominatingFitness(fit1, fit2);
o2domO1 = AbstractEAIndividual.isDominatingFitness(fit2, fit1); o2domO1 = AbstractEAIndividual.isDominatingFitness(fit2, fit1);
@ -104,15 +119,15 @@ public class AbstractEAIndividualComparator implements Comparator<Object>, Seria
} }
} else { } else {
if (fitCriterion < 0) { if (fitCriterion < 0) {
o1domO2 = ((AbstractEAIndividual) o1).isDominatingDebConstraints((AbstractEAIndividual) o2); o1domO2 = ((AbstractEAIndividual) o1).isDominating((AbstractEAIndividual) o2);
o2domO1 = ((AbstractEAIndividual) o2).isDominatingDebConstraints((AbstractEAIndividual) o1); o2domO1 = ((AbstractEAIndividual) o2).isDominating((AbstractEAIndividual) o1);
} else { } else {
if (((AbstractEAIndividual) o1).getFitness()[fitCriterion] == ((AbstractEAIndividual) o2).getFitness()[fitCriterion]) return 0; if (((AbstractEAIndividual) o1).getFitness()[fitCriterion] == ((AbstractEAIndividual) o2).getFitness()[fitCriterion]) return 0;
return (((AbstractEAIndividual) o1).getFitness()[fitCriterion] < ((AbstractEAIndividual) o2).getFitness()[fitCriterion]) ? -1 : 1; return (((AbstractEAIndividual) o1).getFitness()[fitCriterion] < ((AbstractEAIndividual) o2).getFitness()[fitCriterion]) ? -1 : 1;
} }
} }
if (o1domO2 ^ o2domO1) return (o1domO2 ? -1 : 1); if (o1domO2 ^ o2domO1) return (o1domO2 ? -1 : 1); // they are comparable
else return 0; // these are not comparable else return 0; // they are not comparable
} }
public String getIndyDataKey() { public String getIndyDataKey() {
@ -135,6 +150,16 @@ public class AbstractEAIndividualComparator implements Comparator<Object>, Seria
return "If -1, dominance is used, otherwise the indexed fitness criterion (for multiobjective problems)"; return "If -1, dominance is used, otherwise the indexed fitness criterion (for multiobjective problems)";
} }
public boolean isPreferFeasible() {
return preferFeasible;
}
public void setPreferFeasible(boolean priorConst) {
preferFeasible = priorConst;
}
public String preferFeasibleTipText() {
return "Activate preference of feasible individuals in any comparison acc. to Deb's rules.";
}
public String globalInfo() { public String globalInfo() {
return "A comparator class for general EA individuals. Compares individuals based on their fitness in context of minimization."; return "A comparator class for general EA individuals. Compares individuals based on their fitness in context of minimization.";
} }

View File

@ -46,6 +46,16 @@ public class ClusteringDensityBased implements InterfaceClustering, java.io.Seri
m_MinimumGroupSize = minGSize; m_MinimumGroupSize = minGSize;
} }
/**
* Directly set the minimum cluster distance sigma and minimum group size.
* @param sigma the minimum cluster distance
*/
public ClusteringDensityBased(double sigma, int minGSize, InterfaceDistanceMetric metric) {
m_ClusterDistance = sigma;
m_MinimumGroupSize = minGSize;
m_Metric = metric;
}
public ClusteringDensityBased(ClusteringDensityBased a) { public ClusteringDensityBased(ClusteringDensityBased a) {
if (a.m_Metric != null) this.m_Metric = (InterfaceDistanceMetric)a.m_Metric.clone(); if (a.m_Metric != null) this.m_Metric = (InterfaceDistanceMetric)a.m_Metric.clone();
this.m_TestConvergingSpeciesOnBestOnly = a.m_TestConvergingSpeciesOnBestOnly; this.m_TestConvergingSpeciesOnBestOnly = a.m_TestConvergingSpeciesOnBestOnly;

View File

@ -11,6 +11,8 @@ import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.AbstractEAIndividualComparator; 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.operators.paramcontrol.ParamAdaption;
import eva2.server.go.operators.paramcontrol.ParameterControlManager;
import eva2.server.go.populations.Population; import eva2.server.go.populations.Population;
import eva2.tools.Pair; import eva2.tools.Pair;
@ -34,7 +36,8 @@ public class ClusteringNearestBetter implements InterfaceClustering, Serializabl
private double currentMeanDistance = -1.; private double currentMeanDistance = -1.;
private int minimumGroupSize = 3; private int minimumGroupSize = 3;
private boolean testConvergingSpeciesOnBestOnly = true; // if two species are tested for convergence, only the best indies may be compared regarding the distance threshold private boolean testConvergingSpeciesOnBestOnly = true; // if two species are tested for convergence, only the best indies may be compared regarding the distance threshold
protected ParameterControlManager paramControl = new ParameterControlManager();
private int[] uplink; private int[] uplink;
private double[] uplinkDist; private double[] uplinkDist;
private AbstractEAIndividualComparator comparator = new AbstractEAIndividualComparator(); private AbstractEAIndividualComparator comparator = new AbstractEAIndividualComparator();
@ -42,7 +45,7 @@ public class ClusteringNearestBetter implements InterfaceClustering, Serializabl
private static final String initializedForKey = "initializedClustNearestBetterOnHash"; private static final String initializedForKey = "initializedClustNearestBetterOnHash";
private static final String initializedRefData = "initializedClustNearestBetterData"; private static final String initializedRefData = "initializedClustNearestBetterData";
private static boolean TRACE = true; private static boolean TRACE = false;
public ClusteringNearestBetter() { public ClusteringNearestBetter() {
} }
@ -58,9 +61,35 @@ public class ClusteringNearestBetter implements InterfaceClustering, Serializabl
this.testConvergingSpeciesOnBestOnly = o.testConvergingSpeciesOnBestOnly; this.testConvergingSpeciesOnBestOnly = o.testConvergingSpeciesOnBestOnly;
} }
public void hideHideable() { /**
* Set the mean distance factor in the adaptive case or the absolute distance
* threshold in the non-adaptive case.
*
* @param adaptive
* @param thresholdOrFactor
*
*/
public ClusteringNearestBetter(boolean adaptive, double thresholdOrFactor) {
setAdaptiveThreshold(adaptive);
if (adaptive) setMeanDistFactor(thresholdOrFactor);
else setDistThreshold(thresholdOrFactor);
}
public void hideHideable() {
setAdaptiveThreshold(isAdaptiveThreshold()); setAdaptiveThreshold(isAdaptiveThreshold());
} }
public ParameterControlManager getParamControl() {
return paramControl;
}
public ParamAdaption[] getParameterControl() {
return paramControl.getSingleAdapters();
}
public void setParameterControl(ParamAdaption[] paramControl) {
this.paramControl.setSingleAdapters(paramControl);
}
/** This method allows you to make a deep clone of /** This method allows you to make a deep clone of
* the object * the object
@ -289,7 +318,10 @@ public class ClusteringNearestBetter implements InterfaceClustering, Serializabl
// so add it to the cluster, mark it, and proceed recursively. // so add it to the cluster, mark it, and proceed recursively.
currentClust.add(sorted.get(children[current].get(i))); currentClust.add(sorted.get(children[current].get(i)));
clustered[children[current].get(i)]=true; clustered[children[current].get(i)]=true;
if (TRACE) System.out.println("Assigned " + current);
addChildren(children[current].get(i), clustered, sorted, currentClust); addChildren(children[current].get(i), clustered, sorted, currentClust);
} else {
if (TRACE) System.out.println("Not assigned " + current);
} }
} }
} else { } else {

View File

@ -7,7 +7,8 @@ import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.tools.math.RNG; import eva2.tools.math.RNG;
/** /**
* Created by IntelliJ IDEA. * Default 1-point-Crossover on InterfaceESIndividual instances.
*
* User: streiche * User: streiche
* Date: 25.03.2003 * Date: 25.03.2003
* Time: 11:16:39 * Time: 11:16:39

View File

@ -1,5 +1,6 @@
package eva2.server.go.operators.mutation; package eva2.server.go.operators.mutation;
import eva2.gui.BeanInspector;
import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceESIndividual; import eva2.server.go.individuals.InterfaceESIndividual;
import eva2.server.go.populations.Population; import eva2.server.go.populations.Population;
@ -34,7 +35,7 @@ public class MutateESCovarianceMatrixAdaption implements InterfaceMutation, java
protected Matrix m_C; protected Matrix m_C;
protected Matrix B; protected Matrix B;
protected boolean m_CheckConstraints = false; protected boolean m_CheckConstraints = false;
protected int m_constraint = 20; protected int m_constraintMaxTries = 50;
protected int m_Counter; protected int m_Counter;
protected int m_frequency = 1; protected int m_frequency = 1;
protected double[] m_Eigenvalues; protected double[] m_Eigenvalues;
@ -46,7 +47,7 @@ public class MutateESCovarianceMatrixAdaption implements InterfaceMutation, java
this.m_Counter = mutator.m_Counter; this.m_Counter = mutator.m_Counter;
this.m_frequency = mutator.m_frequency; this.m_frequency = mutator.m_frequency;
this.m_InitSigmaScalar = mutator.m_InitSigmaScalar; this.m_InitSigmaScalar = mutator.m_InitSigmaScalar;
this.m_constraint = mutator.m_constraint; this.m_constraintMaxTries = mutator.m_constraintMaxTries;
this.m_CheckConstraints = mutator.m_CheckConstraints; this.m_CheckConstraints = mutator.m_CheckConstraints;
this.m_D = mutator.m_D; this.m_D = mutator.m_D;
this.m_SigmaGlobal = mutator.m_SigmaGlobal; this.m_SigmaGlobal = mutator.m_SigmaGlobal;
@ -181,7 +182,7 @@ public class MutateESCovarianceMatrixAdaption implements InterfaceMutation, java
this.m_PathS[i] = (1.0 - this.m_c) * this.m_PathS[i] + this.m_c * this.cu * Bz_d; this.m_PathS[i] = (1.0 - this.m_c) * this.m_PathS[i] + this.m_c * this.cu * Bz_d;
pathLen = pathLen + this.m_PathS[i] * this.m_PathS[i]; pathLen = pathLen + this.m_PathS[i] * this.m_PathS[i];
} }
this.m_SigmaGlobal = this.m_SigmaGlobal * Math.exp(this.Beta * this.m_c * (Math.sqrt(pathLen) - this.xi_dach));; this.m_SigmaGlobal = this.m_SigmaGlobal * Math.exp(this.Beta * this.m_c * (Math.sqrt(pathLen) - this.xi_dach));
} }
protected void evaluateNewObjectX(double[] x,double[][] range) { protected void evaluateNewObjectX(double[] x,double[][] range) {
@ -218,8 +219,10 @@ public class MutateESCovarianceMatrixAdaption implements InterfaceMutation, java
// } // }
// } // }
// for (int i = 0; i < N; i++) x[i] = tmpD[i]; // for (int i = 0; i < N; i++) x[i] = tmpD[i];
// conservation of mutaion direction: // conservation of mutation direction:
double[] old = (double[]) this.m_Z.clone(); //double[] oldZ = (double[]) this.m_Z.clone();
double[] oldX = (double[])x.clone();
for (int i = 0; i < this.m_D; i++) this.m_Z[i] = RNG.gaussianDouble(1.0); for (int i = 0; i < this.m_D; i++) this.m_Z[i] = RNG.gaussianDouble(1.0);
this.m_C = (this.m_C.plus(this.m_C.transpose()).times(0.5)); // MAKE C SYMMETRIC this.m_C = (this.m_C.plus(this.m_C.transpose()).times(0.5)); // MAKE C SYMMETRIC
@ -232,9 +235,9 @@ public class MutateESCovarianceMatrixAdaption implements InterfaceMutation, java
this.m_Eigenvalues = helper.getRealEigenvalues(); this.m_Eigenvalues = helper.getRealEigenvalues();
} }
boolean constraint = false; boolean isNewPosFeasible = false;
int counter = 0; int counter = 0;
while (constraint == false && counter < this.m_constraint) { while (!isNewPosFeasible && counter < this.m_constraintMaxTries) {
for (int i = 0; i < this.m_D; i++) { for (int i = 0; i < this.m_D; i++) {
this.Bz[i] = 0; this.Bz[i] = 0;
for (int j = 0; j < this.m_D; j++) { for (int j = 0; j < this.m_D; j++) {
@ -242,22 +245,28 @@ public class MutateESCovarianceMatrixAdaption implements InterfaceMutation, java
} }
x[i] = x[i] + this.m_SigmaGlobal * this.Bz[i]; // here is the new value x[i] = x[i] + this.m_SigmaGlobal * this.Bz[i]; // here is the new value
} }
constraint = true; isNewPosFeasible = true;
if (this.m_CheckConstraints == true) { if (this.m_CheckConstraints == true) {
for (int i = 0; i < m_D; i++) { for (int i = 0; i < m_D; i++) {
if (x[i] < range[i][0] || x[i] > range[i][1]) { if (x[i] < range[i][0] || x[i] > range[i][1]) {
// undo the step and try new Z // undo the step and try new Z
for (int j = 0; j < this.m_D; j++) x[j] = x[j] - this.m_SigmaGlobal * this.Bz[j]; for (int j = 0; j < this.m_D; j++) x[j] = oldX[j] - this.m_SigmaGlobal * this.Bz[j];
this.m_Z[i] = RNG.gaussianDouble(1.0); this.m_Z[i] = RNG.gaussianDouble(1.0); // TODO is this feasible? mal mit rank-mu testen
constraint = false; isNewPosFeasible = false;
counter++; counter++;
break; break;
} }
} }
} }
} }
if (this.m_CheckConstraints) { // CSpieth if (counter>0) {
// System.out.print("CMA ES Req " + counter + " ");
// if (counter > 15) System.out.println(BeanInspector.toString(x));
// else System.out.println();
}
if (this.m_CheckConstraints && !isNewPosFeasible) { // use force
Mathematics.projectToRange(x, range); Mathematics.projectToRange(x, range);
// System.err.println("PROJECTING BY FORCE");
} }
} }

View File

@ -9,6 +9,7 @@ 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.InterfaceDataTypeDouble; import eva2.server.go.individuals.InterfaceDataTypeDouble;
import eva2.server.go.operators.distancemetric.EuclideanMetric;
import eva2.server.go.populations.Population; import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceOptimizationProblem; import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.server.go.strategies.EvolutionStrategies; import eva2.server.go.strategies.EvolutionStrategies;
@ -139,7 +140,10 @@ class CMAParamSet implements InterfacePopulationChangedEventListener, Serializab
// c_u_sig = Math.sqrt(c_sig * (2.-c_sig)); // c_u_sig = Math.sqrt(c_sig * (2.-c_sig));
params.d_sig = params.c_sig+1+2*Math.max(0, Math.sqrt((muEff-1)/(dim+1)) - 1); params.d_sig = params.c_sig+1+2*Math.max(0, Math.sqrt((muEff-1)/(dim+1)) - 1);
if (initialSigma<0) initialSigma = Mathematics.getAvgRange(params.range); if (initialSigma<0) { // this means we scale the average range
if (initialSigma!=-0.25 && (initialSigma!=-0.5)) EVAERROR.errorMsgOnce("Warning, unexpected initial sigma in CMAParamSet!");
initialSigma = -initialSigma*Mathematics.getAvgRange(params.range);
}
if (initialSigma <= 0) { if (initialSigma <= 0) {
EVAERROR.errorMsgOnce("warning: initial sigma <= zero! Working with converged population?"); EVAERROR.errorMsgOnce("warning: initial sigma <= zero! Working with converged population?");
initialSigma = 10e-10; initialSigma = 10e-10;
@ -248,7 +252,7 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
// instance, however this would create quite a big baustelle. // instance, however this would create quite a big baustelle.
private static transient CMAParamSet lastParams=null; private static transient CMAParamSet lastParams=null;
private ESMutationInitialSigma initializeSig = ESMutationInitialSigma.avgInitialDistance; private ESMutationInitialSigma initializeSig = ESMutationInitialSigma.quarterRange;
private double userDefInitSig = 0.2; private double userDefInitSig = 0.2;
public static final String cmaParamsKey = "RankMuCMAParameters"; public static final String cmaParamsKey = "RankMuCMAParameters";
@ -263,6 +267,7 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
this.c_c = mutator.c_c; this.c_c = mutator.c_c;
this.expRandStepLen = mutator.expRandStepLen; this.expRandStepLen = mutator.expRandStepLen;
this.initializeSig = mutator.initializeSig; this.initializeSig = mutator.initializeSig;
this.userDefInitSig = mutator.userDefInitSig;
} }
public Object clone() { public Object clone() {
@ -272,7 +277,8 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
/** /**
* Retrieve the initial sigma for the given population and the user defined method. * Retrieve the initial sigma for the given population and the user defined method.
* For the halfRange case, -1 is returned, as the range is not available here. * For the halfRange case, -1 is returned, as the range is not available here but set
* in initializing the CMAParams.
* @param initGen * @param initGen
* @return * @return
*/ */
@ -282,11 +288,13 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
// scaled by average range as the measures are normed // scaled by average range as the measures are normed
//return initGen.getPopulationMeasures(null)[0]*getAvgRange(); //return initGen.getPopulationMeasures(null)[0]*getAvgRange();
// use euclidian measures without normation and scaling // use euclidian measures without normation and scaling
return initGen.getPopulationMeasures()[0]; return initGen.getPopulationMeasures(new EuclideanMetric())[0]; // use euclidean metric which is not normed by range instead of phenotype metric
//case halfRange: return getAvgRange(range)/2.; //case halfRange: return getAvgRange(range)/2.;
case userDefined: return userDefInitSig ; case userDefined: return userDefInitSig ;
default: return -1.; case halfRange: return -0.5;
case quarterRange: return -0.25;
} }
throw new RuntimeException("Unknown initial sigma type!");
} }
/** /**
@ -554,7 +562,8 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
* additional rank mu * additional rank mu
* update * update
*/ */
double[] x_k = ((InterfaceDataTypeDouble)selected.getEAIndividual(k)).getDoubleData(); // double[] x_k = ((InterfaceDataTypeDouble)selected.getEAIndividual(k)).getDoubleData();
double[] x_k = AbstractEAIndividual.getDoublePositionShallow(selected.getEAIndividual(k));
newVal = params.mC.get(i,j)+ ccv * (1 - 1. / mcv) newVal = params.mC.get(i,j)+ ccv * (1 - 1. / mcv)
* params.weights[k] * (x_k[i] - params.meanX[i]) * params.weights[k] * (x_k[i] - params.meanX[i])
* (x_k[j] - params.meanX[j]) / (getSigma(params, i) * getSigma(params, j)); // TODO right sigmas? * (x_k[j] - params.meanX[j]) / (getSigma(params, i) * getSigma(params, j)); // TODO right sigmas?
@ -753,7 +762,7 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
} }
if (Mathematics.isInRange(x, range)) return x; if (Mathematics.isInRange(x, range)) return x;
else { else {
if (count > 5) return repairMutation(x, range); // allow some nice tries before using brute force if (count > 2*x.length) return repairMutation(x, range); // allow some nice tries before using brute force
else return mutate(params, x, range, count+1); // for really bad initial deviations this might be a quasi infinite loop else return mutate(params, x, range, count+1); // for really bad initial deviations this might be a quasi infinite loop
} }
} }
@ -764,6 +773,7 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
// % (the latter will decrease the overall step size) and // % (the latter will decrease the overall step size) and
// % recalculate arx accordingly. Do not change arx or arz in any // % recalculate arx accordingly. Do not change arx or arz in any
// % other way. // % other way.
EVAERROR.errorMsgOnce("Warning, brute-forcing constraints! Too large initial sigma? (pot. multiple errors)");
Mathematics.projectToRange(x, range); Mathematics.projectToRange(x, range);
return x; return x;
} }
@ -896,4 +906,8 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
public void setUserDefInitSig(double userDefInitSig) { public void setUserDefInitSig(double userDefInitSig) {
this.userDefInitSig = userDefInitSig; this.userDefInitSig = userDefInitSig;
} }
public String userDefInitSigTipText() {
return "Set a manual initial sigma which should be related to the initial individual distribution.";
}
} }

View File

@ -113,7 +113,7 @@ public class MutateGIOrdinal implements InterfaceMutation, java.io.Serializable
* @return description * @return description
*/ */
public String globalInfo() { public String globalInfo() {
return "The ordinal mutation alters n element of the int attributes based on an oridinal ordering."; return "The ordinal mutation alters n element of the int attributes based on an ordinal ordering.";
} }
/** This method allows you to set the mean step size. /** This method allows you to set the mean step size.

View File

@ -1,11 +1,13 @@
package eva2.server.go.operators.paramcontrol; package eva2.server.go.operators.paramcontrol;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.Vector; import java.util.Vector;
import eva2.gui.BeanInspector; import eva2.gui.BeanInspector;
import eva2.server.go.populations.Population; import eva2.server.go.populations.Population;
import eva2.server.modules.Processor; import eva2.server.modules.Processor;
import eva2.tools.Pair;
/** /**
* The ParameterControlManager handles an array of ParamAdaption instances which dynamically adapt * The ParameterControlManager handles an array of ParamAdaption instances which dynamically adapt
@ -144,4 +146,25 @@ public class ParameterControlManager implements InterfaceParameterControl, Seria
public String getName() { public String getName() {
return "ParameterControlManager"; return "ParameterControlManager";
} }
/**
* Retrieve a list of objects which are properties of the given target object (retrievable by a
* getter method) and which implement the getParamControl method.
*
* @param target
* @return
*/
public static Object[] arrayOfControllables(
Object target) {
Pair<String[],Object[]> propsNamesVals = BeanInspector.getPublicPropertiesOf(target, true);
ArrayList<Object> controllables = new ArrayList<Object>();
Object[] objs = propsNamesVals.tail;
for (int i=0; i<objs.length; i++) {
if (objs[i]!=null) {
// TODO avoid hasMethod recreate some interface for this??
if (BeanInspector.hasMethod(objs[i], "getParamControl")!=null) controllables.add(objs[i]);
}
}
return controllables.toArray(new Object[controllables.size()]);
}
} }

View File

@ -34,8 +34,11 @@ import eva2.server.go.problems.AbstractMultiModalProblemKnown;
import eva2.server.go.problems.AbstractOptimizationProblem; import eva2.server.go.problems.AbstractOptimizationProblem;
import eva2.server.go.problems.FM0Problem; import eva2.server.go.problems.FM0Problem;
import eva2.server.go.problems.Interface2DBorderProblem; import eva2.server.go.problems.Interface2DBorderProblem;
import eva2.server.go.problems.InterfaceFirstOrderDerivableProblem;
import eva2.server.go.problems.InterfaceInterestingHistogram;
import eva2.server.go.problems.InterfaceMultimodalProblemKnown; import eva2.server.go.problems.InterfaceMultimodalProblemKnown;
import eva2.server.go.strategies.EvolutionStrategies; import eva2.server.go.strategies.EvolutionStrategies;
import eva2.server.go.strategies.GradientDescentAlgorithm;
import eva2.server.go.strategies.HillClimbing; import eva2.server.go.strategies.HillClimbing;
import eva2.server.go.strategies.NelderMeadSimplex; import eva2.server.go.strategies.NelderMeadSimplex;
import eva2.server.modules.GOParameters; import eva2.server.modules.GOParameters;
@ -61,6 +64,8 @@ public class PostProcess {
private static double minMutationStepSize = 0.0000000000000001; private static double minMutationStepSize = 0.0000000000000001;
// used for hill climbing post processing and only alive during that period // used for hill climbing post processing and only alive during that period
private static OptimizerRunnable ppRunnable = null; private static OptimizerRunnable ppRunnable = null;
public static final String movedDistanceKey = "PostProcessingMovedBy";
public static final String movedToPositionKey = "PostProcessingMovedTo";
public static final int BEST_ONLY = 1; public static final int BEST_ONLY = 1;
public static final int BEST_RAND = 2; public static final int BEST_RAND = 2;
@ -157,9 +162,9 @@ public class PostProcess {
* Cluster the population. Return for every cluster a subset of representatives which are the best individuals * Cluster the population. Return for every cluster a subset of representatives which are the best individuals
* or a random subset of the cluster or the best and a random subset. Returns shallow copies! * or a random subset of the cluster or the best and a random subset. Returns shallow copies!
* returnQuota should be in [0,1] and defines, which percentage of individuals of each cluster is kept, however * returnQuota should be in [0,1] and defines, which percentage of individuals of each cluster is kept, however
* if returnQuota is > 0, at least one is kept. * at least one is kept per cluster.
* lonerMode defines whether loners are discarded, kept, or treated as clusters, meaning they are kept if returnQuota > 0. * lonerMode defines whether loners are discarded, kept, or treated as clusters, meaning they are kept if returnQuota > 0.
* takOverMode defines whether, of a cluster with size > 1, which n individuals are kept. Either the n best only, * takeOverMode defines whether, of a cluster with size > 1, which n individuals are kept. Either the n best only,
* or the single best and random n-1, or all n random. * or the single best and random n-1, or all n random.
* *
* @param pop * @param pop
@ -231,9 +236,9 @@ public class PostProcess {
* @param upper * @param upper
* @return * @return
*/ */
public static Population filterFitnessIn(Population pop, double lower, double upper) { public static Population filterFitnessIn(Population pop, double lower, double upper, int crit) {
Population result = filterFitness(pop, upper, true); Population result = filterFitness(pop, upper, true, crit);
return filterFitness(result, lower, false); return filterFitness(result, lower, false, crit);
} }
/** /**
@ -245,7 +250,7 @@ public class PostProcess {
* @param bSmaller if true, return individuals with lower or equal, else with higher fitness norm only * @param bSmaller if true, return individuals with lower or equal, else with higher fitness norm only
* @return * @return
*/ */
public static Population filterFitness(Population pop, double fitNorm, boolean bSmallerEq) { public static Population filterFitnessNormed(Population pop, double fitNorm, boolean bSmallerEq) {
AbstractEAIndividual indy; AbstractEAIndividual indy;
Population result = new Population(); Population result = new Population();
for (int i=0; i<pop.size(); i++) { for (int i=0; i<pop.size(); i++) {
@ -257,31 +262,33 @@ public class PostProcess {
} }
/** /**
* Create a fitness histogram of an evaluated population within the given interval and nBins number of bins. * Filter the individuals of a population which have a fitness below a given value.
* Therefore a bin is of size (upperBound-lowerBound)/nBins, and bin 0 starts at lowerBound. * If the single fitness criterion is valid (within the range of the fitness array),
* Returns an integer array with the number of individuals in each bin. * the absolute value of that criterion is compared, otherwise (e.g. crit=-1) the
* phenotypic norm of the full vector is used.
* Returns shallow copies!
* *
* @param pop the population to scan. * @param pop
* @param lowerBound lower bound of the fitness interval * @param fitNorm
* @param upperBound upper bound of the fitness interval * @param bSmaller if true, return individuals with lower or equal, else with higher fitness only
* @param nBins number of bins * @param crit index of the fitness criterion or -1 to use the norm
* @return an integer array with the number of individuals in each bin * @return
* @see filterFitnessIn()
*/ */
public static int[] createFitNormHistogram(Population pop, double lowerBound, double upperBound, int nBins) { public static Population filterFitness(Population pop, double fitThresh, boolean bSmallerEq, int crit) {
int[] res = new int[nBins]; double curFit;
double lower = lowerBound; AbstractEAIndividual indy;
double step = (upperBound - lowerBound) / nBins; Population result = new Population();
for (int i=0; i<nBins; i++) { for (int i=0; i<pop.size(); i++) {
// if (TRACE) System.out.println("checking between " + lower + " and " + (lower+step)); indy = pop.getEAIndividual(i);
res[i] = filterFitnessIn(pop, lower, lower+step).size(); if ((crit>=0) && (crit<indy.getFitness().length)) curFit = indy.getFitness(crit);
// if (TRACE) System.out.println("found " + res[i]); else curFit = PhenotypeMetric.norm(indy.getFitness());
lower += step;
} if (bSmallerEq && (curFit<=fitThresh)) result.add(indy);
return res; else if (!bSmallerEq && (curFit>fitThresh)) result.add(indy);
}
return result;
} }
// /** // /**
// * This method returns a set of individuals corresponding to an optimum in a given list. // * This method returns a set of individuals corresponding to an optimum in a given list.
// * The individuals returned are to be nearer than epsilon to a given optimum. It is not // * The individuals returned are to be nearer than epsilon to a given optimum. It is not
@ -399,6 +406,28 @@ public class PostProcess {
runPP(); runPP();
} }
// TODO ! test this
public static int processWithGDA(Population pop, AbstractOptimizationProblem problem, InterfaceTerminator term, int baseEvals, double minStepSize, double maxStepSize) {
GradientDescentAlgorithm gda = new GradientDescentAlgorithm();
gda.setAdaptStepSizeLocally(true);
gda.SetProblem(problem);
gda.setLocalMinStepSize(minStepSize);
gda.setLocalMaxStepSize(maxStepSize);
gda.setRecovery(false);
gda.initByPopulation(pop, false);
int funCallsBefore = pop.getFunctionCalls();
pop.SetFunctionCalls(baseEvals);
ppRunnable = new OptimizerRunnable(OptimizerFactory.makeParams(gda, pop, problem, 0, term), true);
ppRunnable.getStats().createNextGenerationPerformed(gda.getPopulation(), gda, null);
int funCallsDone = pop.getFunctionCalls()-baseEvals;
pop.SetFunctionCalls(funCallsBefore);
return funCallsDone;
}
/** /**
* Search for a local minimum using nelder mead and return the solution found and the number of steps * Search for a local minimum using nelder mead and return the solution found and the number of steps
* (evaluations) actually performed. This uses the whole population as starting population for nelder mead * (evaluations) actually performed. This uses the whole population as starting population for nelder mead
@ -426,7 +455,17 @@ public class PostProcess {
// as nms creates a new population and has already evaluated them, send a signal to stats // as nms creates a new population and has already evaluated them, send a signal to stats
ppRunnable.getStats().createNextGenerationPerformed(nms.getPopulation(), nms, null); ppRunnable.getStats().createNextGenerationPerformed(nms.getPopulation(), nms, null);
// if (problem instanceof InterfaceFirstOrderDerivableProblem) {
// double[] x = pop.getBestEAIndividual().getDoublePosition();
// System.out.println("grads: " + BeanInspector.toString(((InterfaceFirstOrderDerivableProblem)problem).getFirstOrderGradients(x)));
// }
runPP(); runPP();
// if (problem instanceof InterfaceFirstOrderDerivableProblem) {
// double[] x = pop.getBestEAIndividual().getDoublePosition();
// System.out.println("grads: " + BeanInspector.toString(((InterfaceFirstOrderDerivableProblem)problem).getFirstOrderGradients(x)));
// }
int funCallsDone = pop.getFunctionCalls()-baseEvals; int funCallsDone = pop.getFunctionCalls()-baseEvals;
pop.SetFunctionCalls(funCallsBefore); pop.SetFunctionCalls(funCallsBefore);
@ -520,25 +559,46 @@ public class PostProcess {
* @param maxPerturbation * @param maxPerturbation
* @param includeCand * @param includeCand
*/ */
public static Population createLSSupPopulation(PostProcessMethod method, AbstractOptimizationProblem problem, Population candidates, int index, double maxPerturbation, boolean includeCand) { public static Population createLSSupPopulation(PostProcessMethod method, AbstractOptimizationProblem problem, Population candidates, int index, double maxRelativePerturbation, boolean includeCand) {
Population subPop = null; Population subPop = null;
switch (method) { switch (method) {
case cmaES: case cmaES:
subPop = createPopInSubRange(maxPerturbation, problem, candidates.getEAIndividual(index)); // target size minus one because indy is added later
subPop = new Population();
createPopInSubRange(subPop, maxRelativePerturbation, getDefCMAPopSize(candidates.getEAIndividual(index))-1, candidates.getEAIndividual(index));
break; break;
case hillClimber: case hillClimber:
System.err.println("INVALID in createLSSupPopulation"); System.err.println("INVALID in createLSSupPopulation");
break; break;
case nelderMead: case nelderMead:
double[][] range = ((InterfaceDataTypeDouble)candidates.getEAIndividual(index)).getDoubleRange(); double[][] range = ((InterfaceDataTypeDouble)candidates.getEAIndividual(index)).getDoubleRange();
double perturb = findNMSPerturb(candidates, index, maxPerturbation); double perturb = findNMSPerturb(candidates, index, relToAbsPerturb(maxRelativePerturbation, range));
if (TRACE) System.out.println("perturb " + index + " is " + perturb); if (TRACE) System.out.println("perturb " + index + " is " + perturb);
subPop = NelderMeadSimplex.createNMSPopulation(candidates.getEAIndividual(index), perturb, range, false); subPop = NelderMeadSimplex.createNMSPopulation(candidates.getEAIndividual(index), absToRelPerturb(perturb, range), range, false);
} }
// subPop.setSameParams(candidates); // subPop.setSameParams(candidates);
return subPop; return subPop;
} }
public static double relToAbsPerturb(double maxRelativePerturbation, double[][] range) {
return maxRelativePerturbation*(Mathematics.getAvgRange(range));
}
public static double absToRelPerturb(double maxAbsPerturbation, double[][] range) {
return maxAbsPerturbation/(Mathematics.getAvgRange(range));
}
private static int getDefCMAPopSize(AbstractEAIndividual template) {
if (isDoubleCompliant(template)) {
double[][] range = getDoubleRange(template);
int targetSize = (int) (4.0 + 3.0 * Math.log(range.length)); // minus one because indy is added later
return targetSize;
} else {
System.err.println("Warning, invalid individual for PostProcess.getDefCMAPopSize");
return 10;
}
}
/** /**
* Employ hill-climbing directly or NM/CMA on the candidates. The candidate population * Employ hill-climbing directly or NM/CMA on the candidates. The candidate population
* must not be empty and candidates must implement InterfaceDataTypeDouble. * must not be empty and candidates must implement InterfaceDataTypeDouble.
@ -588,7 +648,8 @@ public class PostProcess {
* improved by checking the convergence state in the future. The given terminator will be applied to each * improved by checking the convergence state in the future. The given terminator will be applied to each
* candidate sub-population anew. If the terminator is null, 10*n steps will be performed on each candidate. * candidate sub-population anew. If the terminator is null, 10*n steps will be performed on each candidate.
* *
* A double value is added to each solution individual that replaces its ancestor candidate, using the key "PostProcessingMovedBy". * A double value is added to each solution individual that replaces its ancestor candidate, using the key
* PostProcess.movedDistanceKey.
* It indicates the phenotype distance the found solution has moved relatively to the original candidate. * It indicates the phenotype distance the found solution has moved relatively to the original candidate.
* *
* @see #findNMSPerturb(Population, int, double) * @see #findNMSPerturb(Population, int, double)
@ -598,17 +659,17 @@ public class PostProcess {
* @param method NM or CMA is allowed here * @param method NM or CMA is allowed here
* @param candidates * @param candidates
* @param term * @param term
* @param maxPerturbation perturbation for the sub population * @param maxRelativePerturbation perturbation for the sub population relative to problem range
* @param prob * @param prob
* @return the number of evaluations performed * @return the number of evaluations performed
*/ */
public static int processSingleCandidatesNMCMA(PostProcessMethod method, Population candidates, InterfaceTerminator term, double maxPerturbation, AbstractOptimizationProblem prob) { public static int processSingleCandidatesNMCMA(PostProcessMethod method, Population candidates, InterfaceTerminator term, double maxRelativePerturbation, AbstractOptimizationProblem prob) {
ArrayList<Population> nmPops = new ArrayList<Population>(); ArrayList<Population> nmPops = new ArrayList<Population>();
int stepsPerf = 0; int stepsPerf = 0;
Population subPop; Population subPop;
for (int i=0; i<candidates.size(); i++) { // create all subPopulations for (int i=0; i<candidates.size(); i++) { // create all subPopulations
subPop = createLSSupPopulation(method, prob, candidates, i, maxPerturbation, false); subPop = createLSSupPopulation(method, prob, candidates, i, maxRelativePerturbation, false);
prob.evaluate(subPop); prob.evaluate(subPop);
stepsPerf += subPop.size(); stepsPerf += subPop.size();
@ -642,7 +703,9 @@ public class PostProcess {
// if (subPop.getBestEAIndividual().isDominant(candidates.getEAIndividual(i))) { // TODO Multiobjective??? // if (subPop.getBestEAIndividual().isDominant(candidates.getEAIndividual(i))) { // TODO Multiobjective???
if (subPop.getBestEAIndividual().getFitness(0)<candidates.getEAIndividual(i).getFitness(0)) { if (subPop.getBestEAIndividual().getFitness(0)<candidates.getEAIndividual(i).getFitness(0)) {
// System.out.println("moved by "+ PhenotypeMetric.dist(candidates.getEAIndividual(i), subPop.getBestEAIndividual())); // System.out.println("moved by "+ PhenotypeMetric.dist(candidates.getEAIndividual(i), subPop.getBestEAIndividual()));
subPop.getBestEAIndividual().putData("PostProcessingMovedBy", new Double(PhenotypeMetric.dist(candidates.getEAIndividual(i), subPop.getBestEAIndividual()))); subPop.getBestEAIndividual().putData(movedDistanceKey, new Double(PhenotypeMetric.dist(candidates.getEAIndividual(i), subPop.getBestEAIndividual())));
// subPop.getBestEAIndividual().putData(movedToPositionKey, subPop.getBestEAIndividual().getDoublePosition());
// ^ this makes no sense here since the new position is returned anyways by replacing the candidate individual
candidates.set(i, subPop.getBestEAIndividual()); candidates.set(i, subPop.getBestEAIndividual());
} }
} else { } else {
@ -689,36 +752,33 @@ public class PostProcess {
* problem constraints, meaning that the box may be smaller at the brim of the problem-defined search range. * problem constraints, meaning that the box may be smaller at the brim of the problem-defined search range.
* *
* @param searchBoxLen * @param searchBoxLen
* @param prob
* @param indy * @param indy
* @return * @return
*/ */
private static Population createPopInSubRange(double searchBoxLen, public static void createPopInSubRange(Population destPop, double searchBoxLen,
AbstractOptimizationProblem prob, int targetSize,
AbstractEAIndividual indy) { AbstractEAIndividual indy) {
if (isDoubleCompliant(indy)) { if (isDoubleCompliant(indy)) {
double[][] range = getDoubleRange(indy); double[][] range = getDoubleRange(indy);
double[] data = getDoubleData(indy); double[] data = getDoubleData(indy);
int lambda= (int) (4.0 + 3.0 * Math.log(range.length));
double[][] newRange = new double[range.length][2]; double[][] newRange = new double[range.length][2];
for (int dim=0; dim<range.length; dim++) { for (int dim=0; dim<range.length; dim++) {
// create a small range array around the expected local optimum // create a small range array around the expected local optimum
newRange[dim][0] = Math.max(range[dim][0], data[dim]-(searchBoxLen/2.)); newRange[dim][0] = Math.max(range[dim][0], data[dim]-(searchBoxLen/2.));
newRange[dim][1] = Math.min(range[dim][1], data[dim]+(searchBoxLen/2.)); newRange[dim][1] = Math.min(range[dim][1], data[dim]+(searchBoxLen/2.));
} }
Population pop = new Population(); // Population pop = new Population();
for (int i=0; i<lambda-1; i++) { // minus one because indy is added later destPop.clear();
for (int i=0; i<targetSize; i++) {
AbstractEAIndividual tmpIndy = (AbstractEAIndividual)indy.clone(); AbstractEAIndividual tmpIndy = (AbstractEAIndividual)indy.clone();
data = getDoubleData(tmpIndy); data = getDoubleData(tmpIndy);
ESIndividualDoubleData.defaultInit(data, newRange); ESIndividualDoubleData.defaultInit(data, newRange);
setDoubleData(tmpIndy, data); setDoubleData(tmpIndy, data);
pop.addIndividual(tmpIndy); destPop.addIndividual(tmpIndy);
} }
pop.synchSize(); destPop.synchSize();
return pop;
} else { } else {
System.err.println("invalid individual type!"); System.err.println("invalid individual type!");
return null;
} }
} }
@ -760,7 +820,7 @@ public class PostProcess {
if (plot == null) { if (plot == null) {
plot = new TopoPlot("PostProcessing: " + title, "x", "y",range[0],range[1]); plot = new TopoPlot("PostProcessing: " + title, "x", "y",range[0],range[1]);
if (prob instanceof Interface2DBorderProblem) { if (prob instanceof Interface2DBorderProblem) {
plot.setParams(60, 60); plot.setParams(60, 60);
plot.setTopology((Interface2DBorderProblem)prob); plot.setTopology((Interface2DBorderProblem)prob);
} }
} }
@ -860,9 +920,9 @@ public class PostProcess {
if (prob instanceof InterfaceMultimodalProblemKnown) { if (prob instanceof InterfaceMultimodalProblemKnown) {
InterfaceMultimodalProblemKnown mmkProb = (InterfaceMultimodalProblemKnown)prob; InterfaceMultimodalProblemKnown mmkProb = (InterfaceMultimodalProblemKnown)prob;
listener.println("number of known optima is " + mmkProb.getRealOptima().size()); listener.println("number of known optima is " + mmkProb.getRealOptima().size());
listener.println("default epsilon is " + mmkProb.getEpsilon()); listener.println("default epsilon is " + mmkProb.getDefaultAccuracy());
listener.println("optima found with default epsilon: " + getFoundOptima(solutions, mmkProb.getRealOptima(), mmkProb.getEpsilon(), true).size()); listener.println("optima found with default epsilon: " + getFoundOptima(solutions, mmkProb.getRealOptima(), mmkProb.getDefaultAccuracy(), true).size());
listener.println("max peak ratio is " + mmkProb.getMaximumPeakRatio(getFoundOptima(solutions, mmkProb.getRealOptima(), mmkProb.getEpsilon(), true))); listener.println("max peak ratio is " + mmkProb.getMaximumPeakRatio(getFoundOptima(solutions, mmkProb.getRealOptima(), mmkProb.getDefaultAccuracy(), true)));
for (double epsilon=0.1; epsilon > 0.00000001; epsilon/=10.) { for (double epsilon=0.1; epsilon > 0.00000001; epsilon/=10.) {
// out.println("no optima found: " + ((InterfaceMultimodalProblemKnown)mmProb).getNumberOfFoundOptima(pop)); // out.println("no optima found: " + ((InterfaceMultimodalProblemKnown)mmProb).getNumberOfFoundOptima(pop));
listener.println("found " + getFoundOptima(solutions, mmkProb.getRealOptima(), epsilon, true).size() + " for epsilon = " + epsilon + ", maxPeakRatio: " + AbstractMultiModalProblemKnown.getMaximumPeakRatio(mmkProb,solutions, epsilon)); listener.println("found " + getFoundOptima(solutions, mmkProb.getRealOptima(), epsilon, true).size() + " for epsilon = " + epsilon + ", maxPeakRatio: " + AbstractMultiModalProblemKnown.getMaximumPeakRatio(mmkProb,solutions, epsilon));
@ -885,6 +945,24 @@ public class PostProcess {
} }
} }
/**
* Cluster the potential optima from a population using {@link #getFoundOptima(Population, Population, double, boolean)} or
* extractPotentialOptima {@link AbstractOptimizationProblem}. Overwrites the given histogram and returns the found solutions
* within a new population.
*
* @param pop
* @param prob
* @param hist
* @param accuracy
* @param maxPPEvalsPerIndy
* @return
*/
public static Population clusterBestUpdateHistogram(Population pop, AbstractOptimizationProblem prob, SolutionHistogram hist, int crit, double accuracy) {
Population opts = clusterBest(pop, accuracy, 0, KEEP_LONERS, BEST_ONLY);
hist.updateFrom(opts, crit);
return opts;
}
/** /**
* General post processing method, receiving parameter instance for specification. * General post processing method, receiving parameter instance for specification.
* Optional clustering and HC step, output contains population measures, fitness histogram and * Optional clustering and HC step, output contains population measures, fitness histogram and
@ -897,7 +975,7 @@ public class PostProcess {
* @return the clustered, post-processed population * @return the clustered, post-processed population
*/ */
public static Population postProcess(InterfacePostProcessParams params, Population inputPop, AbstractOptimizationProblem problem, InterfaceTextListener listener) { public static Population postProcess(InterfacePostProcessParams params, Population inputPop, AbstractOptimizationProblem problem, InterfaceTextListener listener) {
if (params.isDoPostProcessing()) { if (params.isDoPostProcessing() && (inputPop!=null)) {
Plot plot; Plot plot;
Population clusteredPop, outputPop, stateBeforeLS; Population clusteredPop, outputPop, stateBeforeLS;
@ -945,11 +1023,17 @@ public class PostProcess {
double upBnd = PhenotypeMetric.norm(outputPop.getWorstEAIndividual().getFitness())*1.1; double upBnd = PhenotypeMetric.norm(outputPop.getWorstEAIndividual().getFitness())*1.1;
upBnd = Math.pow(10,Math.floor(Math.log10(upBnd)+1)); upBnd = Math.pow(10,Math.floor(Math.log10(upBnd)+1));
double lowBnd = 0; double lowBnd = 0;
int[] sols = PostProcess.createFitNormHistogram(outputPop, lowBnd, upBnd, 20); int fitCrit = 0; // use first fitness criterion
SolutionHistogram solHist = SolutionHistogram.createFitNormHistogram(outputPop, lowBnd, upBnd, 20, fitCrit);
// PostProcessInterim.outputResult((AbstractOptimizationProblem)goParams.getProblem(), outputPop, 0.01, System.out, 0, 2000, 20, goParams.getPostProcessSteps()); // PostProcessInterim.outputResult((AbstractOptimizationProblem)goParams.getProblem(), outputPop, 0.01, System.out, 0, 2000, 20, goParams.getPostProcessSteps());
if (outputPop.size()>1) { if (outputPop.size()>1) {
if (listener != null) listener.println("measures: " + BeanInspector.toString(outputPop.getPopulationMeasures())); if (listener != null) listener.println("measures: " + BeanInspector.toString(outputPop.getPopulationMeasures()));
if (listener != null) listener.println("solution histogram in [" + lowBnd + "," + upBnd + "]: " + BeanInspector.toString(sols)); if (listener != null) listener.println("solution histogram: " + solHist + ", score " + solHist.getScore());
if ((listener != null) && (problem instanceof InterfaceInterestingHistogram)) {
SolutionHistogram pSolHist = ((InterfaceInterestingHistogram)problem).getHistogram();
pSolHist.updateFrom(outputPop, fitCrit);
listener.println("problem-defined histogram: " + pSolHist + ", score " + pSolHist.getScore());
}
} }
//////////// multimodal data output //////////// multimodal data output
@ -1002,7 +1086,7 @@ public class PostProcess {
* @param maxPerturb optional upper bound of the returned perturbation * @param maxPerturb optional upper bound of the returned perturbation
* @return * @return
*/ */
public static double findNMSPerturb(Population candidates, int i, double maxPerturb) { public static double findNMSPerturb(Population candidates, int i, double maxAbsPerturb) {
double minDistNeighbour = Double.MAX_VALUE; double minDistNeighbour = Double.MAX_VALUE;
AbstractEAIndividual indy = candidates.getEAIndividual(i); AbstractEAIndividual indy = candidates.getEAIndividual(i);
boolean found=false; boolean found=false;
@ -1019,13 +1103,13 @@ public class PostProcess {
} }
if (!found) { if (!found) {
// System.err.println("warning, equal candidates in PostProcess.findNMSPerturb - converged population?!"); // System.err.println("warning, equal candidates in PostProcess.findNMSPerturb - converged population?!");
if (maxPerturb>0) return maxPerturb; if (maxAbsPerturb>0) return maxAbsPerturb;
else { else {
System.err.println("error, unable to select perturbance value in PostProcess.findNMSPerturb since all candidates are equal. Converged population?!"); System.err.println("error, unable to select perturbance value in PostProcess.findNMSPerturb since all candidates are equal. Converged population?!");
return 0.01; return 0.01;
} }
} }
if (maxPerturb>0) return Math.min(maxPerturb, minDistNeighbour/3.); if (maxAbsPerturb>0) return Math.min(maxAbsPerturb, minDistNeighbour/3.);
else return minDistNeighbour/3.; else return minDistNeighbour/3.;
} }

View File

@ -0,0 +1,166 @@
package eva2.server.go.operators.postprocess;
import java.util.Arrays;
import eva2.gui.BeanInspector;
import eva2.server.go.populations.Population;
import eva2.tools.math.Mathematics;
public class SolutionHistogram {
private double lBound, uBound;
private int numBins;
private int[] histogram;
private int arity; // number of summed-up histograms
public SolutionHistogram(double lower, double upper, int nBins) {
lBound=lower;
uBound=upper;
numBins=nBins;
histogram = new int[numBins];
arity = 0;
}
public SolutionHistogram cloneEmpty() {
return new SolutionHistogram(getLowerBound(), getUpperBound(), getNumBins());
}
public boolean isEmtpy() {
return arity==0;
}
private void setEntry(int i, int v) {
histogram[i]=v;
}
public int getEntry(int i) {
return histogram[i];
}
public double lowerBoundOfEntry(int i) {
return lBound+(i*getStepSize());
}
public double upperBoundOfEntry(int i) {
return lBound+((i+1)*getStepSize());
}
public double getLowerBound() {
return lBound;
}
public double getUpperBound() {
return uBound;
}
public int getNumBins() {
return numBins;
}
public double getStepSize() {
return (uBound-lBound)/numBins;
}
public boolean isCompatible(SolutionHistogram o) {
if (lBound==o.getLowerBound() && (uBound==o.getUpperBound()) && (numBins==o.getNumBins())) return true;
else return false;
}
/**
* Add another histogram to this one.
* @param o
*/
public void addHistogram(SolutionHistogram o) {
if (o.isEmtpy()) System.err.println("Warning, adding empty histogram... (SolutionHistogram)");
if (isCompatible(o)) {
arity+=o.arity;
for (int i=0; i<numBins; i++) histogram[i]+=o.histogram[i];
}
}
/**
* Get the average of summed-up histograms.
* @return
*/
public double[] getAverage() {
double[] avg = new double[numBins];
for (int i=0; i<numBins; i++) avg[i]=((double)histogram[i])/arity;
return avg;
}
public int sum() {
return Mathematics.sum(histogram);
}
public String toString() {
return "Hist("+arity+"):"+lBound+"/"+uBound+","+BeanInspector.toString(histogram) + ",Sc:"+getScore()+(arity>1 ? (",Avg.Sc:"+(getScore()/arity)) : (""));
}
/**
* Fill a given histogram from a population. Old entries are overwritten.
* @param pop
* @param hist
*/
public static void createFitNormHistogram(Population pop, SolutionHistogram hist, int crit) {
hist.reset();
for (int i=0; i<hist.getNumBins(); i++) {
hist.setEntry(i, PostProcess.filterFitnessIn(pop, hist.lowerBoundOfEntry(i), hist.upperBoundOfEntry(i), crit).size());
}
hist.setSingularHist();
}
/**
* Notify that a single histogram has been created.
*/
private void setSingularHist() {
arity=1;
}
private void reset() {
arity=0;
Arrays.fill(histogram, 0);
}
/**
* Fill a given histogram from a population. Old entries are overwritten.
* This resets the arity.
* @param pop
* @param hist
*/
public void updateFrom(Population pop, int crit) {
SolutionHistogram.createFitNormHistogram(pop, this, crit);
}
/**
* Create a fitness histogram of an evaluated population within the given interval and nBins number of bins.
* Therefore a bin is of size (upperBound-lowerBound)/nBins, and bin 0 starts at lowerBound.
* Returns an integer array with the number of individuals in each bin.
*
* @param pop the population to scan.
* @param lowerBound lower bound of the fitness interval
* @param upperBound upper bound of the fitness interval
* @param nBins number of bins
* @return an integer array with the number of individuals in each bin
* @see filterFitnessIn()
*/
public static SolutionHistogram createFitNormHistogram(Population pop, double lowerBound, double upperBound, int nBins, int crit) {
SolutionHistogram res = new SolutionHistogram(lowerBound, upperBound, nBins);
createFitNormHistogram(pop, res, crit);
return res;
}
// public void updateFrom(Population pop, double accuracy) {
//
// }
public double getScore() {
double sc = 0;
if (sum()>0) {
for (int i=numBins-1; i>=0; i--) {
sc += getScalingFactor(i)*((double)getEntry(i));
}
return sc;
} else return 0;
}
private double getScalingFactor(int i) {
return (numBins-i)/((double)numBins);
}
}

View File

@ -88,7 +88,8 @@ public class CombinedTerminator implements InterfaceTerminator, Serializable {
// make sure that both terminators are triggered by every call, because some judge // make sure that both terminators are triggered by every call, because some judge
// time-dependently and store information on the population. // time-dependently and store information on the population.
ret = getTermState(t1, curPopOrSols); ret = getTermState(t1, curPopOrSols);
ret = ret && getTermState(t2, curPopOrSols); boolean ret2 = getTermState(t2, curPopOrSols);
ret=ret && ret2;
if (ret) msg = "Terminated because both: " + t1.lastTerminationMessage() + " And " + t2.lastTerminationMessage(); if (ret) msg = "Terminated because both: " + t1.lastTerminationMessage() + " And " + t2.lastTerminationMessage();
} else { // OR } else { // OR
// make sure that both terminators are triggered on every call, because some judge // make sure that both terminators are triggered on every call, because some judge

View File

@ -91,11 +91,11 @@ Serializable {
public boolean isTerminated(PopulationInterface Pop) { public boolean isTerminated(PopulationInterface Pop) {
if (!firstTime && isStillConverged(Pop)) { if (!firstTime && isStillConverged(Pop)) {
if (stagnationTimeHasPassed(Pop)) { if (stagnationTimeHasPassed(Pop)) {
// population hasnt improved much for max time, criterion is met // population hasnt changed much for max time, criterion is met
msg = getTerminationMessage(tagString); msg = getTerminationMessage(tagString);
return true; return true;
} else { } else {
// population hasnt improved much for i<max time, keep running // population hasnt changed much for i<max time, keep running
return false; return false;
} }
} else { } else {
@ -131,7 +131,7 @@ Serializable {
} }
/** /**
* Return true if |oldFit - curFit| < |oldFit| * thresh% (relative case) * Return true if |oldFit - curFit| < |oldFit| * thresh (relative case)
* and if |oldFit - curFit| < thresh (absolute case). * and if |oldFit - curFit| < thresh (absolute case).
* *
* @param curFit * @param curFit
@ -160,13 +160,6 @@ Serializable {
} }
} }
/**
*
*/
// public String toString() {
// return BeanTest.toString(this);
// }
/** /**
* *
*/ */

View File

@ -0,0 +1,149 @@
package eva2.server.go.operators.terminators;
import java.io.Serializable;
import java.util.List;
import eva2.server.go.InterfaceTerminator;
import eva2.server.go.PopulationInterface;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.AbstractEAIndividualComparator;
import eva2.server.go.operators.distancemetric.ObjectiveSpaceMetric;
import eva2.server.go.populations.InterfaceSolutionSet;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceOptimizationProblem;
/**
* A terminator regarding population history (the archive of a population). Since the population
* history is not in general accessible from the GUI, this terminator is hidden.
* @author mkron
*
*/
public class HistoryConvergenceTerminator implements InterfaceTerminator, Serializable {
int haltingWindowLen = 15;
int fitCrit = 0;
double convergenceThreshold;
boolean stdDevInsteadOfImprovement;
AbstractEAIndividualComparator indyImprovementComparator = new AbstractEAIndividualComparator("", -1, true);
String msg;
public static final boolean hideFromGOE=true; // hide from GUI
public HistoryConvergenceTerminator() {}
public HistoryConvergenceTerminator(int windowLen, double convThreshold, int fitnessCrit, boolean stdDevInsteadOfImprovement) {
haltingWindowLen = windowLen;
convergenceThreshold=convThreshold;
fitCrit = fitnessCrit;
this.stdDevInsteadOfImprovement = stdDevInsteadOfImprovement;
}
public String globalInfo() {
return "Converge based on a halting window on a population history.";
}
public void init(InterfaceOptimizationProblem prob) {
msg = "Not terminated.";
}
public boolean isTerminated(PopulationInterface pop) {
int histLen = (((Population)pop).getHistory()).size();
boolean res = false;
if (histLen >= haltingWindowLen) {
List<AbstractEAIndividual> subHist = ((Population)pop).getHistory().subList(histLen-haltingWindowLen, histLen);
if (stdDevInsteadOfImprovement) { // look at fitness std dev.
double[] fitMeas = Population.getFitnessMeasures(subHist, fitCrit);
res = (fitMeas[3]<convergenceThreshold);
if (res) {
msg="Historic fitness std.dev. below " + convergenceThreshold + " for " + histLen + " generations.";
}
} else { // look at improvements
AbstractEAIndividual historicHWAgo = subHist.get(0);
res = true;
for (int i = 1; i < haltingWindowLen; i++) {
// if historic[-hW] is worse than historic[-hW+i] return false
AbstractEAIndividual historicIter = subHist.get(i);
// if the iterated indy (the later one in history) has improved, there is no convergence.
boolean improvementHappened = (testSecondForImprovement(historicHWAgo, historicIter));
if (improvementHappened) {
res = false;
break;
}
}
if (res) {
msg = "History did not improve" + (convergenceThreshold>0 ? (" by more than " + convergenceThreshold) : "") + " for " + haltingWindowLen + " iterations.";
}
}
}
return res;
}
/**
* Define the criterion by which individual improvement is judged. The original version defined
* improvement strictly, but for some EA this should be done more laxly. E.g. DE will hardly ever
* stop improving slightly, so optionally use an epsilon-bound: improvement only counts if it is
* larger than epsilon in case useEpsilonBound is true.
*
* @param firstIndy
* @param secIndy
* @return true if the second individual has improved in relation to the first one
*/
private boolean testSecondForImprovement(AbstractEAIndividual firstIndy, AbstractEAIndividual secIndy) {
if (convergenceThreshold > 0) {
double fitDiff = (new ObjectiveSpaceMetric()).distance(firstIndy, secIndy);
boolean ret = (secIndy.isDominatingDebConstraints(firstIndy));
ret = ret && (fitDiff > convergenceThreshold); // there is improvement if the second is dominant and the fitness difference is larger than epsilon
return ret;
} else {
return (indyImprovementComparator.compare(firstIndy, secIndy)>0);
}
}
public boolean isTerminated(InterfaceSolutionSet sols) {
return isTerminated(sols.getCurrentPopulation());
}
public String lastTerminationMessage() {
return msg;
}
public int getHaltingWindowLen() {
return haltingWindowLen;
}
public void setHaltingWindowLen(int haltingWindowLen) {
this.haltingWindowLen = haltingWindowLen;
}
public String haltingWindowLenTipText() {
return "Number of generations regarded back in the history";
}
public int getFitCrit() {
return fitCrit;
}
public void setFitCrit(int fitCrit) {
this.fitCrit = fitCrit;
}
public String fitCritTipText() {
return "The index of the fitness criterion regarded (multi-objective case).";
}
public double getConvergenceThreshold() {
return convergenceThreshold;
}
public void setConvergenceThreshold(double convergenceThreshold) {
this.convergenceThreshold = convergenceThreshold;
}
public String convergenceThresholdTipText() {
return "Threshold below improvements (or deviations) are still seen as stagnation.";
}
public boolean isStdDevInsteadOfImprovement() {
return stdDevInsteadOfImprovement;
}
public void setStdDevInsteadOfImprovement(boolean stdDevInsteadOfImprovement) {
this.stdDevInsteadOfImprovement = stdDevInsteadOfImprovement;
}
public String stdDevInsteadOfImprovementTipText() {
return "Look at the standard deviation of historic fitness values instead of absolute fitness.";
}
}

View File

@ -8,16 +8,17 @@ import java.util.List;
import java.util.PriorityQueue; import java.util.PriorityQueue;
import java.util.Set; import java.util.Set;
import eva2.gui.GenericObjectEditor;
import eva2.server.go.IndividualInterface; import eva2.server.go.IndividualInterface;
import eva2.server.go.InterfacePopulationChangedEventListener; import eva2.server.go.InterfacePopulationChangedEventListener;
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.individuals.AbstractEAIndividualComparator; import eva2.server.go.individuals.AbstractEAIndividualComparator;
import eva2.server.go.individuals.GAIndividualBinaryData;
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.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.operators.postprocess.PostProcess;
import eva2.server.go.operators.selection.probability.AbstractSelProb; import eva2.server.go.operators.selection.probability.AbstractSelProb;
import eva2.tools.EVAERROR; import eva2.tools.EVAERROR;
import eva2.tools.Pair; import eva2.tools.Pair;
@ -44,7 +45,6 @@ import eva2.tools.math.Jama.Matrix;
*/ */
public class Population extends ArrayList implements PopulationInterface, Cloneable, java.io.Serializable { public class Population extends ArrayList implements PopulationInterface, Cloneable, java.io.Serializable {
protected int m_Generation = 0; protected int m_Generation = 0;
protected int m_FunctionCalls = 0; protected int m_FunctionCalls = 0;
protected int m_TargetSize = 50; protected int m_TargetSize = 50;
@ -62,13 +62,16 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
public static final String nextGenerationPerformed = "NextGenerationPerformed"; public static final String nextGenerationPerformed = "NextGenerationPerformed";
boolean useHistory = false; boolean useHistory = false;
public ArrayList<AbstractEAIndividual> m_History = new ArrayList<AbstractEAIndividual>(); private transient ArrayList<AbstractEAIndividual> m_History = new ArrayList<AbstractEAIndividual>();
// remember when the last sorted queue was prepared // remember when the last sorted queue was prepared
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 int lastFitCrit = -1;
private AbstractEAIndividualComparator historyComparator = null;
private double[] seedPos = new double[10];
private double aroundDist=0.1;
private transient static boolean TRACE = false; private transient static boolean TRACE = false;
// remember when the last evaluation was performed // remember when the last evaluation was performed
@ -138,6 +141,10 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
} }
} }
public void hideHideable() {
setInitMethod(getInitMethod());
}
public void copyHistAndArchive(Population population) { public void copyHistAndArchive(Population population) {
if (population.m_Archive != null) this.m_Archive = (Population)population.m_Archive.clone(); if (population.m_Archive != null) this.m_Archive = (Population)population.m_Archive.clone();
if (population.m_History != null) this.m_History = (ArrayList<AbstractEAIndividual>)population.m_History.clone(); if (population.m_History != null) this.m_History = (ArrayList<AbstractEAIndividual>)population.m_History.clone();
@ -161,6 +168,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
this.m_TargetSize = population.m_TargetSize; this.m_TargetSize = population.m_TargetSize;
this.useHistory = population.useHistory; this.useHistory = population.useHistory;
this.notifyEvalInterval = population.notifyEvalInterval; this.notifyEvalInterval = population.notifyEvalInterval;
this.initMethod = population.initMethod;
if (population.seedPos!=null) this.seedPos = population.seedPos.clone();
// this.m_Listener = population.m_Listener; // this.m_Listener = population.m_Listener;
if (population.listeners != null) this.listeners = (ArrayList<InterfacePopulationChangedEventListener>)population.listeners.clone(); if (population.listeners != null) this.listeners = (ArrayList<InterfacePopulationChangedEventListener>)population.listeners.clone();
else listeners = null; else listeners = null;
@ -236,22 +245,53 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
case randomLatinHypercube: case randomLatinHypercube:
createRLHSampling(this, false); createRLHSampling(this, false);
break; break;
case aroundSeed:
AbstractEAIndividual template = (AbstractEAIndividual) getEAIndividual(0).clone();
if (template.getDoublePosition().length<=seedPos.length) {
if (template.getDoublePosition().length<seedPos.length) {
double[] smallerSeed = new double[template.getDoublePosition().length];
System.arraycopy(seedPos, 0, smallerSeed, 0, smallerSeed.length);
AbstractEAIndividual.setDoublePosition(template, smallerSeed);
} else AbstractEAIndividual.setDoublePosition(template, seedPos);
PostProcess.createPopInSubRange(this, aroundDist, this.getTargetSize(), template);
} else System.err.println("Warning, skipping seed initialization: too small individual seed!");
break;
} }
firePropertyChangedEvent(Population.populationInitialized); firePropertyChangedEvent(Population.populationInitialized);
} }
public double[] getInitPos() {
return seedPos ;
}
public void setInitPos(double[] si) {
seedPos=si;
}
public String initPosTipText() {
return "Position around which the population will be (randomly) initialized. Be aware that the vector length must match (or exceed) problem dimension!";
}
public void setInitAround(double d) {
aroundDist = d;
}
public double getInitAround() {
return aroundDist;
}
public String initAroundTipText() {
return "Lenght of hypercube within which individuals are initialized around the initial position.";
}
// /** This method inits the population. Function and generation counters // /** This method inits the population. Function and generation counters
// * are reset and m_Size default Individuals are created and initialized by // * are reset and m_Size default Individuals are created and initialized by
// * the GAIndividual default init() method. // * the GAIndividual default init() method.
// */ // */
// public void defaultInit(AbstractEAIndividual template) { Were missing the optimization problem - thus no initial range can be specified. And since no one calls this method, I removed it for now // public void defaultInit(AbstractEAIndividual template) {
// this.m_Generation = 0; // this.m_Generation = 0;
// this.m_FunctionCalls = 0; // this.m_FunctionCalls = 0;
// this.m_Archive = null; // this.m_Archive = null;
// this.clear(); // this.clear();
// for (int i = 0; i < this.m_TargetSize; i++) { // for (int i = 0; i < this.m_TargetSize; i++) {
// AbstractEAIndividual tmpIndy = (AbstractEAIndividual)template.clone(); // AbstractEAIndividual tmpIndy = (AbstractEAIndividual)template.clone();
// tmpIndy.defaultInit(null); // tmpIndy.defaultInit();
// super.add(tmpIndy); // super.add(tmpIndy);
// } // }
// } // }
@ -303,12 +343,38 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
/** /**
* Activate or deactivate the history tracking, which stores the best individual in every * Activate or deactivate the history tracking, which stores the best individual in every
* generation in the incrGeneration() method. * generation in the incrGeneration() method. This uses a default individual comparator
* which is based on fitness.
* *
* @param useHist * @param useHist
*/ */
public void setUseHistory(boolean useHist) { public void setUseHistory(boolean useHist) {
this.setUseHistory(useHist, (useHist ? (new AbstractEAIndividualComparator()) : null));
}
/**
* Activate or deactivate the history tracking, which stores the best individual in every
* generation in the incrGeneration() method.
*
* @param useHist
* @param histComparator comparator to use for determining the best current individual
*/
public void setUseHistory(boolean useHist, AbstractEAIndividualComparator histComparator) {
useHistory = useHist; useHistory = useHist;
this.historyComparator = histComparator;
}
public int getHistoryLength() {
if (useHistory) return m_History.size();
else return 0;
}
public ArrayList<AbstractEAIndividual> getHistory() {
return m_History;
}
public void SetHistory(ArrayList<AbstractEAIndividual> theHist) {
m_History = theHist;
} }
/** This method will allow you to increment the current number of function calls. /** This method will allow you to increment the current number of function calls.
@ -396,7 +462,9 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
* Stagnation measured etc. pp. * Stagnation measured etc. pp.
*/ */
public void incrGeneration() { public void incrGeneration() {
if (useHistory && (this.size() >= 1)) this.m_History.add((AbstractEAIndividual)this.getBestEAIndividual().clone()); if (useHistory && (this.size() >= 1)) {
this.m_History.add((AbstractEAIndividual)this.getBestEAIndividual().clone());// TODO
}
for (int i=0; i<size(); i++) ((AbstractEAIndividual)get(i)).incrAge(); for (int i=0; i<size(); i++) ((AbstractEAIndividual)get(i)).incrAge();
this.m_Generation++; this.m_Generation++;
firePropertyChangedEvent(nextGenerationPerformed); firePropertyChangedEvent(nextGenerationPerformed);
@ -591,9 +659,9 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
* @see getIndexOfBestOrWorstIndividual() * @see getIndexOfBestOrWorstIndividual()
* @return The index of the best individual. * @return The index of the best individual.
*/ */
public int getIndexOfBestIndividual() { public int getIndexOfBestIndividualPrefFeasible() {
if (size()<1) return -1; if (size()<1) return -1;
return getIndexOfBestOrWorstIndividual(true, true, -1); return getIndexOfBestOrWorstIndy(true, true, -1);
} }
/** /**
@ -603,8 +671,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
* @see getIndexOfBestOrWorstIndividual() * @see getIndexOfBestOrWorstIndividual()
* @return The index of the best individual. * @return The index of the best individual.
*/ */
public int getIndexOfWorstIndividual() { public int getIndexOfWorstIndividualNoConstr() {
return getIndexOfBestOrWorstIndividual(false, false, -1); return getIndexOfBestOrWorstIndy(false, false, -1);
} }
/** /**
@ -615,9 +683,9 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
* @see getIndexOfBestOrWorstIndividual() * @see getIndexOfBestOrWorstIndividual()
* @return The index of the best individual. * @return The index of the best individual.
*/ */
public int getIndexOfBestIndividual(int fitIndex) { public int getIndexOfBestIndividualPrefFeasible(int fitIndex) {
if (size()<1) return -1; if (size()<1) return -1;
return getIndexOfBestOrWorstIndividual(true, true, fitIndex); return getIndexOfBestOrWorstIndy(true, true, fitIndex);
} }
/** /**
@ -627,8 +695,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
* @see getIndexOfBestOrWorstIndividual() * @see getIndexOfBestOrWorstIndividual()
* @return The index of the best individual. * @return The index of the best individual.
*/ */
public int getIndexOfWorstIndividual(int fitIndex) { public int getIndexOfWorstIndividualNoConstr(int fitIndex) {
return getIndexOfBestOrWorstIndividual(false, false, fitIndex); return getIndexOfBestOrWorstIndy(false, false, fitIndex);
} }
/** /**
@ -686,49 +754,104 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
* @param indicate whether constraints should be regarded * @param 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, boolean checkConstraints, int fitIndex) { public int getIndexOfBestOrWorstIndividual(boolean bBest, AbstractEAIndividualComparator comparator) {
int result = -1; ArrayList<AbstractEAIndividual> sorted = getSorted(comparator);
double[] curSelFitness = null; if (bBest) return indexOf(sorted.get(0));
boolean allViolate = true; else return indexOfInstance(sorted.get(sorted.size()-1));
for (int i = 0; i < super.size(); i++) {
if (!checkConstraints || !(getEAIndividual(i).violatesConstraint())) {
allViolate = false;
if ((result<0) || (compareFit(bBest, getEAIndividual(i).getFitness(), curSelFitness, fitIndex))) {
// fit i is better than remembered
result = i;
curSelFitness = getEAIndividual(i).getFitness(); // remember fit i
}
}
}
if (result < 0) {
if (checkConstraints && allViolate) {
// darn all seem to violate the constraint
// so lets search for the guy who is close to feasible
// to avoid problems with NaN or infinite fitness value, preselect an ind.
result = 0;
double minViol = getEAIndividual(0).getConstraintViolation();
for (int i = 1; i < super.size(); i++) {
if ((bBest && getEAIndividual(i).getConstraintViolation() < minViol) ||
(!bBest && (getEAIndividual(i).getConstraintViolation() > minViol))) {
result = i;
minViol = ((AbstractEAIndividual)super.get(i)).getConstraintViolation();
}
}
// System.err.println("Population reports: All individuals violate the constraints, choosing smallest constraint violation.");
// this is now really reported nicer...
} else {
// not all violate, maybe all are NaN!
// so just select a random one
System.err.println("Population reports: All individuals seem to have NaN or infinite fitness!");
result = RNG.randomInt(size());
}
}
return result;
} }
public int getIndexOfBestOrWorstIndy(boolean bBest, boolean checkConstraints, int fitIndex) {
return getIndexOfBestOrWorstIndividual(bBest, new AbstractEAIndividualComparator(fitIndex, checkConstraints));
}
/** /**
* Returns the index of the first occurrence of the specified element
* in this list, or -1 if this list does not contain the element.
* This only checks for pointer equality. Different instances which
* have equal properties will be considered different.
*/
public int indexOfInstance(Object o) {
if (o == null) {
System.err.println("Error, instance null should not be contained! (Population.indexOfInstance)");
} else {
for (int i = 0; i < size(); i++) {
if (o==get(i)) {
return i;
}
}
}
return -1;
}
// /**
// * This method will return the index of the current best (worst) individual from the
// * population. If indicated, only those are regarded which do not violate the constraints.
// * If all violate the constraints, the smallest (largest) violation is selected.
// * Comparisons are done multicriterial, but note that for incomparable sets (pareto fronts)
// * this selection will not be fair (always the lowest index of incomparable sets will be returned).
// *
// * @param bBest if true, smallest fitness (regarded best) index is returned, else the highest one
// * @param indicate whether constraints should be regarded
// * @return The index of the best (worst) individual.
// */
// public int getIndexOfBestOrWorstIndividual(boolean bBest, boolean checkConstraints, int fitIndex) {
// int result = -1;
// double[] curSelFitness = null;
// boolean allViolate = true;
//
// for (int i = 0; i < super.size(); i++) {
// if (!checkConstraints || !(getEAIndividual(i).violatesConstraint())) {
// allViolate = false;
// if ((result<0) || (compareFit(bBest, getEAIndividual(i).getFitness(), curSelFitness, fitIndex))) {
// // fit i is better than remembered
// result = i;
// curSelFitness = getEAIndividual(i).getFitness(); // remember fit i
// }
// }
// }
// if (result < 0) {
// if (checkConstraints && allViolate) {
// // darn all seem to violate the constraint
// // so lets search for the guy who is close to feasible
//
// // to avoid problems with NaN or infinite fitness value, preselect an ind.
// result = 0;
// double minViol = getEAIndividual(0).getConstraintViolation();
// for (int i = 1; i < super.size(); i++) {
// if ((bBest && getEAIndividual(i).getConstraintViolation() < minViol) ||
// (!bBest && (getEAIndividual(i).getConstraintViolation() > minViol))) {
// result = i;
// minViol = ((AbstractEAIndividual)super.get(i)).getConstraintViolation();
// }
// }
//// System.err.println("Population reports: All individuals violate the constraints, choosing smallest constraint violation.");
// // this is now really reported nicer...
// } else {
// // not all violate, maybe all are NaN!
// // so just select a random one
// System.err.println("Population reports: All individuals seem to have NaN or infinite fitness!");
// result = RNG.randomInt(size());
// }
// }
// int testcmp = getIndexOfBestOrWorstIndy(bBest, checkConstraints, fitIndex);
// if (result!=testcmp) {
// if (((getEAIndividual(result).getFitness(0)!=getEAIndividual(testcmp).getFitness(0)) && (!violatesConstraints(testcmp) || !violatesConstraints(result)))
// || (violatesConstraints(testcmp) && violatesConstraints(result) && (!equalConstraintViolation(testcmp, result)))) {
// System.err.println("Error in comparison!!! " + getIndexOfBestOrWorstIndy(bBest, checkConstraints, fitIndex));
// }
// } else System.err.println("Succ with " + bBest + " " + checkConstraints + " " + fitIndex);
// return result;
// }
// private boolean equalConstraintViolation(int a, int b) {
// return (getEAIndividual(a).getConstraintViolation()==getEAIndividual(b).getConstraintViolation());
// }
//
// private boolean violatesConstraints(int i) {
// return (getEAIndividual(i).isMarkedPenalized() || getEAIndividual(i).violatesConstraint());
// }
/**
* Search the population for the best (worst) considering the given criterion (or all criteria * Search the population for the best (worst) considering the given criterion (or all criteria
* for fitIndex<0) which also does not violate constraints. * for fitIndex<0) which also does not violate constraints.
* Returns -1 if no feasible solution is found, else the index of the best feasible solution. * Returns -1 if no feasible solution is found, else the index of the best feasible solution.
@ -764,8 +887,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
} }
/** /**
* This method returns the current best individual from the population * This method returns the currently best individual from the population
* by a given fitness component. * by a given fitness component while prioritizing feasible ones.
* If the population is empty, null is returned. * If the population is empty, null is returned.
* *
* @param fitIndex the fitness criterion index or -1 * @param fitIndex the fitness criterion index or -1
@ -773,7 +896,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
*/ */
public AbstractEAIndividual getBestEAIndividual(int fitIndex) { public AbstractEAIndividual getBestEAIndividual(int fitIndex) {
if (size()<1) return null; if (size()<1) return null;
int best = this.getIndexOfBestIndividual(fitIndex); int best = this.getIndexOfBestIndividualPrefFeasible(fitIndex);
if (best == -1) { if (best == -1) {
System.err.println("This shouldnt happen!"); System.err.println("This shouldnt happen!");
return null; return null;
@ -1041,7 +1164,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
} }
public AbstractEAIndividual getWorstEAIndividual(int fitIndex) { public AbstractEAIndividual getWorstEAIndividual(int fitIndex) {
return getEAIndividual(getIndexOfWorstIndividual(fitIndex)); return getEAIndividual(getIndexOfWorstIndividualNoConstr(fitIndex));
} }
/** /**
@ -1135,14 +1258,14 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
this.m_Archive = a; this.m_Archive = a;
} }
/** This method will return a string description of the GAIndividal /**
* noteably the Genotype. * This method will return a string description of the Population
* including the individuals.
* @return A descriptive string * @return A descriptive string
*/ */
public String getStringRepresentation() { public String getStringRepresentation() {
StringBuilder strB = new StringBuilder(200); StringBuilder strB = new StringBuilder(200);
strB.append("Population:\nPopulation size: "); strB.append("Population:\nPopulation size: ");
strB.append("Population size: ");
strB.append(this.size()); strB.append(this.size());
strB.append("\nFunction calls : "); strB.append("\nFunction calls : ");
strB.append(this.m_FunctionCalls); strB.append(this.m_FunctionCalls);
@ -1268,7 +1391,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
modCount++; modCount++;
if (lastFitCrit==fitIndex && (lastQModCount==(modCount-1))) { if (lastFitCrit==fitIndex && (lastQModCount==(modCount-1))) {
// if nothing happend between this event and the last sorting by the same criterion... // if nothing happend between this event and the last sorting by the same criterion...
sortedArr.remove(prev); if (!sortedArr.remove(prev)) System.err.println("Error in Population.set!");
int i=0; int i=0;
AbstractEAIndividualComparator comp = new AbstractEAIndividualComparator(fitIndex); AbstractEAIndividualComparator comp = new AbstractEAIndividualComparator(fitIndex);
while (i<sortedArr.size() && comp.compare(element, sortedArr.get(i))>0) { while (i<sortedArr.size() && comp.compare(element, sortedArr.get(i))>0) {
@ -1310,15 +1433,30 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
return (IndividualInterface)set(index, ind); return (IndividualInterface)set(index, ind);
} }
public void removeIndividual (IndividualInterface ind) { /**
*
* @param ind
* @return true if an indy was actually removed, else false
*/
public boolean removeMember(IndividualInterface ind) {
long id = ((AbstractEAIndividual)ind).getIndyID();
for (int i = 0; i < this.size(); i++) { for (int i = 0; i < this.size(); i++) {
if (ind.equals(this.get(i))) { if (getEAIndividual(i).getIndyID()==id) {
this.remove(i); removeIndexSwitched(i);
return; return true;
} }
} }
return false;
} }
public void removeMembers(Population tmpPop, boolean errorOnMissing) {
for (int i=0; i<tmpPop.size(); i++) {
if (!removeMember(tmpPop.getEAIndividual(i))) {
if (errorOnMissing) throw new RuntimeException("Error, member to be removed was missing (Population.removeMembers)!");
}
}
}
public IndividualInterface getBestIndividual() { public IndividualInterface getBestIndividual() {
return (IndividualInterface)this.getBestEAIndividual(); return (IndividualInterface)this.getBestEAIndividual();
} }
@ -1382,7 +1520,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
// } // }
// return measures; // return measures;
// } // }
double[] res = calcPopulationMeasures(metric); double[] res = getPopulationMeasures(this, metric);
// putData(lastPopMeasuresFlagKey, new Integer(modCount)); // putData(lastPopMeasuresFlagKey, new Integer(modCount));
// putData(lastPopMeasuresDatKey, res); // putData(lastPopMeasuresDatKey, res);
// System.out.println(getStringRepresentation()); // System.out.println(getStringRepresentation());
@ -1390,34 +1528,34 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
return res; return res;
} }
private double[] calcPopulationMeasures(InterfaceDistanceMetric metric) { public static double[] getPopulationMeasures(List<AbstractEAIndividual> pop, InterfaceDistanceMetric metric) {
double d; double d;
double[] res = new double[3]; double[] res = new double[3];
double meanDist = 0.; double distSum = 0.;
double maxDist = Double.MIN_VALUE; double maxDist = Double.MIN_VALUE;
double minDist = Double.MAX_VALUE; double minDist = Double.MAX_VALUE;
for (int i = 0; i < this.size(); i++) { for (int i = 0; i < pop.size(); i++) {
for (int j = i+1; j < this.size(); j++) { for (int j = i+1; j < pop.size(); j++) {
if (metric == null) d = EuclideanMetric.euclideanDistance(AbstractEAIndividual.getDoublePositionShallow(getEAIndividual(i)), if (metric == null) d = EuclideanMetric.euclideanDistance(AbstractEAIndividual.getDoublePositionShallow(pop.get(i)),
AbstractEAIndividual.getDoublePositionShallow(getEAIndividual(j))); AbstractEAIndividual.getDoublePositionShallow(pop.get(j)));
else d = metric.distance((AbstractEAIndividual)this.get(i), (AbstractEAIndividual)this.get(j)); else d = metric.distance((AbstractEAIndividual)pop.get(i), (AbstractEAIndividual)pop.get(j));
meanDist += d; distSum += d;
if (d < minDist) minDist = d; if (d < minDist) minDist = d;
if (d > maxDist) maxDist = d; if (d > maxDist) maxDist = d;
} }
} }
res[1] = minDist; res[1] = minDist;
res[2] = maxDist; res[2] = maxDist;
if (this.size() > 1) res[0] = meanDist / (this.size() * (this.size()-1) / 2); if (pop.size() > 1) res[0] = distSum / (pop.size() * (pop.size()-1) / 2);
else { // only one indy? else { // only one indy?
res[1]=0; res[1]=0;
res[2]=0; res[2]=0;
} }
return res; return res;
} }
/** /**
* Returns the average, minimal and maximal individual fitness and std dev. for the population in the given criterion. * Returns the average, minimal and maximal individual fitness and std dev. for the population in the given criterion.
* *
@ -1425,6 +1563,16 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
* @return the average, minimal, maximal and std dev. of fitness of individuals in an array * @return the average, minimal, maximal and std dev. of fitness of individuals in an array
*/ */
public double[] getFitnessMeasures(int fitCrit) { public double[] getFitnessMeasures(int fitCrit) {
return Population.getFitnessMeasures(this, fitCrit);
}
/**
* Returns the average, minimal and maximal individual fitness and std dev. for the population in the given criterion.
*
* @param fitCrit fitness dimension to be used
* @return the average, minimal, maximal and std dev. of fitness of individuals in an array
*/
public static double[] getFitnessMeasures(List<AbstractEAIndividual> pop, int fitCrit) {
double d; double d;
double[] res = new double[4]; double[] res = new double[4];
@ -1433,23 +1581,23 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
res[2] = Double.MIN_VALUE; res[2] = Double.MIN_VALUE;
res[3] = 0; res[3] = 0;
for (int i = 0; i < this.size(); i++) { for (int i = 0; i < pop.size(); i++) {
d = this.getEAIndividual(i).getFitness(fitCrit); d = pop.get(i).getFitness(fitCrit);
res[0] += d; res[0] += d;
if (d < res[1]) res[1] = d; if (d < res[1]) res[1] = d;
if (d > res[2]) res[2] = d; if (d > res[2]) res[2] = d;
} }
if (size()==0) { if (pop.size()==0) {
res[0]=res[1]=res[2]=res[3]=Double.NaN; res[0]=res[1]=res[2]=res[3]=Double.NaN;
} else { } else {
// calc standard deviation // calc standard deviation
res[0] = res[0] / this.size(); res[0] = res[0] / pop.size();
for (int i=0; i< this.size(); i++) { for (int i=0; i< pop.size(); i++) {
d = res[0]-this.getEAIndividual(i).getFitness(fitCrit); d = res[0]-pop.get(i).getFitness(fitCrit);
res[3]+=d*d; res[3]+=d*d;
} }
res[3] /= this.size(); res[3] /= pop.size();
res[3] = Math.sqrt(res[3]); res[3] = Math.sqrt(res[3]);
} }
@ -1564,33 +1712,33 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
} }
/** /**
* Search for the closest individual which is not equal to the given individual. Return * Search for the closest individual to the indexed individual within the population. Return
* its index or -1 if none could be found. * its index or -1 if none could be found.
* *
* @param indy * @param indy
* @return closest neighbor (euclidian measure) of the given individual in the given population * @return closest neighbor (euclidian measure) of the given individual in the given population
*/ */
public int getNeighborIndex(AbstractEAIndividual indy) { public int getNeighborIndex(int neighborIndex) {
// get the neighbor... // get the neighbor...
int index = -1; int foundIndex = -1;
double mindist = Double.POSITIVE_INFINITY; double mindist = Double.POSITIVE_INFINITY;
for (int i = 0; i < size(); ++i){ for (int i = 0; i < size(); ++i){
AbstractEAIndividual currentindy = getEAIndividual(i); AbstractEAIndividual currentindy = getEAIndividual(i);
if (!indy.equals(currentindy)){ // dont compare particle to itself or a copy of itself if (i!=neighborIndex){ // dont compare particle to itself or a copy of itself
double dist = EuclideanMetric.euclideanDistance(AbstractEAIndividual.getDoublePositionShallow(indy), double dist = EuclideanMetric.euclideanDistance(AbstractEAIndividual.getDoublePositionShallow(getEAIndividual(neighborIndex)),
AbstractEAIndividual.getDoublePositionShallow(currentindy)); AbstractEAIndividual.getDoublePositionShallow(currentindy));
if (dist < mindist){ if (dist < mindist){
mindist = dist; mindist = dist;
index = i; foundIndex = i;
} }
} }
} }
if (index == -1){ if (foundIndex == -1){
System.err.println("Pop too small or all individuals in population are equal !?"); System.err.println("Pop too small or all individuals in population are equal !?");
return -1; return -1;
} }
return index; return foundIndex;
} }
/** /**
@ -1609,7 +1757,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
double d=0; double d=0;
for (int i = 0; i < size(); ++i){ for (int i = 0; i < size(); ++i){
AbstractEAIndividual neighbor, indy = getEAIndividual(i); AbstractEAIndividual neighbor, indy = getEAIndividual(i);
int neighborIndex = getNeighborIndex(indy); int neighborIndex = getNeighborIndex(i);
if (neighborIndex >= 0) neighbor = getEAIndividual(neighborIndex); if (neighborIndex >= 0) neighbor = getEAIndividual(neighborIndex);
else return null; else return null;
if (normalizedPhenoMetric){ if (normalizedPhenoMetric){
@ -1719,6 +1867,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
public void setInitMethod(PopulationInitMethod initMethod) { public void setInitMethod(PopulationInitMethod initMethod) {
this.initMethod = initMethod; this.initMethod = initMethod;
GenericObjectEditor.setShowProperty(this.getClass(), "initAround", initMethod==PopulationInitMethod.aroundSeed);
GenericObjectEditor.setShowProperty(this.getClass(), "initPos", initMethod==PopulationInitMethod.aroundSeed);
} }
public String initMethodTipText() { public String initMethodTipText() {
@ -1792,6 +1942,16 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
return Math.max(0, this.getTargetSize() - this.size()); return Math.max(0, this.getTargetSize() - this.size());
} }
public boolean assertMembers(Population pop) {
for (int i=0; i<pop.size(); i++) {
if (!isMemberByID(pop.getEAIndividual(i))) {
System.err.println("Warning, indy " + i + " is not a member of " + this);
return false;
}
}
return true;
}
// /** // /**
// * Mark the population at the current state as evaluated. Changes to the modCount or hashes of individuals // * Mark the population at the current state as evaluated. Changes to the modCount or hashes of individuals
// * will invalidate the mark. // * will invalidate the mark.

View File

@ -1,5 +1,5 @@
package eva2.server.go.populations; package eva2.server.go.populations;
public enum PopulationInitMethod { public enum PopulationInitMethod {
individualDefault, randomLatinHypercube; individualDefault, randomLatinHypercube, aroundSeed;
} }

View File

@ -99,6 +99,7 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
this.m_GlobalOpt = Double.NEGATIVE_INFINITY; this.m_GlobalOpt = Double.NEGATIVE_INFINITY;
m_ListOfOptima = new Population(); m_ListOfOptima = new Population();
this.initListOfOptima(); this.initListOfOptima();
if (!fullListAvailable() && (Double.isInfinite(m_GlobalOpt))) m_GlobalOpt=0;
} }
/** Ths method allows you to evaluate a simple bit string to determine the fitness /** Ths method allows you to evaluate a simple bit string to determine the fitness
@ -106,6 +107,7 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
* @return The m-dimensional output vector. * @return The m-dimensional output vector.
*/ */
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] result = new double[1]; double[] result = new double[1];
result[0] = this.m_GlobalOpt - evalUnnormalized(x)[0]; result[0] = this.m_GlobalOpt - evalUnnormalized(x)[0];
return result; return result;
@ -124,7 +126,7 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
* @return String * @return String
*/ */
public String getAdditionalFileStringHeader(PopulationInterface pop) { public String getAdditionalFileStringHeader(PopulationInterface pop) {
return "#Optima found \t Maximum Peak Ratio"; return "#Optima found \tMaximum Peak Ratio \t" + super.getAdditionalFileStringHeader(pop);
} }
/** /**
@ -137,7 +139,7 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
// result += AbstractEAIndividual.getDefaultDataString(pop.getBestIndividual()) +"\t"; // result += AbstractEAIndividual.getDefaultDataString(pop.getBestIndividual()) +"\t";
result += this.getNumberOfFoundOptima((Population)pop)+"\t"; result += this.getNumberOfFoundOptima((Population)pop)+"\t";
result += this.getMaximumPeakRatio((Population)pop); result += this.getMaximumPeakRatio((Population)pop);
return result; return result +"\t"+ super.getAdditionalFileStringValue(pop);
} }
// //
// /** This method returns a string describing the optimization problem. // /** This method returns a string describing the optimization problem.
@ -212,6 +214,14 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
public Population getRealOptima() { public Population getRealOptima() {
return this.m_ListOfOptima; return this.m_ListOfOptima;
} }
/**
* Return true if the full list of optima is available, else false.
* @return
*/
public boolean fullListAvailable() {
return ((getRealOptima()!=null) && (getRealOptima().size()>0));
}
/** This method returns the Number of Identified optima /** This method returns the Number of Identified optima
* @param pop A population of possible solutions. * @param pop A population of possible solutions.
@ -222,7 +232,7 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
} }
public static int getNoFoundOptimaOf(InterfaceMultimodalProblemKnown mmProb, Population pop) { public static int getNoFoundOptimaOf(InterfaceMultimodalProblemKnown mmProb, Population pop) {
List<AbstractEAIndividual> sols = PostProcess.getFoundOptima(pop, mmProb.getRealOptima(), mmProb.getEpsilon(), true); List<AbstractEAIndividual> sols = PostProcess.getFoundOptima(pop, mmProb.getRealOptima(), mmProb.getDefaultAccuracy(), true);
return sols.size(); return sols.size();
} }
@ -241,9 +251,19 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
return getMaximumPeakRatio(this, pop, m_Epsilon); return getMaximumPeakRatio(this, pop, m_Epsilon);
} }
/**
* Returns -1 if the full list is not available. Otherwise calculates the maximum peak ratio
* based on the full list of known optima.
*
* @param mmProb
* @param pop
* @param epsilon
* @return
*/
public static double getMaximumPeakRatio(InterfaceMultimodalProblemKnown mmProb, Population pop, double epsilon) { public static double getMaximumPeakRatio(InterfaceMultimodalProblemKnown mmProb, Population pop, double epsilon) {
double foundInvertedSum = 0, sumRealMaxima = 0; double foundInvertedSum = 0, sumRealMaxima = 0;
Population realOpts = mmProb.getRealOptima(); if (!mmProb.fullListAvailable()) return -1;
Population realOpts = mmProb.getRealOptima();
double tmp, maxOpt = realOpts.getEAIndividual(0).getFitness(0); double tmp, maxOpt = realOpts.getEAIndividual(0).getFitness(0);
sumRealMaxima = maxOpt; sumRealMaxima = maxOpt;
for (int i=1; i<realOpts.size(); i++) { for (int i=1; i<realOpts.size(); i++) {
@ -306,23 +326,23 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
// return range; // return range;
// } // }
/** // /**
* @return the m_Epsilon // * @return the m_Epsilon
*/ // */
public double getEpsilon() { // public double getEpsilon() {
return m_Epsilon; // return m_Epsilon;
} // }
/** /**
* @param epsilon the m_Epsilon to set * @param epsilon the m_Epsilon to set
*/ */
public void setEpsilon(double epsilon) { public void setDefaultAccuracy(double epsilon) {
m_Epsilon = epsilon; super.SetDefaultAccuracy(epsilon);
}
public String epsilonTipText() {
return "Epsilon criterion indicating whether an optimum was found";
} }
//
// public String epsilonTipText() {
// return "Epsilon criterion indicating whether an optimum was found";
// }
@Override @Override
public int getProblemDimension() { public int getProblemDimension() {

View File

@ -1,11 +1,11 @@
package eva2.server.go.problems; package eva2.server.go.problems;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.io.Serializable;
import java.util.Vector;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import java.io.Serializable;
import java.util.Vector;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JPanel; import javax.swing.JPanel;
@ -17,12 +17,16 @@ import eva2.server.go.PopulationInterface;
import eva2.server.go.enums.PostProcessMethod; import eva2.server.go.enums.PostProcessMethod;
import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeDouble; import eva2.server.go.individuals.InterfaceDataTypeDouble;
import eva2.server.go.operators.cluster.ClusteringDensityBased;
import eva2.server.go.operators.cluster.InterfaceClustering;
import eva2.server.go.operators.distancemetric.IndividualDataMetric;
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.operators.moso.MOSONoConvert; import eva2.server.go.operators.moso.MOSONoConvert;
import eva2.server.go.operators.mutation.InterfaceMutation; import eva2.server.go.operators.mutation.InterfaceMutation;
import eva2.server.go.operators.mutation.MutateESFixedStepSize; import eva2.server.go.operators.mutation.MutateESFixedStepSize;
import eva2.server.go.operators.postprocess.PostProcess; import eva2.server.go.operators.postprocess.PostProcess;
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;
@ -37,7 +41,8 @@ import eva2.tools.math.Mathematics;
* Time: 13:40:12 * Time: 13:40:12
* To change this template use Options | File Templates. * To change this template use Options | File Templates.
*/ */
public abstract class AbstractOptimizationProblem implements InterfaceOptimizationProblem /*, InterfaceParamControllable*/, Serializable { public abstract class AbstractOptimizationProblem
implements InterfaceOptimizationProblem /*, InterfaceParamControllable*/, Serializable {
class EvalThread extends Thread { class EvalThread extends Thread {
AbstractOptimizationProblem prob; AbstractOptimizationProblem prob;
AbstractEAIndividual ind; AbstractEAIndividual ind;
@ -71,6 +76,8 @@ public abstract class AbstractOptimizationProblem implements InterfaceOptimizati
protected AbstractEAIndividual m_Template; protected AbstractEAIndividual m_Template;
// private transient ArrayList<ParamChangeListener> changeListeners = null; // private transient ArrayList<ParamChangeListener> changeListeners = null;
private double defaultAccuracy = 0.01; // default accuracy for identifying optima.
/** This method returns a deep clone of the problem. /** This method returns a deep clone of the problem.
* @return the clone * @return the clone
*/ */
@ -88,7 +95,9 @@ public abstract class AbstractOptimizationProblem implements InterfaceOptimizati
return "Set the number of threaded parallel function evaluations - interesting for slow functions and generational optimizers."; return "Set the number of threaded parallel function evaluations - interesting for slow functions and generational optimizers.";
} }
/** This method inits the Problem to log multiruns /**
* This method initializes the problem instance.
* If you override it, make sure to call the super method!
*/ */
public abstract void initProblem(); public abstract void initProblem();
@ -231,8 +240,8 @@ public abstract class AbstractOptimizationProblem implements InterfaceOptimizati
* @return String * @return String
*/ */
public String getAdditionalFileStringHeader(PopulationInterface pop) { public String getAdditionalFileStringHeader(PopulationInterface pop) {
return "Solution"; if (this instanceof InterfaceInterestingHistogram) return "Solution \t Histogram(c0) \t Score";
// return ""; else return "Solution";
} }
/** This method returns the additional data that is to be written into a file /** This method returns the additional data that is to be written into a file
@ -240,8 +249,12 @@ public abstract class AbstractOptimizationProblem implements InterfaceOptimizati
* @return String * @return String
*/ */
public String getAdditionalFileStringValue(PopulationInterface pop) { public String getAdditionalFileStringValue(PopulationInterface pop) {
// return ""; String solStr = AbstractEAIndividual.getDefaultDataString(pop.getBestIndividual());
return AbstractEAIndividual.getDefaultDataString(pop.getBestIndividual()); if (this instanceof InterfaceInterestingHistogram) {
SolutionHistogram hist = ((InterfaceInterestingHistogram)this).getHistogram();
Population sols = PostProcess.clusterBestUpdateHistogram((Population)pop, this, hist, 0, getDefaultAccuracy());
return solStr + " \t " + hist + "\t" + hist.getScore();
} else return solStr;
} }
/** /**
@ -328,21 +341,27 @@ public abstract class AbstractOptimizationProblem implements InterfaceOptimizati
* @param epsilonPhenoSpace maximal allowed improvement of an individual before considered premature (given as distance in the search space) * @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 epsilonFitConv if positive: additional absolute convergence criterion (fitness space) as termination criterion of the local search
* @param clusterSigma minimum cluster distance * @param clusterSigma minimum cluster distance
* @param numOfFailures * @param maxEvalsPerIndy
* @see #isPotentialOptimumNMS(AbstractEAIndividual, double, double, int) * @see #isPotentialOptimumNMS(AbstractEAIndividual, double, double, int)
* @return * @return
*/ */
public Population extractPotentialOptima(Population pop, double epsilonPhenoSpace, double epsilonFitConv, double clusterSigma, int numOfFailures) { public static Population extractPotentialOptima(AbstractOptimizationProblem prob, Population pop, double epsilonPhenoSpace, double epsilonFitConv, double clusterSigma, int maxEvalsPerIndy) {
Population potOptima = new Population(); Population potOptima = new Population();
for (int i = 0; i < pop.size(); ++i){ for (int i = 0; i < pop.size(); ++i){
AbstractEAIndividual indy = pop.getEAIndividual(i); AbstractEAIndividual indy = pop.getEAIndividual(i);
// System.out.println("bef: " + indy.toString()); // System.out.println("bef: " + indy.toString());
if (isPotentialOptimumNMS(indy, epsilonPhenoSpace, epsilonFitConv, numOfFailures)){ boolean isConverged = AbstractOptimizationProblem.isPotentialOptimumNMS(prob, indy, epsilonPhenoSpace, epsilonFitConv, maxEvalsPerIndy);
// if (isPotentialOptimum(indy, epsilon,-1,-1)){ if (isConverged) {
potOptima.addIndividual(indy); potOptima.addIndividual(indy);
if (!indy.hasData(PostProcess.movedDistanceKey)) {
System.err.println("Error, missing distance information in individual (AbstractOptimizationProblem.extractPotentialOptimum)");
}
} }
} }
if (clusterSigma > 0) return (Population)PostProcess.clusterBest(potOptima, clusterSigma, 0, PostProcess.KEEP_LONERS, PostProcess.BEST_ONLY).clone(); // cluster by the converged-to positions instead of the original ones
InterfaceClustering clustering = new ClusteringDensityBased(clusterSigma, 2, new IndividualDataMetric(PostProcess.movedToPositionKey));
clustering = new ClusteringDensityBased(clusterSigma, 2);
if (clusterSigma > 0) return (Population)PostProcess.clusterBest(potOptima, clustering, 0, PostProcess.KEEP_LONERS, PostProcess.BEST_ONLY).clone();
else return potOptima; else return potOptima;
} }
@ -407,31 +426,33 @@ public abstract class AbstractOptimizationProblem implements InterfaceOptimizati
/** /**
* Refine a given individual using Nelder-Mead-Simplex local search. Return true, if the refined result is within a given * Refine a given individual using Nelder-Mead-Simplex local search. Return true, if the refined result is within a given
* distance from the original individual in phenotype space. The numOfFailures parameter gives the maximum evaluations * distance from the original individual in phenotype space. The maxEvaluations parameter gives the maximum evaluations
* for the local search Using the epsilonFitConv parameter may define a convergence criterion as PhenotypeConvergenceTerminator * 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. * which is combined (using OR) with the evaluation counter.
* If numOfFailures 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, 100*dim is used. Be aware that this may cost quite some runtime depending on the target
* function. * function.
* A double value for the distance by which it was moved is added to the individual using the key PostProcess.movedDistanceKey.
* *
* @param orig * @param orig
* @param epsilonPhenoSpace * @param epsilonPhenoSpace allowed distance for a solution moved by local search
* @param epsilonFitConv * @param epsilonFitConv if the fitness changes below the threshold, the search is stopped earlier. Set to -1 to deactivate.
* @param numOfFailures * @param maxEvaluations maximal number of evaluations or -1
* @return * @return
*/ */
public boolean isPotentialOptimumNMS(AbstractEAIndividual orig, double epsilonPhenoSpace, double epsilonFitConv, int numOfFailures){ public static boolean isPotentialOptimumNMS(AbstractOptimizationProblem prob, AbstractEAIndividual orig, double epsilonPhenoSpace, double epsilonFitConv, int maxEvaluations){
AbstractEAIndividual indy = (AbstractEAIndividual)orig.clone(); AbstractEAIndividual indy = (AbstractEAIndividual)orig.clone();
this.evaluate(indy); // indy may be evaluated in a normalised way... prob.evaluate(indy); // indy may be evaluated in a normalised way...
InterfaceDistanceMetric metric = new PhenotypeMetric(); InterfaceDistanceMetric metric = new PhenotypeMetric();
double overallDist = 0; double overallDist = 0;
double initPerturb = -1; double initRelPerturb = -1;
int dim = -1; int dim = -1;
if (orig instanceof InterfaceDataTypeDouble) { if (orig instanceof InterfaceDataTypeDouble) {
initPerturb = epsilonPhenoSpace/(2*(Mathematics.getAvgRange(((InterfaceDataTypeDouble)orig).getDoubleRange()))); // initPerturb = epsilonPhenoSpace/(2*(Mathematics.getAvgRange(((InterfaceDataTypeDouble)orig).getDoubleRange())));
initRelPerturb = epsilonPhenoSpace*0.5;
dim=((InterfaceDataTypeDouble)orig).getDoubleRange().length; dim=((InterfaceDataTypeDouble)orig).getDoubleRange().length;
if (numOfFailures<0) numOfFailures = 100*AbstractEAIndividual.getDoublePositionShallow(this.m_Template).length; // scales the effort with the number of problem dimensions if (maxEvaluations<0) maxEvaluations = 100*AbstractEAIndividual.getDoublePositionShallow(prob.m_Template).length; // scales the effort with the number of problem dimensions
} else { } else {
System.err.println("Cannot initialize NMS on non-double valued individuals!"); System.err.println("Cannot initialize NMS on non-double valued individuals!");
return false; return false;
@ -439,14 +460,31 @@ public abstract class AbstractOptimizationProblem implements InterfaceOptimizati
Population pop = new Population(1); Population pop = new Population(1);
pop.add(orig); pop.add(orig);
InterfaceTerminator term = new EvaluationTerminator(numOfFailures); 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, 10*dim, true, true), term, false);
int evalsPerf = PostProcess.processSingleCandidatesNMCMA(PostProcessMethod.nelderMead, pop, term, initPerturb, this); 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("aft: " + pop.getBestEAIndividual().toString() + ", evals performed: " + evalsPerf + ", opt moved by " + overallDist); // System.out.println("aft: " + pop.getBestEAIndividual().toString() + ", evals performed: " + evalsPerf + ", opt moved by " + overallDist);
// System.out.println("terminated because: " + term.lastTerminationMessage()); // System.out.println("terminated because: " + term.lastTerminationMessage());
if (overallDist < epsilonPhenoSpace) return true; orig.putData(PostProcess.movedDistanceKey, overallDist);
else return false; orig.putData(PostProcess.movedToPositionKey, pop.getBestEAIndividual().getDoublePosition());
// if (overallDist==0) {
// PostProcess.processSingleCandidatesNMCMA(PostProcessMethod.nelderMead, pop, term, initPerturb, this);
// }
return (overallDist < epsilonPhenoSpace);
}
public double getDefaultAccuracy() {
return defaultAccuracy ;
}
public void SetDefaultAccuracy(double defAcc) {
defaultAccuracy = defAcc;
}
public void setDefaultAccuracy(double defAcc) {
defaultAccuracy = defAcc;
}
public String defaultAccuracyTipText() {
return "A default threshold to identify optima - e.g. the assumed minimal distance between any two optima.";
} }
// /********************************************************************************************************************** // /**********************************************************************************************************************

View File

@ -2,6 +2,7 @@ package eva2.server.go.problems;
import eva2.gui.BeanInspector; import eva2.gui.BeanInspector;
import eva2.gui.GenericObjectEditor; import eva2.gui.GenericObjectEditor;
import eva2.gui.TopoPlot;
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.individuals.ESIndividualDoubleData; import eva2.server.go.individuals.ESIndividualDoubleData;
@ -11,7 +12,10 @@ import eva2.server.go.operators.constraint.GenericConstraint;
import eva2.server.go.populations.Population; import eva2.server.go.populations.Population;
import eva2.server.go.strategies.InterfaceOptimizer; import eva2.server.go.strategies.InterfaceOptimizer;
import eva2.tools.Pair; import eva2.tools.Pair;
import eva2.tools.diagram.ColorBarCalculator;
import eva2.tools.math.Mathematics;
import eva2.tools.math.RNG; import eva2.tools.math.RNG;
import eva2.tools.math.Jama.Matrix;
/** /**
* For a double valued problem, there are two main methods to implement: {@link #getProblemDimension()} * For a double valued problem, there are two main methods to implement: {@link #getProblemDimension()}
@ -37,10 +41,14 @@ import eva2.tools.math.RNG;
public abstract class AbstractProblemDouble extends AbstractOptimizationProblem implements InterfaceProblemDouble, Interface2DBorderProblem/*, InterfaceParamControllable */{ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem implements InterfaceProblemDouble, Interface2DBorderProblem/*, InterfaceParamControllable */{
private double m_DefaultRange = 10; private double m_DefaultRange = 10;
private double m_Noise = 0; private double m_Noise = 0;
private boolean doRotation = false; // should really be false by default
private Matrix rotation;
// PropertySelectableList<AbstractConstraint> constraintList = new PropertySelectableList<AbstractConstraint>(new AbstractConstraint[]{new GenericConstraint()}); // PropertySelectableList<AbstractConstraint> constraintList = new PropertySelectableList<AbstractConstraint>(new AbstractConstraint[]{new GenericConstraint()});
private AbstractConstraint[] constraintArray = new AbstractConstraint[]{new GenericConstraint()}; private AbstractConstraint[] constraintArray = new AbstractConstraint[]{new GenericConstraint()};
private boolean withConstraints = false; private boolean withConstraints = false;
private transient boolean isShowing = false;
private double rotAngle = 22.5; // for default rotation along every axis
public static String rawFitKey="UnconstrainedFitnessValue"; public static String rawFitKey="UnconstrainedFitnessValue";
public AbstractProblemDouble() { public AbstractProblemDouble() {
@ -66,12 +74,16 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
protected void cloneObjects(AbstractProblemDouble o) { protected void cloneObjects(AbstractProblemDouble o) {
this.m_DefaultRange = o.m_DefaultRange; this.m_DefaultRange = o.m_DefaultRange;
this.m_Noise = o.m_Noise; this.m_Noise = o.m_Noise;
this.SetDefaultAccuracy(o.getDefaultAccuracy());
if (o.m_Template != null) this.m_Template = (AbstractEAIndividual)o.m_Template.clone(); if (o.m_Template != null) this.m_Template = (AbstractEAIndividual)o.m_Template.clone();
if (o.constraintArray!=null) { if (o.constraintArray!=null) {
this.constraintArray=o.constraintArray.clone(); this.constraintArray=o.constraintArray.clone();
for (int i=0; i<constraintArray.length; i++) constraintArray[i]=(AbstractConstraint)o.constraintArray[i].clone(); for (int i=0; i<constraintArray.length; i++) constraintArray[i]=(AbstractConstraint)o.constraintArray[i].clone();
} }
this.withConstraints=o.withConstraints; this.withConstraints=o.withConstraints;
this.doRotation = o.doRotation;
this.rotation = (Matrix)o.rotation.clone();
this.rotAngle = o.rotAngle;
} }
/** /**
@ -111,6 +123,14 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
addConstraints(individual, x); addConstraints(individual, x);
} }
} }
protected double[] rotateMaybe(double[] x) {
if (isDoRotation()) {
if (rotation==null) initProblem();
x = Mathematics.rotate(x, rotation);
}
return x;
}
/** /**
* Add all constraint violations to the individual. Expect that the fitness has already been set. * Add all constraint violations to the individual. Expect that the fitness has already been set.
@ -140,6 +160,8 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
/** /**
* Evaluate a double vector, representing the target function. * Evaluate a double vector, representing the target function.
* If you implement this, you should take care of the offsets and rotation,
* e.g. by using x=rotateMaybe(x) before further evaluation.
* *
* @param x the vector to evaluate * @param x the vector to evaluate
* @return the target function value * @return the target function value
@ -202,6 +224,28 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
@Override @Override
public void initProblem() { public void initProblem() {
initTemplate(); initTemplate();
if (isDoRotation()) {
rotation = initDefaultRotationMatrix(rotAngle , getProblemDimension());
} else rotation = null;
}
/**
* Initialize rotation matrix which rotates around the given angle in every axis.
*
* @param rotAngle
* @param dim
* @return
*/
public static Matrix initDefaultRotationMatrix(double rotAngle, int dim) {
Matrix rotation=null;
// Matrix vec = new Matrix(dim, 1);
// for (int i=0; i<dim; i++) vec.set(i,0, i+1);
// System.out.println(BeanInspector.toString(eval(vec.getColumnPackedCopy())));
// 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())));
return rotation;
} }
/** /**
@ -267,6 +311,17 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
return "Absolute limit for the symmetric range in any dimension"; return "Absolute limit for the symmetric range in any dimension";
} }
public void setDoRotation(boolean doRotation) {
this.doRotation = doRotation;
if (!doRotation) rotation=null;
}
public boolean isDoRotation() {
return doRotation;
}
public String doRotationTipText() {
return "If marked, the function is rotated by 22.5 degrees along every axis.";
}
/********************************************************************************************************************** /**********************************************************************************************************************
* These are for InterfaceParamControllable * These are for InterfaceParamControllable
*/ */
@ -388,4 +443,19 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
} }
return new Pair<Integer,Double>(numViol, sum); return new Pair<Integer,Double>(numViol, sum);
} }
public boolean isShowPlot() {
return isShowing ;
}
public void setShowPlot(boolean showP) {
if (!isShowing && showP) {
TopoPlot plot = new TopoPlot(getName(), "x1", "x2");
plot.setParams(60,60, ColorBarCalculator.BLUE_TO_RED);
plot.setTopology(this, makeRange(), true);
}
isShowing = showP;
}
public String showPlotTipText() {
return "Produce an exemplary 2D plot of the function (dimensional cut at x_i=0 for n>1).";
}
} }

View File

@ -39,13 +39,6 @@ public abstract class AbstractProblemDoubleOffset extends AbstractProblemDouble
setDefaultRange(defRange); setDefaultRange(defRange);
} }
/** This method inits the Problem to log multiruns
*/
public void initProblem() {
// this.m_OverallBest = null;
initTemplate();
}
/********************************************************************************************************************** /**********************************************************************************************************************
* These are for GUI * These are for GUI
*/ */

View File

@ -51,6 +51,7 @@ public class ConstrHimmelblauProblem extends AbstractProblemDouble implements Se
@Override @Override
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double v=5.3578547*x[2]*x[2]+0.8356891*x[0]*x[4]+37.293239*x[0]-40792.141; double v=5.3578547*x[2]*x[2]+0.8356891*x[0]*x[4]+37.293239*x[0]-40792.141;
if (useYOffset) v+=yOffset; if (useYOffset) v+=yOffset;
return new double[]{v}; return new double[]{v};

View File

@ -37,6 +37,7 @@ public class F10Problem extends AbstractProblemDoubleOffset implements Interface
* @return The m-dimensional output vector. * @return The m-dimensional output vector.
*/ */
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] result = new double[1]; double[] result = new double[1];
double c1 = this.calculateC(1); double c1 = this.calculateC(1);
result[0] = m_YOffSet; result[0] = m_YOffSet;

View File

@ -39,6 +39,7 @@ public class F11Problem extends AbstractProblemDoubleOffset implements Interface
* @return The m-dimensional output vector. * @return The m-dimensional output vector.
*/ */
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] result = new double[1]; double[] result = new double[1];
double tmpProd = 1; double tmpProd = 1;
for (int i = 0; i < x.length; i++) { for (int i = 0; i < x.length; i++) {

View File

@ -34,13 +34,14 @@ public class F12Problem extends AbstractProblemDoubleOffset implements java.io.S
* @return The m-dimensional output vector. * @return The m-dimensional output vector.
*/ */
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] result = new double[1]; double[] result = new double[1];
double tmp = -5; double tmp = 0;//-5;
for (int i = 1; i < x.length-1; i++) { for (int i = 1; i < x.length-1; i++) {
tmp += Math.pow(x[i]-m_XOffSet, 2); tmp += Math.pow(x[i]-m_XOffSet, 2);
} }
double x0 = x[0]-m_XOffSet; double x0 = x[0]-m_XOffSet;
result[0] = m_YOffSet+(Math.exp(-5*x0*x0)+2*Math.exp(-5*Math.pow(1-x0, 2)))*Math.exp(tmp); result[0] = m_YOffSet+((Math.exp(-5*x0*x0)+2*Math.exp(-5*Math.pow(1-x0, 2)))*Math.exp(-5*tmp));
return result; return result;
} }

View File

@ -1,12 +1,14 @@
package eva2.server.go.problems; package eva2.server.go.problems;
import eva2.gui.GenericObjectEditor;
import eva2.server.go.individuals.ESIndividualDoubleData; import eva2.server.go.individuals.ESIndividualDoubleData;
import eva2.server.go.operators.postprocess.SolutionHistogram;
/** /**
* Schwefels sine root function (1981) with a minimum at 420.9687^n of value 0. * Schwefels sine root function (1981) with a minimum at 420.9687^n of value 0.
* Function f(x) = (418.9829 * n) - sum_n(x_i * sin(sqrt(abs(x_i)))) + (418.9829 * n); * Function f(x) = (418.9829 * n) - sum_n(x_i * sin(sqrt(abs(x_i)))) + (418.9829 * n);
*/ */
public class F13Problem extends AbstractProblemDoubleOffset implements InterfaceMultimodalProblem { public class F13Problem extends AbstractProblemDoubleOffset implements InterfaceMultimodalProblem, InterfaceInterestingHistogram {
public F13Problem() { public F13Problem() {
this.m_Template = new ESIndividualDoubleData(); this.m_Template = new ESIndividualDoubleData();
@ -27,28 +29,37 @@ public class F13Problem extends AbstractProblemDoubleOffset implements Interface
return (Object) new F13Problem(this); return (Object) new F13Problem(this);
} }
// public double[][] makeRange() { @Override
// double[][] range = new double[this.m_ProblemDimension][2]; public double getRangeLowerBound(int dim) {
// for (int i = 0; i < range.length; i++) { return -512.03;
// range[i][0] = -512.03; }
// range[i][1] = 511.97;
// } @Override
// return range; public double getRangeUpperBound(int dim) {
// } return 511.97;
}
@Override
public void hideHideable() {
super.hideHideable();
GenericObjectEditor.setHideProperty(this.getClass(), "defaultRange", true);
}
/** Ths method allows you to evaluate a double[] to determine the fitness /** Ths method allows you to evaluate a double[] to determine the fitness
* @param x The n-dimensional input vector * @param x The n-dimensional input vector
* @return The m-dimensional output vector. * @return The m-dimensional output vector.
*/ */
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] result = new double[1]; double[] result = new double[1];
result[0] = m_YOffSet; result[0] = m_YOffSet;
for (int i=0; i<x.length; i++) { for (int i=0; i<x.length; i++) {
double xi = x[i]-m_XOffSet; double xi = (x[i]-m_XOffSet);
result[0] -= xi*Math.sin(Math.sqrt(Math.abs(xi))); result[0] -= xi*Math.sin(Math.sqrt(Math.abs(xi)));
} }
result[0] += (418.9829 * m_ProblemDimension); result[0] += (418.9829 * m_ProblemDimension);
// res = cn-sum_i(xi*sin(sqrt(abs(xi))))
return result; return result;
} }
@ -67,6 +78,11 @@ public class F13Problem extends AbstractProblemDoubleOffset implements Interface
return result; return result;
} }
public SolutionHistogram getHistogram() {
if (getProblemDimension() < 15) return new SolutionHistogram(0, 800, 16);
else if (getProblemDimension() < 25) return new SolutionHistogram(0, 1600, 16);
else return new SolutionHistogram(0, 3200, 12);
}
/********************************************************************************************************************** /**********************************************************************************************************************
* These are for GUI * These are for GUI
*/ */
@ -85,4 +101,7 @@ public class F13Problem extends AbstractProblemDoubleOffset implements Interface
return "Schwefels sine-root Function (multimodal, 1981). Remember to use range check!"; return "Schwefels sine-root Function (multimodal, 1981). Remember to use range check!";
} }
public void setDefaultAccuracy(double v) {
super.SetDefaultAccuracy(v);
}
} }

View File

@ -0,0 +1,102 @@
package eva2.server.go.problems;
import static java.lang.Math.PI;
import static java.lang.Math.sin;
public class F15Problem extends AbstractProblemDoubleOffset {
int iterations = 100;
public F15Problem(F15Problem f15Problem) {
iterations = f15Problem.iterations;
}
public Object clone() {
return (Object) new F15Problem(this);
}
/** This method allows you to evaluate a double[] to determine the fitness
* @param x The n-dimensional input vector
* @return The m-dimensional output vector.
*/
public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] c = new double[2];
// c[0]= (x[0])*getXOffSet();
// c[1]= (x[1])*Math.sin((Math.PI/2)*getYOffSet());
c[0] = x[0]*x[2];
c[1] = x[1] * sin( PI / 2.0 * x[3]);
// c[0]= (x[0]+(x[2]/10))*getXOffSet();
// c[1]= (x[1]+(x[3]/10))*Math.sin(Math.PI/2*getYOffSet());
// c[0]= (x[0]*(1-x[2]/10));
// c[1]= (x[1]*(1-x[3]/10));
double[] result = new double[1];
result[0] = flatten(evalRec(x, c, iterations));
return result;
}
private double[] evalRec(double[] x, double[] c, int n) {
if (n==0) return x;
else return evalRec(addComplex(squareComplex(x),c), c, n-1);
}
private double[] squareComplex(double[] x) {
double[] result = new double[2];
result[0] = (x[0]*x[0])-(x[1]*x[1]);
result[1] = (2*x[0]*x[1]);
return result;
}
private double[] addComplex(double[] x, double[] y) {
double[] result = new double[2];
result[0] = x[0] + y[0];
result[1] = x[1] + y[1];
return result;
}
private double flatten(double[] x) {
double len = Math.sqrt((x[0]*x[0])+(x[1]*x[1]));
double ang = Math.atan2(x[1],x[0]);
if (Double.isNaN(len) || (len > 1000.)) len = 1000.;
return len;
// return 0.5+0.5*t*(2*b*a*u(x/a));
// return 1/(2*Math.PI*ang);
// return +Math.abs(x[0])+Math.abs(x[1]);
}
public int getProblemDimension() {
return 4;
}
public String getName() {
return "F15-Problem";
}
public double getRangeLowerBound(int dim) {
// return -1;
if (dim == 0) return -2.5;
else return -1.5;
}
public double getRangeUpperBound(int dim) {
// return 1;
return 1.5;
}
/**
* @return the iterations
*/
public int getIterations() {
return iterations;
}
/**
* @param iterations the iterations to set
*/
public void setIterations(int iterations) {
this.iterations = iterations;
}
}

View File

@ -13,6 +13,7 @@ public class F16Problem extends AbstractProblemDouble implements InterfaceMultim
@Override @Override
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] res = new double[1]; double[] res = new double[1];
double sum = 0; double sum = 0;
@ -50,6 +51,6 @@ public class F16Problem extends AbstractProblemDouble implements InterfaceMultim
} }
public String globalInfo() { public String globalInfo() {
return "Multiple optima with increasing densitiy near the lower bounds, there for decreasing attractor size."; return "Multiple optima with increasing densitiy near the lower bounds, therefore decreasing attractor size.";
} }
} }

View File

@ -1,18 +1,33 @@
package eva2.server.go.problems; package eva2.server.go.problems;
import eva2.server.go.operators.postprocess.SolutionHistogram;
/**
* Bohachevsky function, numerous optima on an oval hyperparabola with similar attractor sizes
* but decreasing fitness towards the bounds. Described e.g. in Shir&Bäck, PPSN 2006,
* "Niche radius adaption in the CMA-ES Niching Algorithm".
*
*/
public class F17Problem extends AbstractProblemDouble implements public class F17Problem extends AbstractProblemDouble implements
InterfaceMultimodalProblem { InterfaceMultimodalProblem, InterfaceInterestingHistogram{
int dim = 10; int dim = 10;
public F17Problem() { public F17Problem() {
setDefaultRange(10.);
dim=10; dim=10;
} }
public F17Problem(int dimension) {
this();
setProblemDimension(dimension);
}
public F17Problem(F17Problem other) { public F17Problem(F17Problem other) {
super(other);
dim=other.dim; dim=other.dim;
} }
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] res = new double[1]; double[] res = new double[1];
double sum = 0; double sum = 0;
for (int i=0; i<getProblemDimension()-1; i++) { for (int i=0; i<getProblemDimension()-1; i++) {
@ -30,7 +45,7 @@ public class F17Problem extends AbstractProblemDouble implements
public void setProblemDimension(int newDim) { public void setProblemDimension(int newDim) {
dim = newDim; dim = newDim;
} }
public Object clone() { public Object clone() {
return new F17Problem(this); return new F17Problem(this);
} }
@ -42,4 +57,9 @@ public class F17Problem extends AbstractProblemDouble implements
public String globalInfo() { public String globalInfo() {
return "Bohachevsky function, numerous optima on an oval hyperparabola with similar attractor sizes but decreasing fitness towards the bounds."; return "Bohachevsky function, numerous optima on an oval hyperparabola with similar attractor sizes but decreasing fitness towards the bounds.";
} }
public SolutionHistogram getHistogram() {
if (getProblemDimension()<15) return new SolutionHistogram(-0.5, 7.5, 16);
else return new SolutionHistogram(-0.5, 15.5, 16);
}
} }

View File

@ -14,6 +14,7 @@ InterfaceMultimodalProblem {
} }
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] res = new double[1]; double[] res = new double[1];
double sum = 0; double sum = 0;
for (int i=0; i<getProblemDimension(); i++) { for (int i=0; i<getProblemDimension(); i++) {

View File

@ -1,14 +1,23 @@
package eva2.server.go.problems; package eva2.server.go.problems;
import java.util.Arrays; import java.util.Arrays;
import java.util.Random;
import wsi.ra.math.RNG; import eva2.server.go.operators.postprocess.SolutionHistogram;
import eva2.tools.math.RNG;
/**
* Fletcher-Powell function with up to 2^n optima from Shir&Baeck, PPSN 2006,
* after Bäck 1996. Alphas and Matrices A and B are randomly created with a fixed seed.
* @author mkron
*
*/
public class F19Problem extends AbstractProblemDouble implements public class F19Problem extends AbstractProblemDouble implements
InterfaceMultimodalProblem { InterfaceMultimodalProblem, InterfaceInterestingHistogram {
int dim = 10; int dim = 10;
transient private double[] alphas, As; transient private double[] alphas, As;
transient private int[] A,B; transient private int[] A,B;
private long randSeed = 23;
public F19Problem() { public F19Problem() {
alphas=null; alphas=null;
@ -21,15 +30,21 @@ InterfaceMultimodalProblem {
alphas=null; alphas=null;
} }
public F19Problem(int d) {
this();
setProblemDimension(d);
}
public void initProblem() { public void initProblem() {
super.initProblem(); super.initProblem();
if (alphas==null) { // if (alphas==null) {
// create static random data // create static random data
alphas = RNG.randomVector(dim, -Math.PI, Math.PI); Random rand = new Random(randSeed);
A = RNG.randomVector(dim*dim, -100, 100); alphas = RNG.randomDoubleArray(rand, -Math.PI, Math.PI, dim);
B = RNG.randomVector(dim*dim, -100, 100); A = RNG.randomIntArray(rand, -100, 100, dim*dim);
B = RNG.randomIntArray(rand, -100, 100, dim*dim);
As = transform(alphas); As = transform(alphas);
} // }
} }
private double[] transform(double[] x) { private double[] transform(double[] x) {
@ -55,6 +70,7 @@ InterfaceMultimodalProblem {
} }
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] res = new double[1]; double[] res = new double[1];
double[] Bs = transform(x); double[] Bs = transform(x);
@ -88,7 +104,12 @@ InterfaceMultimodalProblem {
} }
public String globalInfo() { public String globalInfo() {
return "Fletcher-Powell function with up to 2^n optima from Shir&Baeck, PPSN 2006, after Bäck 1996. Alphas and Matrices A and B are randomly created but kept when the dimension is decreased."; return "Fletcher-Powell function with up to 2^n optima from Shir&Baeck, PPSN 2006, after Bäck 1996. Alphas and Matrices A and B are randomly created with a fixed seed.";
}
public SolutionHistogram getHistogram() {
if (getProblemDimension()<15) return new SolutionHistogram(0, 8, 16);
else return new SolutionHistogram(0, 40000, 16);
} }
} }

View File

@ -44,6 +44,7 @@ public class F1Problem extends AbstractProblemDoubleOffset implements Interface2
* @return The m-dimensional output vector. * @return The m-dimensional output vector.
*/ */
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] result = new double[1]; double[] result = new double[1];
result[0] = m_YOffSet; result[0] = m_YOffSet;
// add an offset in solution space // add an offset in solution space
@ -89,6 +90,7 @@ public class F1Problem extends AbstractProblemDoubleOffset implements Interface2
} }
public double[] getFirstOrderGradients(double[] x) { public double[] getFirstOrderGradients(double[] x) {
x = rotateMaybe(x);
// first order partial derivation in direction x_i is 2*x_i // first order partial derivation in direction x_i is 2*x_i
double[] grads=new double[x.length]; double[] grads=new double[x.length];
for (int i=0; i<x.length; i++) { for (int i=0; i<x.length; i++) {

View File

@ -0,0 +1,117 @@
package eva2.server.go.problems;
import java.io.Serializable;
import eva2.server.go.operators.postprocess.SolutionHistogram;
/**
* The multi-modal, multi-funnel Rana function, f_rana = sum_{i=0}^{n-2} (g(x_i, x_{i+1})
* with g(x,y) = x sin(a)cos(b)+(y+1)cos(a)sin(b), a=sqrt(|-x+y+1|), b=sqrt(|x+y+1|).
*
* For gnuplot: x *sin(sqrt(abs(-x+y+1)))*cos(sqrt(abs(x+y+1)))+(y+1)*cos(sqrt(abs(-x+y+1)))*sin(sqrt(abs(x+y+1)))
*
* @author mkron
*
*/
public class F20Problem extends AbstractProblemDouble implements Serializable, InterfaceInterestingHistogram{
private int dim=10;
private boolean shiftFit = false;
public F20Problem() {
setDefaultRange(512.);
}
public F20Problem(int dim, boolean rotate) {
this();
setProblemDimension(dim);
setDoRotation(rotate);
}
public F20Problem(F20Problem o) {
super(o);
setDefaultRange(512);
this.dim = o.dim;
this.setShiftFit(o.isShiftFit());
}
@Override
public double[] eval(double[] x) {
x = rotateMaybe(x);
double sum=getYOffset();
for (int i=0; i<x.length-1; i++) {
sum += g(x[i],x[i+1]);
}
return new double[] {sum};
}
private double getYOffset() {
if (isShiftFit()) return (getProblemDimension() - 1)*getDefaultRange();
else return 0;
}
private double g(double x, double y) {
double a=beta(-x,y);
double b=beta(x,y);
return x*Math.sin(a)*Math.cos(b)+(y+1.)*Math.cos(a)*Math.sin(b);
}
// private double alpha(double x, double y) {
// return Math.sqrt(Math.abs(-x+y+1));
// }
private double beta(double x, double y) {
return Math.sqrt(Math.abs(x+y+1));
}
@Override
public int getProblemDimension() {
return dim;
}
public void setProblemDimension(int newDim) {
dim=newDim;
}
@Override
public Object clone() {
return new F20Problem(this);
}
public String getName() {
return "Rana"+(isDoRotation() ? "-rot" : "");
}
public String globalInfo() {
return "The Rana function is non-separable, highly multi-modal and multi-funnel." +
" There are diagonal ridges across the search space and the optima are close to the bounds." +
"The minimum fitness f(x*) is close to (n-1)*r for dimension n and default range r, by which " +
"this implementation may be shifted to the positive domain.";
}
public void setShiftFit(boolean shiftFit) {
this.shiftFit = shiftFit;
}
public boolean isShiftFit() {
return shiftFit;
}
public SolutionHistogram getHistogram() {
if (getProblemDimension()==10) {
if (getYOffset()==0) return new SolutionHistogram(-5000, -3400, 16);
else return new SolutionHistogram(0, 1600, 16);
}
if (getProblemDimension()==30) {
if (getYOffset()==0) return new SolutionHistogram(-15000, -8600, 16);
// das passst wohl nicht für Multimodales... Also nochmal für 30D.
else return new SolutionHistogram(0, 6400, 16);
}
if (getProblemDimension() <= 5) {
double lower = getYOffset()-((getProblemDimension()-1)*getDefaultRange());
return new SolutionHistogram(lower, lower+160, 16);
} else if (getProblemDimension() < 15) {
return new SolutionHistogram(getYOffset()-5000, getYOffset()-3400, 16);
} else return new SolutionHistogram(getYOffset()-15000, getYOffset()-13400, 16);
}
}

View File

@ -0,0 +1,77 @@
package eva2.server.go.problems;
import java.io.Serializable;
import eva2.server.go.operators.postprocess.SolutionHistogram;
/**
* The Levy-function, from Levy, A., and Montalvo, A. (1985). Also described in
* "A Trust-Region Algorithm for Global Optimization", Bernardetta Addisy and Sven Leyfferz, 2004/2006.
*/
public class F21Problem extends AbstractProblemDouble implements Serializable, InterfaceInterestingHistogram {
private int dim=10;
public F21Problem() {
super();
super.SetDefaultAccuracy(0.00001);
setDefaultRange(10);
}
public F21Problem(int d) {
this();
setProblemDimension(d);
}
public F21Problem(F21Problem f21Problem) {
super(f21Problem);
dim=f21Problem.getProblemDimension();
setDefaultRange(f21Problem.getDefaultRange());
}
@Override
public double[] eval(double[] x) {
x = rotateMaybe(x);
double t=0, s=0, sum=0;
for (int i=0; i<x.length-2; i++) {
s=(x[i]-1.);
t=Math.sin(Math.PI*x[i+1]);
sum += (s*s)*(1+10.*t*t);
}
s=Math.sin(Math.PI*x[0]);
double[] y = new double[1];
y[0] = 10.*s*s+sum+dim*(x[dim-1]-1)*(x[dim-1]-1);
return y;
}
@Override
public int getProblemDimension() {
return dim;
}
public void setProblemDimension(int d) {
dim=d;
}
@Override
public Object clone() {
return new F21Problem(this);
}
public SolutionHistogram getHistogram() {
if (getProblemDimension()<15) return new SolutionHistogram(0, 2, 16);
else if (getProblemDimension()<25) return new SolutionHistogram(0, 4, 16);
else return new SolutionHistogram(0, 8, 16);
}
public String getName() {
return "F21-Problem";
}
public String globalInfo() {
return "The Levy-function, from Levy, A., and Montalvo, A. (1985)";
}
}

View File

@ -1,6 +1,8 @@
package eva2.server.go.problems; package eva2.server.go.problems;
import eva2.server.go.individuals.ESIndividualDoubleData; import eva2.server.go.individuals.ESIndividualDoubleData;
import eva2.server.go.populations.Population;
import eva2.server.go.strategies.GradientDescentAlgorithm;
/** /**
* Created by IntelliJ IDEA. * Created by IntelliJ IDEA.
@ -9,9 +11,12 @@ import eva2.server.go.individuals.ESIndividualDoubleData;
* Time: 19:03:09 * Time: 19:03:09
* To change this template use File | Settings | File Templates. * To change this template use File | Settings | File Templates.
*/ */
public class F2Problem extends AbstractProblemDoubleOffset implements InterfaceMultimodalProblem, java.io.Serializable, InterfaceFirstOrderDerivableProblem { public class F2Problem extends AbstractProblemDoubleOffset implements InterfaceLocalSearchable, InterfaceMultimodalProblem, java.io.Serializable, InterfaceFirstOrderDerivableProblem {
public F2Problem() { private transient GradientDescentAlgorithm localSearchOptimizer=null;
public F2Problem() {
this.m_Template = new ESIndividualDoubleData(); this.m_Template = new ESIndividualDoubleData();
} }
public F2Problem(F2Problem b) { public F2Problem(F2Problem b) {
@ -33,6 +38,7 @@ public class F2Problem extends AbstractProblemDoubleOffset implements InterfaceM
* @return The m-dimensional output vector. * @return The m-dimensional output vector.
*/ */
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] result = new double[1]; double[] result = new double[1];
result[0] = m_YOffSet; result[0] = m_YOffSet;
double xi, xii; double xi, xii;
@ -46,6 +52,7 @@ public class F2Problem extends AbstractProblemDoubleOffset implements InterfaceM
} }
public double[] getFirstOrderGradients(double[] x) { public double[] getFirstOrderGradients(double[] x) {
x = rotateMaybe(x);
int dim = x.length; int dim = x.length;
double[] result = new double[dim]; double[] result = new double[dim];
double xi, xii; double xi, xii;
@ -93,4 +100,26 @@ public class F2Problem extends AbstractProblemDoubleOffset implements InterfaceM
public String globalInfo() { public String globalInfo() {
return "Generalized Rosenbrock's function."; return "Generalized Rosenbrock's function.";
} }
public void doLocalSearch(Population pop) {
if (localSearchOptimizer == null) {
initLS();
}
localSearchOptimizer.setPopulation(pop);
localSearchOptimizer.optimize();
}
private void initLS() {
localSearchOptimizer = new GradientDescentAlgorithm();
localSearchOptimizer.SetProblem(this);
localSearchOptimizer.init();
}
public double getLocalSearchStepFunctionCallEquivalent() {
double cost = 1;
if (this.localSearchOptimizer instanceof GradientDescentAlgorithm) {
cost = ((GradientDescentAlgorithm) localSearchOptimizer).getIterations();
}
return cost;
}
} }

View File

@ -31,6 +31,7 @@ public class F3Problem extends AbstractProblemDoubleOffset implements java.io.Se
* @return The m-dimensional output vector. * @return The m-dimensional output vector.
*/ */
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] result = new double[1]; double[] result = new double[1];
result[0] = m_YOffSet+6*x.length; result[0] = m_YOffSet+6*x.length;
for (int i = 0; i < x.length-1; i++) { for (int i = 0; i < x.length-1; i++) {

View File

@ -35,6 +35,7 @@ public class F4Problem extends AbstractProblemDoubleOffset implements java.io.Se
* @return The m-dimensional output vector. * @return The m-dimensional output vector.
*/ */
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] result = new double[1]; double[] result = new double[1];
result[0] = m_YOffSet; result[0] = m_YOffSet;
for (int i = 0; i < x.length-1; i++) { for (int i = 0; i < x.length-1; i++) {

View File

@ -35,6 +35,7 @@ public class F5Problem extends AbstractProblemDoubleOffset implements java.io.Se
* @return The m-dimensional output vector. * @return The m-dimensional output vector.
*/ */
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] result = new double[1]; double[] result = new double[1];
double tmp; double tmp;
result[0] = m_YOffSet; result[0] = m_YOffSet;

View File

@ -2,28 +2,26 @@ package eva2.server.go.problems;
import eva2.server.go.individuals.ESIndividualDoubleData; import eva2.server.go.individuals.ESIndividualDoubleData;
import eva2.tools.math.Mathematics; import eva2.tools.math.Mathematics;
import eva2.server.go.operators.postprocess.SolutionHistogram;
import eva2.server.go.populations.Population;
import eva2.server.go.strategies.GradientDescentAlgorithm;
import eva2.tools.math.Jama.Matrix; import eva2.tools.math.Jama.Matrix;
/** /**
* Created by IntelliJ IDEA. * Generalized Rastrigin's function.
* User: streiche *
* Date: 30.06.2005
* Time: 13:09:36
* To change this template use File | Settings | File Templates.
*/ */
public class F6Problem extends AbstractProblemDoubleOffset implements InterfaceMultimodalProblem, InterfaceFirstOrderDerivableProblem, java.io.Serializable { public class F6Problem extends AbstractProblemDoubleOffset
implements InterfaceMultimodalProblem, InterfaceFirstOrderDerivableProblem, InterfaceLocalSearchable, java.io.Serializable, InterfaceInterestingHistogram {
private boolean doRotation = false;
private double m_A = 10; private double m_A = 10;
private double m_Omega = 2*Math.PI; private double m_Omega = 2*Math.PI;
private Matrix rotation; private transient GradientDescentAlgorithm localSearchOptimizer=null;
public F6Problem() { public F6Problem() {
this.m_Template = new ESIndividualDoubleData(); this.m_Template = new ESIndividualDoubleData();
} }
public F6Problem(F6Problem b) { public F6Problem(F6Problem b) {
super(b); super(b);
doRotation = b.doRotation;
this.m_A = b.m_A; this.m_A = b.m_A;
this.m_Omega = b.m_Omega; this.m_Omega = b.m_Omega;
} }
@ -31,17 +29,6 @@ public class F6Problem extends AbstractProblemDoubleOffset implements InterfaceM
public F6Problem(int dim) { public F6Problem(int dim) {
super(dim); super(dim);
} }
/** This method inits the Problem to log multiruns
*/
public void initProblem() {
super.initProblem();
if (doRotation) {
rotation = new Matrix(m_ProblemDimension, m_ProblemDimension);
Matrix vec = new Matrix(m_ProblemDimension, 1);
for (int i=0; i<m_ProblemDimension; i++) vec.set(i,0, i+1);
rotation = Mathematics.getRotationMatrix(vec).transpose();
} else rotation = null;
}
/** This method returns a deep clone of the problem. /** This method returns a deep clone of the problem.
* @return the clone * @return the clone
@ -55,10 +42,7 @@ public class F6Problem extends AbstractProblemDoubleOffset implements InterfaceM
* @return The m-dimensional output vector. * @return The m-dimensional output vector.
*/ */
public double[] eval(double[] x) { public double[] eval(double[] x) {
if (doRotation) { x = rotateMaybe(x);
Matrix resVec = rotation.times(new Matrix(x, x.length));
x = resVec.getColumnPackedCopy();
}
double[] result = new double[1]; double[] result = new double[1];
result[0] = x.length * this.m_A + m_YOffSet; result[0] = x.length * this.m_A + m_YOffSet;
for (int i = 0; i < x.length; i++) { for (int i = 0; i < x.length; i++) {
@ -69,10 +53,7 @@ public class F6Problem extends AbstractProblemDoubleOffset implements InterfaceM
} }
public double[] getFirstOrderGradients(double[] x) { public double[] getFirstOrderGradients(double[] x) {
if (doRotation) { x = rotateMaybe(x);
Matrix resVec = rotation.times(new Matrix(x, x.length));
x = resVec.getColumnPackedCopy();
}
double[] result = new double[x.length]; double[] result = new double[x.length];
for (int j=0; j<x.length; j++) { for (int j=0; j<x.length; j++) {
result[j]=0; result[j]=0;
@ -141,10 +122,36 @@ public class F6Problem extends AbstractProblemDoubleOffset implements InterfaceM
public String omegaTipText() { public String omegaTipText() {
return "Choose Omega."; return "Choose Omega.";
} }
public boolean isDoRotation() {
return doRotation; public void setDefaultAccuracy(double acc) {
} super.SetDefaultAccuracy(acc);
public void setDoRotation(boolean doRotation) { }
this.doRotation = doRotation;
public SolutionHistogram getHistogram() {
if (getProblemDimension() < 15) return new SolutionHistogram(-0.5, 15.5, 16);
else if (getProblemDimension() < 25) return new SolutionHistogram(-0.5, 39.5, 16);
else return new SolutionHistogram(0, 80, 16);
} }
public void doLocalSearch(Population pop) {
if (localSearchOptimizer == null) {
initLS();
}
localSearchOptimizer.setPopulation(pop);
localSearchOptimizer.optimize();
}
private void initLS() {
localSearchOptimizer = new GradientDescentAlgorithm();
localSearchOptimizer.SetProblem(this);
localSearchOptimizer.init();
}
public double getLocalSearchStepFunctionCallEquivalent() {
double cost = 1;
if (this.localSearchOptimizer instanceof GradientDescentAlgorithm) {
cost = ((GradientDescentAlgorithm) localSearchOptimizer).getIterations();
}
return cost;
}
} }

View File

@ -70,6 +70,7 @@ public class F7Problem extends AbstractProblemDoubleOffset implements java.io.Se
* @return The m-dimensional output vector. * @return The m-dimensional output vector.
*/ */
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] result = new double[1]; double[] result = new double[1];
result[0] = m_YOffSet; result[0] = m_YOffSet;
if ((Math.floor(this.m_CurrentTimeStamp / this.m_t)%2) == 0) { if ((Math.floor(this.m_CurrentTimeStamp / this.m_t)%2) == 0) {

View File

@ -41,6 +41,7 @@ public class F8Problem extends AbstractProblemDoubleOffset implements InterfaceM
* @return The m-dimensional output vector. * @return The m-dimensional output vector.
*/ */
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] result = new double[1]; double[] result = new double[1];
double sum1 = 0, sum2 = 0, exp1, exp2; double sum1 = 0, sum2 = 0, exp1, exp2;

View File

@ -24,6 +24,7 @@ public class F9Problem extends AbstractProblemDoubleOffset implements java.io.Se
* @return The m-dimensional output vector. * @return The m-dimensional output vector.
*/ */
public double[] eval(double[] x) { public double[] eval(double[] x) {
x = rotateMaybe(x);
double[] result = new double[1]; double[] result = new double[1];
result[0] = m_YOffSet; result[0] = m_YOffSet;
for (int i = 0; i < x.length; i++) { for (int i = 0; i < x.length; i++) {

View File

@ -87,6 +87,7 @@ public class GPFunctionProblem extends AbstractProblemDouble implements Interfac
EVAERROR.errorMsgOnce("mismatching dimension of GPFunctionProblem! Setting to " + x.length); EVAERROR.errorMsgOnce("mismatching dimension of GPFunctionProblem! Setting to " + x.length);
setProblemDimension(x.length); setProblemDimension(x.length);
} }
x = rotateMaybe(x);
pos = x; pos = x;
Double res = (Double) gpProblem.evaluate(this); Double res = (Double) gpProblem.evaluate(this);
double[] fit = new double[1]; double[] fit = new double[1];

View File

@ -10,6 +10,8 @@ public interface InterfaceFirstOrderDerivableProblem {
/** /**
* Calculate the first order gradients of this problem. * Calculate the first order gradients of this problem.
* If you implement this, be aware that some types of AbstractProblemDouble may be rotated,
* so you may have to use x = rotateMaybe(x) first.
* @param x * @param x
* @return the first order gradients of this problem * @return the first order gradients of this problem
*/ */

View File

@ -0,0 +1,20 @@
package eva2.server.go.problems;
import eva2.server.go.operators.postprocess.SolutionHistogram;
/**
* Target functions may provide an idea which fitness values are
* interesting.
*
* @author mkron
*
*/
public interface InterfaceInterestingHistogram {
/**
* For this specific instance, provide an empty histogram defining in which
* area interesting solutions would lie.
*
* @return
*/
public SolutionHistogram getHistogram();
}

View File

@ -19,6 +19,12 @@ public interface InterfaceMultimodalProblemKnown extends InterfaceMultimodalProb
*/ */
public void initListOfOptima(); public void initListOfOptima();
/**
* Return true if the full list of optima is available, else false.
* @return
*/
public boolean fullListAvailable();
/** /**
* This method returns a list of all optima as population or null if * This method returns a list of all optima as population or null if
* the optima are unknown. * the optima are unknown.
@ -48,5 +54,5 @@ public interface InterfaceMultimodalProblemKnown extends InterfaceMultimodalProb
* *
* @return * @return
*/ */
public double getEpsilon(); public double getDefaultAccuracy();
} }

View File

@ -267,9 +267,10 @@ public class SimpleProblemWrapper extends AbstractOptimizationProblem {
* @return description * @return description
*/ */
public String globalInfo() { public String globalInfo() {
Object maybeAdditionalString = BeanInspector.callIfAvailable(simProb, "globalInfo", null); return "Wrapping simple problem implementations.";
if (maybeAdditionalString != null) { }
return "Wrapping a simple problem: " + (String)maybeAdditionalString;
} else return "Wrapping a simple problem."; public String[] getGOEPropertyUpdateLinks() {
return new String[] {"globalInfo", "simpleProblem"};
} }
} }

View File

@ -327,7 +327,7 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis
* @return True if converged. * @return True if converged.
*/ */
private boolean testSpeciesForConvergence(Population pop) { private boolean testSpeciesForConvergence(Population pop) {
ArrayList<AbstractEAIndividual> speciesHistory = pop.m_History; ArrayList<AbstractEAIndividual> speciesHistory = pop.getHistory();
int histLen = speciesHistory.size(); int histLen = speciesHistory.size();
if (histLen <= haltingWindow) { if (histLen <= haltingWindow) {
@ -762,7 +762,7 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis
if (plot && (m_Topology!=null)) plotLine(m_Topology, spec1.getBestEAIndividual(), spec2.getBestEAIndividual()); if (plot && (m_Topology!=null)) plotLine(m_Topology, spec1.getBestEAIndividual(), spec2.getBestEAIndividual());
spec1.addPopulation(spec2); spec1.addPopulation(spec2);
// keep longer history // keep longer history
if (spec2.m_History.size() > spec1.m_History.size()) spec1.m_History = spec2.m_History; if (spec2.getHistoryLength() > spec1.getHistoryLength()) spec1.SetHistory(spec2.getHistory());
if (spec2.getGeneration() > spec1.getGeneration()) spec1.setGenerationTo(spec2.getGeneration()); if (spec2.getGeneration() > spec1.getGeneration()) spec1.setGenerationTo(spec2.getGeneration());
// possibly notify the optimizer of the merging event to merge population based information // possibly notify the optimizer of the merging event to merge population based information
if (m_Optimizer instanceof InterfaceSpeciesAware) ((InterfaceSpeciesAware)m_Optimizer).mergeToFirstPopulationEvent(spec1, spec2); if (m_Optimizer instanceof InterfaceSpeciesAware) ((InterfaceSpeciesAware)m_Optimizer).mergeToFirstPopulationEvent(spec1, spec2);
@ -780,10 +780,10 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis
newSp.setUseHistory(true); newSp.setUseHistory(true);
if (startAtP1Gen) { // start explicitely as a child population of p1 if (startAtP1Gen) { // start explicitely as a child population of p1
newSp.setGenerationTo(parentSp.getGeneration()); newSp.setGenerationTo(parentSp.getGeneration());
newSp.m_History = (ArrayList<AbstractEAIndividual>) parentSp.m_History.clone(); newSp.SetHistory((ArrayList<AbstractEAIndividual>) parentSp.getHistory().clone());
} else { // start anew (from undiff) } else { // start anew (from undiff)
newSp.setGenerationTo(0); newSp.setGenerationTo(0);
newSp.m_History = new ArrayList<AbstractEAIndividual>(); newSp.SetHistory(new ArrayList<AbstractEAIndividual>());
} }
if (m_Optimizer instanceof InterfaceSpeciesAware) ((InterfaceSpeciesAware)m_Optimizer).splitFromFirst(parentSp, newSp); if (m_Optimizer instanceof InterfaceSpeciesAware) ((InterfaceSpeciesAware)m_Optimizer).splitFromFirst(parentSp, newSp);

View File

@ -138,8 +138,7 @@ public class EvolutionStrategyIPOP extends EvolutionStrategies implements Interf
protected void firePropertyChangedEvent(String name) { protected void firePropertyChangedEvent(String name) {
if (name.equals(Population.funCallIntervalReached)) { if (name.equals(Population.funCallIntervalReached)) {
super.firePropertyChangedEvent(Population.nextGenerationPerformed); super.firePropertyChangedEvent(Population.nextGenerationPerformed);
} } else {} // nothing, evt is produced in #registerPopulationStateChanged, dont forward original due to changing pop size
else {} // nothing, evt is produced in #registerPopulationStateChanged, dont forward original due to changing pop size
} }
public void init() { public void init() {
@ -152,7 +151,7 @@ public class EvolutionStrategyIPOP extends EvolutionStrategies implements Interf
super.setLambda(initialLambda); super.setLambda(initialLambda);
checkPopulationConstraints(); checkPopulationConstraints();
setForceOrigPopSize(false); setForceOrigPopSize(false);
getPopulation().setNotifyEvalInterval(initialLambda); getPopulation().setNotifyEvalInterval(Math.max(initialLambda, 100));
super.init(); super.init();
bestList = new LinkedList<AbstractEAIndividual>(); bestList = new LinkedList<AbstractEAIndividual>();
best = getPopulation().getBestEAIndividual(); best = getPopulation().getBestEAIndividual();
@ -291,7 +290,6 @@ public class EvolutionStrategyIPOP extends EvolutionStrategies implements Interf
public double getStagThreshold() { public double getStagThreshold() {
return stagThreshold; return stagThreshold;
} }
/** /**
* @param stagThreshold the stagThreshold to set * @param stagThreshold the stagThreshold to set
*/ */
@ -299,6 +297,9 @@ public class EvolutionStrategyIPOP extends EvolutionStrategies implements Interf
this.stagThreshold = stagThreshold; this.stagThreshold = stagThreshold;
if (fitConvTerm != null) fitConvTerm.setConvergenceThreshold(stagThreshold); if (fitConvTerm != null) fitConvTerm.setConvergenceThreshold(stagThreshold);
} }
public String getStagThresholdTipText() {
return "Trigger new aera if the fitness does not change more than this threshold within certain no. iterations.";
}
/** /**
* @return the stagTime * @return the stagTime

View File

@ -1,5 +1,6 @@
package eva2.server.go.strategies; package eva2.server.go.strategies;
import eva2.gui.BeanInspector;
import eva2.server.go.InterfacePopulationChangedEventListener; import eva2.server.go.InterfacePopulationChangedEventListener;
import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.GAIndividualBinaryData; import eva2.server.go.individuals.GAIndividualBinaryData;
@ -111,7 +112,8 @@ public class GeneticAlgorithm implements InterfaceOptimizer, java.io.Serializabl
this.m_ParentSelection.prepareSelection(this.m_Population); this.m_ParentSelection.prepareSelection(this.m_Population);
this.m_PartnerSelection.prepareSelection(this.m_Population); this.m_PartnerSelection.prepareSelection(this.m_Population);
parents = this.m_ParentSelection.selectFrom(this.m_Population, this.m_Population.getTargetSize()); parents = this.m_ParentSelection.selectFrom(this.m_Population, this.m_Population.getTargetSize());
//System.out.println("Parents:"+parents.getSolutionRepresentationFor()); // System.out.println("Parents:"+parents.getStringRepresentation());
// double[] meas = parents.getPopulationMeasures();
if (parents.getEAIndividual(0).getMutationOperator() instanceof InterfaceMutationGenerational) { if (parents.getEAIndividual(0).getMutationOperator() instanceof InterfaceMutationGenerational) {
((InterfaceMutationGenerational)parents.getEAIndividual(0).getMutationOperator()).adaptAfterSelection(m_Population, parents); ((InterfaceMutationGenerational)parents.getEAIndividual(0).getMutationOperator()).adaptAfterSelection(m_Population, parents);
@ -155,7 +157,8 @@ public class GeneticAlgorithm implements InterfaceOptimizer, java.io.Serializabl
for (int i = 0; i < this.m_Plague; i++) if (this.m_Population.size() > 2) this.m_Population.remove(this.m_Population.getWorstEAIndividual()); for (int i = 0; i < this.m_Plague; i++) if (this.m_Population.size() > 2) this.m_Population.remove(this.m_Population.getWorstEAIndividual());
this.m_Population.setTargetSize(this.m_Population.size()); this.m_Population.setTargetSize(this.m_Population.size());
} }
//System.out.println("Population size: " + this.m_Population.size()); // System.out.println("Population size: " + this.m_Population.size());
// System.out.println("Population: " + m_Population.getStringRepresentation());
// if (this.m_Population.getArchive() != null) { // if (this.m_Population.getArchive() != null) {
// if (this.m_Population.getArchive().getArchive() != null) { // if (this.m_Population.getArchive().getArchive() != null) {
// System.out.println("Zwei Archive!"); // System.out.println("Zwei Archive!");

View File

@ -1,5 +1,6 @@
package eva2.server.go.strategies; package eva2.server.go.strategies;
import eva2.gui.BeanInspector;
import eva2.server.go.InterfacePopulationChangedEventListener; import eva2.server.go.InterfacePopulationChangedEventListener;
import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeDouble; import eva2.server.go.individuals.InterfaceDataTypeDouble;
@ -50,6 +51,8 @@ public class GradientDescentAlgorithm implements InterfaceOptimizer, java.io.Ser
transient private String m_Identifier = ""; transient private String m_Identifier = "";
private Population m_Population; private Population m_Population;
private static boolean TRACE=false;
private static final String lockKey = "gdaLockDataKey"; private static final String lockKey = "gdaLockDataKey";
private static final String lastFitnessKey = "gdaLastFitDataKey"; private static final String lastFitnessKey = "gdaLastFitDataKey";
private static final String stepSizeKey = "gdaStepSizeDataKey"; private static final String stepSizeKey = "gdaStepSizeDataKey";
@ -74,6 +77,23 @@ public class GradientDescentAlgorithm implements InterfaceOptimizer, java.io.Ser
this.m_Population = new Population(); this.m_Population = new Population();
this.m_Population.setTargetSize(1); this.m_Population.setTargetSize(1);
} }
/**
* GDA with locally adapted step size.
*
* @param minStepSize
* @param maxStepSize
* @param maxAbsoluteChange
*/
public GradientDescentAlgorithm(double minStepSize, double maxStepSize, double maxAbsoluteChange) {
globalStepSizeAdaption=false;
localStepSizeAdaption=true;
localminstepsize = minStepSize;
globalminstepsize = minStepSize;
localmaxstepsize = maxStepSize;
globalmaxstepsize = maxStepSize;
maximumabsolutechange = maxAbsoluteChange;
}
public Object clone() { public Object clone() {
/**@todo Implement InterfaceOptimizer method*/ /**@todo Implement InterfaceOptimizer method*/
@ -140,6 +160,7 @@ public class GradientDescentAlgorithm implements InterfaceOptimizer, java.io.Ser
double[] oldchange = null; double[] oldchange = null;
double[] gradient = ((InterfaceFirstOrderDerivableProblem) m_Problem).getFirstOrderGradients(params); double[] gradient = ((InterfaceFirstOrderDerivableProblem) m_Problem).getFirstOrderGradients(params);
if (TRACE) System.out.println("GDA: " + BeanInspector.toString(params) + ", grad: " + BeanInspector.toString(gradient));
if ((oldgradient != null) && (wstepsize != null)) { // LOCAL adaption if ((oldgradient != null) && (wstepsize != null)) { // LOCAL adaption
for (int li = 0; li < wstepsize.length; li++) { for (int li = 0; li < wstepsize.length; li++) {
double prod = gradient[li] * oldgradient[li]; double prod = gradient[li] * oldgradient[li];
@ -214,7 +235,7 @@ public class GradientDescentAlgorithm implements InterfaceOptimizer, java.io.Ser
indy = ((AbstractEAIndividual)this.m_Population.get(i)); indy = ((AbstractEAIndividual)this.m_Population.get(i));
// Hashtable history = (Hashtable) indyhash.get(indy); // Hashtable history = (Hashtable) indyhash.get(indy);
if (indy.getFitness()[0] > recoverythreshold) { if (indy.getFitness()[0] > recoverythreshold) {
System.out.println("Gradient Descent: Fitness critical:" + indy.getFitness()[0]); if (TRACE) System.out.println("Gradient Descent: Fitness critical:" + indy.getFitness()[0]);
((InterfaceDataTypeDouble) indy).SetDoublePhenotype((double[]) indy.getData(oldParamsKey)); ((InterfaceDataTypeDouble) indy).SetDoublePhenotype((double[]) indy.getData(oldParamsKey));
double[] changes = (double[]) indy.getData(changesKey); double[] changes = (double[]) indy.getData(changesKey);
int[] lock = (int[]) indy.getData(lockKey); int[] lock = (int[]) indy.getData(lockKey);

View File

@ -120,7 +120,7 @@ public class MemeticAlgorithm implements InterfaceOptimizer,
if (TRACE) System.out.println("global search"); if (TRACE) System.out.println("global search");
this.m_GlobalOptimizer.optimize(); this.m_GlobalOptimizer.optimize();
if (((this.m_GlobalOptimizer.getPopulation().getGeneration() % this.globalSearchIterations) == 0) if ((globalSearchIterations>0) && (((this.m_GlobalOptimizer.getPopulation().getGeneration() % this.globalSearchIterations) == 0))
&& (this.localSearchSteps > 0) && (this.localSearchSteps > 0)
&& (this.m_Problem instanceof InterfaceLocalSearchable)) { && (this.m_Problem instanceof InterfaceLocalSearchable)) {
// here the local search is performed // here the local search is performed

View File

@ -83,8 +83,10 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
public void addPopulationChangedEventListener( public void addPopulationChangedEventListener(
InterfacePopulationChangedEventListener ea) { InterfacePopulationChangedEventListener ea) {
if (m_Listener == null) m_Listener = new Vector<InterfacePopulationChangedEventListener>(); if (ea!=null) {
if (!m_Listener.contains(ea)) m_Listener.add(ea); if (m_Listener == null) m_Listener = new Vector<InterfacePopulationChangedEventListener>();
if (!m_Listener.contains(ea)) m_Listener.add(ea);
}
} }
public boolean removePopulationChangedEventListener( public boolean removePopulationChangedEventListener(
@ -270,7 +272,7 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
// m_Problem.evaluate(ind); // m_Problem.evaluate(ind);
// this.m_Population.incrFunctionCalls(); // this.m_Population.incrFunctionCalls();
} }
m_Population.set(m_Population.getIndexOfWorstIndividual(fitIndex), ind, fitIndex); m_Population.set(m_Population.getIndexOfWorstIndividualNoConstr(fitIndex), ind, fitIndex);
}else{//keine Verbesserung gefunden shrink!! }else{//keine Verbesserung gefunden shrink!!
double[] u_1 = ((InterfaceDataTypeDouble) m_Population.getBestEAIndividual(fitIndex)).getDoubleData(); double[] u_1 = ((InterfaceDataTypeDouble) m_Population.getBestEAIndividual(fitIndex)).getDoubleData();
@ -286,6 +288,7 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
evalsDone = m_Population.getFunctionCalls() - evalCntStart; evalsDone = m_Population.getFunctionCalls() - evalCntStart;
} while (evalsDone < generationCycle); } while (evalsDone < generationCycle);
m_Problem.evaluatePopulationEnd(m_Population); m_Problem.evaluatePopulationEnd(m_Population);
this.m_Population.incrGeneration();
} }
public void setPopulation(Population pop) { public void setPopulation(Population pop) {
@ -344,7 +347,7 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
NelderMeadSimplex nms = new NelderMeadSimplex(); NelderMeadSimplex nms = new NelderMeadSimplex();
nms.setProblemAndPopSize(problem); nms.setProblemAndPopSize(problem);
nms.addPopulationChangedEventListener(listener); if (listener!=null) nms.addPopulationChangedEventListener(listener);
nms.init(); nms.init();
if (listener!=null) listener.registerPopulationStateChanged(nms.getPopulation(), ""); if (listener!=null) listener.registerPopulationStateChanged(nms.getPopulation(), "");
@ -400,18 +403,18 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
* also contains the initial candidate. However, the new candidates have not been evaluated. * also contains the initial candidate. However, the new candidates have not been evaluated.
* *
* @param candidate * @param candidate
* @param perturbRatio * @param perturbRelative
* @param range * @param range
* @param includeCand * @param includeCand
* @return * @return
*/ */
public static Population createNMSPopulation(AbstractEAIndividual candidate, double perturbRatio, double[][] range, boolean includeCand) { public static Population createNMSPopulation(AbstractEAIndividual candidate, double perturbRelative, double[][] range, boolean includeCand) {
Population initPop = new Population(); Population initPop = new Population();
if (includeCand) initPop.add(candidate); if (includeCand) initPop.add(candidate);
if (perturbRatio >= 1. || (perturbRatio <= 0.)) { if (perturbRelative >= 1. || (perturbRelative <= 0.)) {
System.err.println("Warning: perturbation ratio should lie between 0 and 1! (NelderMeadSimplex:createNMSPopulation)"); System.err.println("Warning: perturbation ratio should lie between 0 and 1! (NelderMeadSimplex:createNMSPopulation)");
} }
addPerturbedPopulation(perturbRatio, initPop, range, candidate); addPerturbedPopulation(perturbRelative, initPop, range, candidate);
return initPop; return initPop;
} }

View File

@ -1,6 +1,8 @@
package eva2.server.go.strategies; package eva2.server.go.strategies;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedList;
import java.util.Vector; import java.util.Vector;
import eva2.gui.BeanInspector; import eva2.gui.BeanInspector;
@ -13,6 +15,7 @@ import eva2.server.go.enums.PostProcessMethod;
import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.AbstractEAIndividualComparator; 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.PhenotypeMetric; import eva2.server.go.operators.distancemetric.PhenotypeMetric;
import eva2.server.go.operators.paramcontrol.ParamAdaption; import eva2.server.go.operators.paramcontrol.ParamAdaption;
import eva2.server.go.operators.paramcontrol.ParameterControlManager; import eva2.server.go.operators.paramcontrol.ParameterControlManager;
@ -61,7 +64,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
protected Population m_Population = new Population(); protected Population m_Population = new Population();
Object[] sortedPop = null; Object[] sortedPop = null;
protected AbstractEAIndividual m_BestIndividual; protected AbstractEAIndividual m_BestIndividual = null;
protected InterfaceOptimizationProblem m_Problem = new F1Problem(); protected InterfaceOptimizationProblem m_Problem = new F1Problem();
protected boolean m_CheckRange = true; protected boolean m_CheckRange = true;
protected boolean checkSpeedLimit = false; protected boolean checkSpeedLimit = false;
@ -127,6 +130,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
transient protected eva2.gui.Plot m_Plot; transient protected eva2.gui.Plot m_Plot;
private boolean externalInitialPop = false; private boolean externalInitialPop = false;
private static String lastSuccessKey = "successfulUpdate";
// private double lsCandidateRatio=0.25; // private double lsCandidateRatio=0.25;
@ -137,7 +141,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
algType = new SelectedTag("Inertness", "Constriction"); algType = new SelectedTag("Inertness", "Constriction");
algType.setSelectedTag(1); algType.setSelectedTag(1);
setWithConstriction(getPhi1(), getPhi2()); setConstriction(getPhi1(), getPhi2());
hideHideable(); hideHideable();
} }
@ -224,6 +228,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
// evaluation needs to be done here now, as its omitted if reset is false // evaluation needs to be done here now, as its omitted if reset is false
initDefaults(this.m_Population); initDefaults(this.m_Population);
this.evaluatePopulation(this.m_Population); this.evaluatePopulation(this.m_Population);
if (m_BestIndividual == null) m_BestIndividual = m_Population.getBestEAIndividual();
initByPopulation(null, false); initByPopulation(null, false);
externalInitialPop = false; externalInitialPop = false;
} }
@ -673,8 +678,9 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
AbstractEAIndividual indy = (AbstractEAIndividual)pop.get(i); AbstractEAIndividual indy = (AbstractEAIndividual)pop.get(i);
if (isIndividualToUpdate(indy)) { if (isIndividualToUpdate(indy)) {
updateIndProps(indy, indy); updateIndProps(indy, indy);
indy.putData(lastSuccessKey , indy.getData(partVelKey));
// System.err.println("updated " + i + " - "+ getParticleInfo(indy)); // System.err.println("updated " + i + " - "+ getParticleInfo(indy));
} } else indy.putData(lastSuccessKey, null);
} }
} }
@ -768,7 +774,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
double[] accel, curVelocity = new double[lastVelocity.length]; double[] accel, curVelocity = new double[lastVelocity.length];
if (useAlternative) { if (useAlternative) {
accel = getAccelerationAlternative(personalBestPos, neighbourBestPos, curPosition, range); accel = getAccelerationAlternative(index, personalBestPos, neighbourBestPos, curPosition, range);
} else { } else {
accel = getAcceleration(personalBestPos, neighbourBestPos, curPosition, range); accel = getAcceleration(personalBestPos, neighbourBestPos, curPosition, range);
} }
@ -801,33 +807,75 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
return accel; return accel;
} }
protected double[] getAccelerationAlternative(double[] personalBestPos, double[] neighbourBestPos, double[] curPosition, double[][] range) { protected double[] getAccelerationAlternative(int index, double[] personalBestPos, double[] neighbourBestPos, double[] curPosition, double[][] range) {
double[] accel = new double[curPosition.length]; double[] accel = getAcceleration(personalBestPos, neighbourBestPos, curPosition, range);
double chi; double[] successfulVel = getSuccessfulVel(index);
// double succW = 0.5;
Matrix cogVecB = new Matrix(curPosition.length, 1); if (successfulVel!=null) {
Matrix socVecB = new Matrix(curPosition.length, 1); Mathematics.vvAdd(accel, successfulVel, accel);
Mathematics.svMult(0.5, accel, accel);
for (int i = 0; i < personalBestPos.length; i++) {
cogVecB.set(i, 0, (personalBestPos[i]-curPosition[i]));
socVecB.set(i, 0, (neighbourBestPos[i]-curPosition[i]));
}
Matrix cogRandB = getOrientedGaussianRandomVectorB(cogVecB, 5);
Matrix socRandB = getOrientedGaussianRandomVectorB(socVecB, 5);
for (int i = 0; i < curPosition.length; i++) {
if (algType.getSelectedTag().getID()==1) chi=m_InertnessOrChi;
else chi = 1.;
// the component from the cognition model
// accel[i] = this.m_Phi1*chi*/*RNG.randomDouble(0,1)**/cogRand.getElement(i);
accel[i] = this.m_Phi1*chi*/*RNG.randomDouble(0,1)**/cogRandB.get(i,0);
// the component from the social model
// accel[i] += this.m_Phi2*chi*/*RNG.randomDouble(0,1)**/socRand.getElement(i);
accel[i] += this.m_Phi2*chi*/*RNG.randomDouble(0,1)**/socRandB.get(i,0);
} }
return accel; return accel;
} }
private double[] getSuccessfulVel(int index) {
if (true) {
return (double[])m_Population.getEAIndividual(index).getData(lastSuccessKey);
} else { // random one
ArrayList<Integer> successes = new ArrayList<Integer>();
for (int i = 0; i < this.m_Population.size(); i++) {
double[] succVel = (double[])m_Population.getEAIndividual(i).getData(lastSuccessKey);
if (succVel!=null) successes.add(new Integer(i));
}
if (successes.size()>0) {
int i = successes.get(RNG.randomInt(successes.size()));
return (double[])m_Population.getEAIndividual(i).getData(lastSuccessKey);
} else return null;
}
}
// protected double[] getAccelerationAlternative(double[] personalBestPos, double[] neighbourBestPos, double[] curPosition, double[][] range) {
// double[] accel = new double[curPosition.length];
// double chi;
//
// if (algType.getSelectedTag().getID()==1) chi=m_InertnessOrChi;
// else chi = 1.;
//
// boolean rotatedVect=false;
// if (rotatedVect) {
// Matrix cogVecB = new Matrix(curPosition.length, 1);
// Matrix socVecB = new Matrix(curPosition.length, 1);
// for (int i = 0; i < personalBestPos.length; i++) {
// cogVecB.set(i, 0, (personalBestPos[i]-curPosition[i]));
// socVecB.set(i, 0, (neighbourBestPos[i]-curPosition[i]));
// }
// Matrix cogRandB = getOrientedGaussianRandomVectorB(cogVecB, 5);
// Matrix socRandB = getOrientedGaussianRandomVectorB(socVecB, 5);
//
// for (int i = 0; i < curPosition.length; i++) {
// // the component from the cognition model
// // accel[i] = this.m_Phi1*chi*/*RNG.randomDouble(0,1)**/cogRand.getElement(i);
// accel[i] = this.m_Phi1*chi*/*RNG.randomDouble(0,1)**/cogRandB.get(i,0);
// // the component from the social model
// // accel[i] += this.m_Phi2*chi*/*RNG.randomDouble(0,1)**/socRand.getElement(i);
// accel[i] += this.m_Phi2*chi*/*RNG.randomDouble(0,1)**/socRandB.get(i,0);
// }
// return accel;
// } else {
// double sPB = RNG.randomDouble();
// double sNB = 1.-sPB;
// double[] mean= personalBestPos.clone();
// Mathematics.svMult(sPB, mean);
// Mathematics.svvAddScaled(sNB, neighbourBestPos, mean, mean); // middle position
// double stddev = chi*EuclideanMetric.euclideanDistance(personalBestPos, neighbourBestPos)/3.; // std.dev is one third of the distance
// double[] gausRnd = getGaussianVector(mean, stddev);
// for (int i=0; i<accel.length; i++) {
// accel[i] = (gausRnd[i] - curPosition[i]);
// }
// return accel;
// }
// }
// public static void main(String[] args) { // public static void main(String[] args) {
// ParticleSwarmOptimization pso = new ParticleSwarmOptimization(); // ParticleSwarmOptimization pso = new ParticleSwarmOptimization();
// GVector tmp, vec = new GVector(5); // GVector tmp, vec = new GVector(5);
@ -886,6 +934,13 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
return resVec; return resVec;
} }
protected double[] getGaussianVector(double[] mean, double dev) {
double[] res = new double[mean.length];
RNG.gaussianVector(dev, res, false);
Mathematics.vvAdd(mean, res, res);
return res;
}
public static double project(double min, double max, double val) { public static double project(double min, double max, double val) {
if (val < min) return min; if (val < min) return min;
else if (val > max) return max; else if (val > max) return max;
@ -1593,6 +1648,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
if (TRACE) System.err.println("init indy " + i + " " + AbstractEAIndividual.getDefaultDataString(indy)); if (TRACE) System.err.println("init indy " + i + " " + AbstractEAIndividual.getDefaultDataString(indy));
} }
} }
m_BestIndividual = pop.getBestEAIndividual();
} }
public String populationTipText() { public String populationTipText() {
return "Edit the properties of the population used."; return "Edit the properties of the population used.";
@ -1648,8 +1704,8 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
} }
/** /**
* Set the inertness parameter so as to resemble the constriction scheme. Use this before * Set the phi values as well as the inertness parameter so as to resemble the constriction scheme.
* calling the setAsTau methods. The constriction scheme calculates the speed update in the following * The constriction scheme calculates the speed update in the following
* way: v(t+1) = Chi * ( v(t) + tau1*u1*(p-x(t)) * tau2*u2*(g-x(t))) * way: v(t+1) = Chi * ( v(t) + tau1*u1*(p-x(t)) * tau2*u2*(g-x(t)))
* with u1, u2 random variables in (0,1) and tau1 and tau2 usually set to 2.05. The sum tau1 and tau2 * with u1, u2 random variables in (0,1) and tau1 and tau2 usually set to 2.05. The sum tau1 and tau2
* must be greater than 4. The Chi parameter (constriction) is set as in * must be greater than 4. The Chi parameter (constriction) is set as in
@ -1662,11 +1718,14 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
* @param tau1 * @param tau1
* @param tau2 * @param tau2
*/ */
protected void setWithConstriction(double tau1, double tau2) { protected void setConstriction(double tau1, double tau2) {
double pSum = tau1+tau2; double pSum = tau1+tau2;
if (pSum <= 4) { if (pSum <= 4) {
System.err.println("error, invalid tauSum value in PSO::setWithConstriction"); System.err.println("error, invalid tauSum value in PSO::setWithConstriction");
} else { } else {
if (!getAlgoType().isSelectedString("Constriction")) System.err.println("Warning, PSO algorithm variant constriction expected!");
m_Phi1=tau1;
m_Phi2=tau2;
setInertnessOrChi(2./(Math.abs(2-pSum-Math.sqrt((pSum*pSum)-(4*pSum))))); setInertnessOrChi(2./(Math.abs(2-pSum-Math.sqrt((pSum*pSum)-(4*pSum)))));
} }
} }
@ -1691,7 +1750,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
*/ */
public void setPhi1 (double l) { public void setPhi1 (double l) {
this.m_Phi1 = l; this.m_Phi1 = l;
if (algType.getSelectedTag().getID() == 1) setWithConstriction(getPhi1(), getPhi2()); if (algType.getSelectedTag().getID() == 1) setConstriction(getPhi1(), getPhi2());
} }
public double getPhi1() { public double getPhi1() {
return this.m_Phi1; return this.m_Phi1;
@ -1705,7 +1764,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
*/ */
public void setPhi2 (double l) { public void setPhi2 (double l) {
this.m_Phi2 = l; this.m_Phi2 = l;
if (algType.getSelectedTag().getID() == 1) setWithConstriction(getPhi1(), getPhi2()); if (algType.getSelectedTag().getID() == 1) setConstriction(getPhi1(), getPhi2());
} }
public double getPhi2() { public double getPhi2() {
return this.m_Phi2; return this.m_Phi2;
@ -1723,7 +1782,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
public void setPhiValues(double phi1, double phi2) { public void setPhiValues(double phi1, double phi2) {
m_Phi1 = phi1; m_Phi1 = phi1;
m_Phi2 = phi2; m_Phi2 = phi2;
if (algType.isSelectedString("Constriction")) setWithConstriction(phi1, phi2); if (algType.isSelectedString("Constriction")) setConstriction(phi1, phi2);
} }
/** /**
@ -1778,7 +1837,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
*/ */
public void setAlgoType(SelectedTag s) { public void setAlgoType(SelectedTag s) {
this.algType = s; this.algType = s;
if (s.getSelectedTag().getID() == 1) setWithConstriction(getPhi1(), getPhi2()); if (s.getSelectedTag().getID() == 1) setConstriction(getPhi1(), getPhi2());
} }
public SelectedTag getAlgoType() { public SelectedTag getAlgoType() {
@ -1956,7 +2015,10 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
for (int i=0; i<population.size(); i++) { for (int i=0; i<population.size(); i++) {
double[] personalBestPos = (double[]) population.getEAIndividual(i).getData(partBestPosKey); double[] personalBestPos = (double[]) population.getEAIndividual(i).getData(partBestPosKey);
double[] personalBestfit = (double[]) population.getEAIndividual(i).getData(partBestFitKey); double[] personalBestfit = (double[]) population.getEAIndividual(i).getData(partBestFitKey);
double relDiff = (personalBestfit[0]-((InterfaceProblemDouble)m_Problem).eval(personalBestPos)[0])/personalBestfit[0];
double relDiff;
if (personalBestfit[0]!=0) relDiff = (personalBestfit[0]-((InterfaceProblemDouble)m_Problem).eval(personalBestPos)[0])/personalBestfit[0];
else relDiff=(personalBestfit[0]-((InterfaceProblemDouble)m_Problem).eval(personalBestPos)[0]); // absolute diff in this case
// if (personalBestfit[0]!=((InterfaceProblemDouble)m_Problem).eval(personalBestPos)[0]) { // if (personalBestfit[0]!=((InterfaceProblemDouble)m_Problem).eval(personalBestPos)[0]) {
if (Math.abs(relDiff)>1e-20) { if (Math.abs(relDiff)>1e-20) {
System.err.println("Warning: mismatching best fitness by " + relDiff); System.err.println("Warning: mismatching best fitness by " + relDiff);

View File

@ -1,5 +1,6 @@
package eva2.server.stat; package eva2.server.stat;
import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -14,7 +15,6 @@ import eva2.server.go.IndividualInterface;
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.InterfaceDistanceMetric; import eva2.server.go.operators.distancemetric.InterfaceDistanceMetric;
import eva2.server.go.populations.InterfaceSolutionSet;
import eva2.server.go.populations.Population; import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceAdditionalPopulationInformer; import eva2.server.go.problems.InterfaceAdditionalPopulationInformer;
import eva2.server.go.strategies.InterfaceOptimizer; import eva2.server.go.strategies.InterfaceOptimizer;
@ -107,13 +107,18 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
* @param infoString * @param infoString
*/ */
protected void initOutput(String infoString) { protected void initOutput(String infoString) {
SimpleDateFormat formatter = new SimpleDateFormat("E'_'yyyy.MM.dd'_at_'HH.mm.ss"); String startDate = getDateString();
String startDate = formatter.format(new Date());
// open the result file: // open the result file:
if (doFileOutput() // not "text-window only" if (doFileOutput() // not "text-window only"
&& (m_StatsParams.getOutputVerbosity().getSelectedTagID() > StatsParameter.VERBOSITY_NONE)) { // verbosity accordingly high && (m_StatsParams.getOutputVerbosity().getSelectedTagID() > StatsParameter.VERBOSITY_NONE)) { // verbosity accordingly high
//!resFName.equalsIgnoreCase("none") && !resFName.equals("")) { //!resFName.equalsIgnoreCase("none") && !resFName.equals("")) {
String fname = makeOutputFileName(m_StatsParams.getResultFilePrefix(), infoString, startDate); String fnameBase = makeOutputFileName(m_StatsParams.getResultFilePrefix(), infoString, startDate);
int cnt=0;
String fname = fnameBase;
while (new File(fname).exists()) {
cnt++;
fname=fnameBase+"."+cnt;
}
if (TRACE) System.out.println("FileName =" + fname); if (TRACE) System.out.println("FileName =" + fname);
try { try {
resultOut = new PrintWriter(new FileOutputStream(fname)); resultOut = new PrintWriter(new FileOutputStream(fname));
@ -126,6 +131,16 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
} else resultOut = null; } else resultOut = null;
} }
/**
* Return a simple String describing the current date and time.
* @return
*/
public static String getDateString() {
SimpleDateFormat formatter = new SimpleDateFormat("E'_'yyyy.MM.dd'_at_'HH.mm.ss");
String dt = formatter.format(new Date());
return dt;
}
protected boolean doFileOutput() { protected boolean doFileOutput() {
return (m_StatsParams.getOutputTo().getSelectedTagID()!=1); // not "text-window only" return (m_StatsParams.getOutputTo().getSelectedTagID()!=1); // not "text-window only"
} }
@ -319,9 +334,7 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
if (TRACE) if (TRACE)
System.out.println("End of run"); System.out.println("End of run");
if (resultOut != null) { if (resultOut != null) {
SimpleDateFormat formatter = new SimpleDateFormat( String StopDate = getDateString();
"E'_'yyyy.MM.dd'_at_'hh:mm:ss");
String StopDate = formatter.format(new Date());
resultOut.println("StopDate:" + StopDate); resultOut.println("StopDate:" + StopDate);
resultOut.close(); resultOut.close();
} }
@ -686,11 +699,13 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
} }
// meanCollection.set(pop.getGenerations()-1, means); // meanCollection.set(pop.getGenerations()-1, means);
lastSols = (opt!=null) ? new Population(opt.getAllSolutions()) : pop; lastSols = (opt!=null) ? new Population(opt.getAllSolutions().getSolutions()) : pop;
if (doTextOutput()) { if (doTextOutput()) {
Pair<String,Double[]> addInfo = getOutputLine(informerList, lastSols); Pair<String,Double[]> addInfo = getOutputLine(informerList, lastSols);
if (printLineByVerbosity(runIterCnt)) printToTextListener(addInfo.head()+'\n'); if (printLineByVerbosity(runIterCnt)) {
printToTextListener(addInfo.head()+'\n');
}
// updateAdditionalInfo(addInfo.tail()); // updateAdditionalInfo(addInfo.tail());
if (addInfo.tail()!=null) { if (addInfo.tail()!=null) {
additionalInfoSums = updateAdditionalInfo(additionalInfoSums, addInfo.tail()); additionalInfoSums = updateAdditionalInfo(additionalInfoSums, addInfo.tail());
@ -728,7 +743,14 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
} }
private boolean isKthRun(int i, int k) { private boolean isKthRun(int i, int k) {
return (i % k) == 0; // ingeniously shifting i by two since the stats counter starts at 0
// after two evaluations have already happened: initialization and first optimization
// this allows the last iteration to be within the displayed set if k is a divisor of whole iterations as expected
if ((i==0) || (k==0)) return true;
else {
if (i<=2) return (i % k) == 0; // show more at the beginning (always first time)
else return ((i+2) % k) == 0;
}
} }
private boolean printHeaderByVerbosity() { private boolean printHeaderByVerbosity() {

View File

@ -1,5 +1,6 @@
package eva2.tools; package eva2.tools;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.StringTokenizer; import java.util.StringTokenizer;
@ -72,7 +73,7 @@ public class StringTools {
* with their arities. Returns for each key a value depending on arity and whether it was found. * with their arities. Returns for each key a value depending on arity and whether it was found.
* For any key, if it was not found null is returned as value. Its index in the keys array is contained * For any key, if it was not found null is returned as value. Its index in the keys array is contained
* in the returned integer array. * in the returned integer array.
* For any key, if it was found, the corresponding value is either Boolean(true) for zero-arity-keys * For any key, if it was found, the corresponding value is a String containing "true" for zero-arity-keys
* or a String array of length of the arity containing the arguments to the key. * or a String array of length of the arity containing the arguments to the key.
* *
* @param args * @param args
@ -88,16 +89,30 @@ public class StringTools {
for (int i=0; i<args.length; i++) { // loop all arguments for (int i=0; i<args.length; i++) { // loop all arguments
boolean found=false; boolean found=false;
for (int k=0; k<keys.length; k++) { // loop all keys for (int k=0; k<keys.length; k++) { // loop all keys
if (found || (i>=args.length)) break; // if a key was found look at next argument
if ((ignoreCase && (args[i].equalsIgnoreCase(keys[k]))) if ((ignoreCase && (args[i].equalsIgnoreCase(keys[k])))
|| (!ignoreCase && (args[i].equals(keys[k])))) { // if the key was found || (!ignoreCase && (args[i].equals(keys[k])))) { // if the key was found
found=true; found=true;
if (arities[k]==0) values[k]=new Boolean(true); // and its zero-arity, just return true as its value if (arities[k]==0) values[k]=new String("true"); // and its zero-arity, just return true as its value
else { // else return an array of size arity with following strings else { // else return an array of size arity with following strings
values[k]=new String[arities[k]]; try {
for (int j=0; j<arities[k]; j++) { if (arities[k]==1) {
i++; values[k]=args[i+1];
((String[])values[k])[j]=args[i]; } else { // create String array and fill with following args depending on arity
values[k]=new String[arities[k]];
if (arities[k]>0) {
for (int j=0; j<arities[k]; j++) {
((String[])values[k])[j]=args[i+j+1];
}
i+=(arities[k]-1); // jump one more for every arity beyond 1
}
} }
} catch (ArrayIndexOutOfBoundsException e) {
String errMsg = "Not enough parameters for option "+ keys[k] + ", expected number of arguments: " + arities[k];
System.err.println(errMsg);
throw new RuntimeException(errMsg);
}
i++; // jump one cause we had at least arity 1
} }
} }
} }
@ -106,6 +121,31 @@ public class StringTools {
return unrecogs.toArray(new Integer[unrecogs.size()]); return unrecogs.toArray(new Integer[unrecogs.size()]);
} }
/**
* Store the arguments in a hash map.
*
* @see #parseArguments(String[], String[], int[], Object[], boolean)
* @param args
* @param keys
* @param arities
* @param ignoreCase
* @return
*/
public static HashMap<String, Object> parseArguments(String[] args, String[] keys, int[] arities, boolean ignoreCase, boolean printErrorsOnUnrecog) {
Object[] values = new Object[keys.length];
Integer[] unrecogs = parseArguments(args, keys, arities, values, ignoreCase);
if (printErrorsOnUnrecog) {
if (unrecogs.length>0) {
System.err.println("Unrecognized command line options: ");
for (int i=0; i<unrecogs.length; i++) System.err.println(" " + args[unrecogs[i]]);
}
}
HashMap<String, Object> map = new HashMap<String, Object>();
for (int i=0; i<keys.length; i++) {
map.put(keys[i], values[i]);
}
return map;
}
/** /**
* Check whether an object is a valid String array and if so return the i-th String. * Check whether an object is a valid String array and if so return the i-th String.

View File

@ -122,10 +122,10 @@ private static final boolean TRACE = false;
*/ */
public DRectangle getDRectangle(){ public DRectangle getDRectangle(){
DRectangle rect = (DRectangle)visible_rect.clone(); DRectangle rect = (DRectangle)visible_rect.clone();
if( min_x != null ) rect.x = Math.max(rect.x, getMinX() ); if( min_x != null ) rect.setX(Math.max(rect.getX(), getMinX() ));
if( min_y != null ) rect.y = Math.max(rect.y, getMinY() ); if( min_y != null ) rect.setY(Math.max(rect.getY(), getMinY() ));
if( max_x != null ) rect.width = Math.min(rect.width, getMaxX() - getMinX()); if( max_x != null ) rect.setWidth(Math.min(rect.getWidth(), getMaxX() - getMinX()));
if( max_y != null ) rect.height = Math.min(rect.height, getMaxY() - getMinY()); if( max_y != null ) rect.setHeight(Math.min(rect.getHeight(), getMaxY() - getMinY()));
return rect; return rect;
} }
@ -135,7 +135,7 @@ private static final boolean TRACE = false;
* @return DRectangle the size and position of the visible area * @return DRectangle the size and position of the visible area
*/ */
public SlimRect getSlimRectangle(){ public SlimRect getSlimRectangle(){
SlimRect srect = new SlimRect(visible_rect.x, visible_rect.y, visible_rect.width, visible_rect.height); SlimRect srect = new SlimRect(visible_rect.getX(), visible_rect.getY(), visible_rect.getWidth(), visible_rect.getHeight());
if( min_x != null ) srect.x = Math.max(srect.x, getMinX() ); if( min_x != null ) srect.x = Math.max(srect.x, getMinX() );
if( min_y != null ) srect.y = Math.max(srect.y, getMinY() ); if( min_y != null ) srect.y = Math.max(srect.y, getMinY() );
if( max_x != null ) srect.width = Math.min(srect.width, getMaxX() - getMinX()); if( max_x != null ) srect.width = Math.min(srect.width, getMaxX() - getMinX());
@ -186,7 +186,7 @@ private static final boolean TRACE = false;
"You shopuld never try to set an empty rectangle\n" "You shopuld never try to set an empty rectangle\n"
+ "as the visible rectangle of an DArea" ); + "as the visible rectangle of an DArea" );
if( !rect.equals( visible_rect ) && rect.width > 0 && rect.height > 0 ){ if( !rect.equals( visible_rect ) && rect.getWidth() > 0 && rect.getHeight() > 0 ){
auto_focus = false; auto_focus = false;
visible_rect = (DRectangle)rect.clone(); visible_rect = (DRectangle)rect.clone();
repaint(); repaint();
@ -278,7 +278,7 @@ private static final boolean TRACE = false;
* @param mix the minimal x-value * @param mix the minimal x-value
*/ */
public void setMinX( double mix ){ public void setMinX( double mix ){
if( mix > min_rect.x ) throw if( mix > min_rect.getX() ) throw
new IllegalArgumentException( new IllegalArgumentException(
"Mimimal y-value axes intersects minmal rectangle."); "Mimimal y-value axes intersects minmal rectangle.");
min_x = new Double( mix ); min_x = new Double( mix );
@ -309,7 +309,7 @@ private static final boolean TRACE = false;
* @param miy the minimal y-value * @param miy the minimal y-value
*/ */
public void setMinY( double miy ){ public void setMinY( double miy ){
if( miy > min_rect.y ) throw if( miy > min_rect.getY() ) throw
new IllegalArgumentException( new IllegalArgumentException(
"Mimimal y-value axes intersects minmal rectangle."); "Mimimal y-value axes intersects minmal rectangle.");
min_y = new Double( miy ); min_y = new Double( miy );
@ -341,7 +341,7 @@ private static final boolean TRACE = false;
* @param max the maximal x-value * @param max the maximal x-value
*/ */
public void setMaxX( double max ){ public void setMaxX( double max ){
if( max < min_rect.x + min_rect.width ) throw if( max < min_rect.getX() + min_rect.getWidth() ) throw
new IllegalArgumentException( new IllegalArgumentException(
"Maximal x-value axes intersects minmal rectangle."); "Maximal x-value axes intersects minmal rectangle.");
max_x = new Double( max ); max_x = new Double( max );
@ -373,7 +373,7 @@ private static final boolean TRACE = false;
* @param may the maximal y-value * @param may the maximal y-value
*/ */
public void setMaxY( double may ){ public void setMaxY( double may ){
if( may < min_rect.y + min_rect.height ) throw if( may < min_rect.getY() + min_rect.getHeight() ) throw
new IllegalArgumentException( new IllegalArgumentException(
"Maximal y-value axes intersects minmal rectangle."); "Maximal y-value axes intersects minmal rectangle.");
max_y = new Double( may ); max_y = new Double( may );
@ -432,8 +432,10 @@ private static final boolean TRACE = false;
new IllegalArgumentException("Cannot repaint a null DRectangle"); new IllegalArgumentException("Cannot repaint a null DRectangle");
if( r.isAll() || auto_focus ) repaint(); if( r.isAll() || auto_focus ) repaint();
else{ else{
Point p1 = measures.getPoint( r.x, r.y ), Point p1 = measures.getPoint( r.getX(), r.getY() ),
p2 = measures.getPoint( r.x + r.width, r.y + r.height); p2 = measures.getPoint( r.getX() + r.getWidth(), r.getY() + r.getHeight());
// Point p1 = measures.getPoint( r.x, r.y ),
// p2 = measures.getPoint( r.x + r.width, r.y + r.height);
if( p1 == null || p2 == null ) repaint(); if( p1 == null || p2 == null ) repaint();
else { else {
DBorder b = getDBorder(); DBorder b = getDBorder();
@ -690,8 +692,8 @@ private static final boolean TRACE = false;
return; return;
} }
else{ else{
grid.setDistances(ScaledBorder.aBitBigger( grid.rectangle.width / max_grid ), grid.setDistances(ScaledBorder.aBitBigger( grid.rectangle.getWidth() / max_grid ),
ScaledBorder.aBitBigger( grid.rectangle.height / max_grid )); ScaledBorder.aBitBigger( grid.rectangle.getHeight() / max_grid ));
} }
} }
grid.paint( m ); grid.paint( m );

View File

@ -96,8 +96,8 @@ public class DGrid extends DComponent
DPoint p1, p2; DPoint p1, p2;
DLine l; DLine l;
minX=Mathematics.firstMultipleAbove(rectangle.x, hor_dist); minX=Mathematics.firstMultipleAbove(rectangle.getX(), hor_dist);
minY=Mathematics.firstMultipleAbove(rectangle.y, ver_dist); minY=Mathematics.firstMultipleAbove(rectangle.getY(), ver_dist);
// minX = (int)( rectangle.x / hor_dist ); // minX = (int)( rectangle.x / hor_dist );
// if( minX * hor_dist <= rectangle.x ) minX++; // if( minX * hor_dist <= rectangle.x ) minX++;
// minX *= hor_dist; // minX *= hor_dist;
@ -105,18 +105,18 @@ public class DGrid extends DComponent
// if( minY * ver_dist <= rectangle.y ) minY++; // if( minY * ver_dist <= rectangle.y ) minY++;
// minY *= ver_dist; // minY *= ver_dist;
p1 = new DPoint( 0, rectangle.y ); p1 = new DPoint( 0, rectangle.getY() );
p2 = new DPoint( 0, rectangle.y + rectangle.height ); p2 = new DPoint( 0, rectangle.getY() + rectangle.getHeight() );
for( pos = minX; pos<=rectangle.x + rectangle.width; pos += hor_dist ){ for( pos = minX; pos<=rectangle.getX() + rectangle.getWidth(); pos += hor_dist ){
p1.x = p2.x = pos; p1.x = p2.x = pos;
l = new DLine( p1, p2, color ); l = new DLine( p1, p2, color );
l.paint( m ); l.paint( m );
} }
p1.x = rectangle.x; p1.x = rectangle.getX();
p2.x = p1.x + rectangle.width; p2.x = p1.x + rectangle.getWidth();
pos = minY; pos = minY;
while ( pos<=rectangle.y + rectangle.height){ while ( pos<=rectangle.getY() + rectangle.getHeight()){
p1.y = p2.y = pos; p1.y = p2.y = pos;
l = new DLine( p1, p2, color ); l = new DLine( p1, p2, color );
l.paint( m ); l.paint( m );

View File

@ -24,7 +24,8 @@ import java.awt.* ;
public class DRectangle extends DComponent public class DRectangle extends DComponent
{ {
public double x, y, width, height; private double x, y;
private double width, height;
public static final int PART = 0, ALL = 1, EMPTY = 2; public static final int PART = 0, ALL = 1, EMPTY = 2;
protected int status; protected int status;
protected Color fillColor; protected Color fillColor;
@ -38,11 +39,11 @@ public class DRectangle extends DComponent
super(true); super(true);
this.x = x; this.x = x;
this.y = y; this.y = y;
if( width < 0 ) throw if( width < 0 || Double.isInfinite(width) || Double.isNaN(width)) throw
new IllegalArgumentException("Width of a DRectangle has to be >= 0"); new IllegalArgumentException("Width of a DRectangle is invalid (" + width + ")");
this.width = width; this.width = width;
if( height < 0 ) throw if( height < 0 || Double.isInfinite(height) || Double.isNaN(height)) throw
new IllegalArgumentException("Height of a DRectangle has to be >= 0"); new IllegalArgumentException("Height of a DRectangle is invalid (" + height + ")");
this.height = height; this.height = height;
status = PART; status = PART;
} }
@ -78,6 +79,31 @@ public class DRectangle extends DComponent
return true; return true;
} }
public double getHeight() { return height; }
public double getWidth() { return width; }
public void setHeight(double h) {
if (Double.isInfinite(h) || Double.isNaN(h)) {
System.err.println("Warning, infinite vaule for height!");
} else height = h;
}
public void setWidth(double w) {
if (Double.isInfinite(w) || Double.isNaN(w)) {
System.err.println("Warning, infinite vaule for width!");
} else width = w;
}
public double getX() { return x; }
public double getY() { return y; }
public void setX(double v) {
if (Double.isInfinite(v) || Double.isNaN(v)) {
System.err.println("Warning, infinite vaule for x!");
} else x = v;
}
public void setY(double v) {
if (Double.isInfinite(v) || Double.isNaN(v)) {
System.err.println("Warning, infinite vaule for y!");
} else y = v;
}
/** /**
* Faster contains withouth checking for ALL or EMPTY status. * Faster contains withouth checking for ALL or EMPTY status.
* *
@ -135,7 +161,9 @@ public class DRectangle extends DComponent
* @return true when the size of the rectangle changed * @return true when the size of the rectangle changed
*/ */
public boolean insert( DPoint p ){ public boolean insert( DPoint p ){
if( p.x == Double.NaN || p.y == Double.NaN ) return false; if( p.x == Double.NaN || p.y == Double.NaN || Double.isInfinite(p.x) || Double.isInfinite(p.y)) {
return false;
}
if( isAll() ) return false; if( isAll() ) return false;
if( contains( p ) ) return false; if( contains( p ) ) return false;
if( isEmpty() ){ if( isEmpty() ){

View File

@ -69,7 +69,7 @@ public class ScaledBorder implements Border
* the size of the source rectangle * the size of the source rectangle
* that means before the values are mdified by scale functions * that means before the values are mdified by scale functions
*/ */
SlimRect src_rect; SlimRect src_rect = null;
/** /**
* the minimal increment of the scales * the minimal increment of the scales
@ -321,7 +321,7 @@ public class ScaledBorder implements Border
g.drawLine( insets.left - marker_length, p.y, insets.left, p.y ); g.drawLine( insets.left - marker_length, p.y, insets.left, p.y );
} }
if (v+src_dY<= v) { if (v+src_dY<= v) {
System.err.println("Overflow error B in ScaledBorder!"); System.err.println("Overflow error B in ScaledBorder! v,src_dY:" + v + ", " + src_dY);
v*=1.01; v*=1.01;
} }
v += src_dY; v += src_dY;
@ -336,6 +336,9 @@ public class ScaledBorder implements Border
if( under_construction ) System.out.println("ScaledBorder.getSrcdY()"); if( under_construction ) System.out.println("ScaledBorder.getSrcdY()");
if( (!do_refresh && src_dY != -1) || !auto_scale_y ) return src_dY; if( (!do_refresh && src_dY != -1) || !auto_scale_y ) return src_dY;
int max = componentHeight / fontMetricsHeight; int max = componentHeight / fontMetricsHeight;
if (Double.isInfinite(src_rect.height) || Double.isInfinite(src_rect.width)) {
System.err.println("Error, infinite value in ScaledBorder:getSrcdY !!");
}
double minsrc_dY = 2 * src_rect.height / (double)max; // die 2 einfach mal so eingesetzt <-------------------------- double minsrc_dY = 2 * src_rect.height / (double)max; // die 2 einfach mal so eingesetzt <--------------------------
src_dY = aBitBigger( minsrc_dY ); src_dY = aBitBigger( minsrc_dY );
if( src_dY < minimal_increment ) src_dY = minimal_increment; if( src_dY < minimal_increment ) src_dY = minimal_increment;
@ -417,7 +420,7 @@ public class ScaledBorder implements Border
* @return the displayable value * @return the displayable value
*/ */
public static double aBitBigger( double min ){ public static double aBitBigger( double min ){
if( min <= 0 ) return 1; if( min <= 0 || Double.isInfinite(min) || Double.isNaN(min)) return 1;
double d = 1; double d = 1;
if( min < d ){ if( min < d ){
while( d * .5 > min ) { while( d * .5 > min ) {

View File

@ -69,7 +69,7 @@ public class SlimRect {
* @return A rectangle representing the intersection or null * @return A rectangle representing the intersection or null
*/ */
public SlimRect getIntersection( DRectangle r ){ public SlimRect getIntersection( DRectangle r ){
return getIntersection(r.x, r.y, r.width, r.height); return getIntersection(r.getX(), r.getY(), r.getWidth(), r.getHeight());
} }
/** /**
@ -105,7 +105,7 @@ public class SlimRect {
* @return true if the two rectangles do not intersect, else false * @return true if the two rectangles do not intersect, else false
*/ */
public boolean hasEmptyIntersection(DRectangle r){ public boolean hasEmptyIntersection(DRectangle r){
return (getIntersection(r.x, r.y, r.width, r.height)==null); return (getIntersection(r.getX(), r.getY(), r.getWidth(), r.getHeight())==null);
} }
/** /**

View File

@ -743,44 +743,82 @@ public class Mathematics {
public static void normalizeSum(double[] v, double[] res) { public static void normalizeSum(double[] v, double[] res) {
svMult(1./sum(v), v, res); svMult(1./sum(v), v, res);
} }
/**
* Return a matrix A which performs the rotation of vec to (1,0,0,...0) if forward is true, else
* return a matrix B which performs the reverted rotation, where B=A' (transposition).
*
* @param vec
* @return
*/
public static Matrix getRotationMatrix(Matrix vec) {
Matrix A = Matrix.identity(vec.getRowDimension(), vec.getRowDimension());
Matrix tmp = Matrix.identity(vec.getRowDimension(), vec.getRowDimension());
Matrix z = (Matrix)vec.clone();
z.multi(1./z.norm2()); // normalize
for (int i=1; i<vec.getRowDimension(); i++) {
double w = Math.atan2(z.get(i,0), z.get(0,0));// calc angle between the projection of x and x0 in x0-xi-plane
// System.out.println("deg: "+(w/Math.PI)*180);
/** // make partial rotation matrix
* Return a matrix A which performs the rotation of vec to (1,0,0,...0) if forward is true, else getRotationEntriesSingleAxis(tmp, 0, i, w);
* return a matrix B which performs the reverted rotation, where B=A' (transposition).
* A = tmp.times(A); // add to resulting rotation
* @param vec z = tmp.times(z); // z is now 0 in i-th component
* @return
*/ // reset tmp matrix to unity
public static Matrix getRotationMatrix(Matrix vec) { resetRotationEntriesSingleAxis(tmp, 0, i);
Matrix A = Matrix.identity(vec.getRowDimension(), vec.getRowDimension()); }
Matrix tmp = Matrix.identity(vec.getRowDimension(), vec.getRowDimension()); return A;
Matrix z = (Matrix)vec.clone(); }
double w, cosw, sinw; public static Matrix getRotationMatrix(double w, int dim) {
Matrix A = Matrix.identity(dim, dim);
z.multi(z.norm2()); // normalize Matrix tmp = Matrix.identity(dim, dim);
for (int i=1; i<dim; i++) {
for (int i=1; i<vec.getRowDimension(); i++) { // System.out.println("deg: "+(w/Math.PI)*180);
w = Math.atan2(z.get(i,0), z.get(0,0));// calc angle between the projection of x and x0 in x0-xi-plane // make partial rotation matrix
getRotationEntriesSingleAxis(tmp, i-1, i, w);
cosw = Math.cos(w); A = tmp.times(A); // add to resulting rotation
sinw = Math.sin(w); // reset tmp matrix to unity
tmp.set(0, 0, cosw); // make partial rotation matrix resetRotationEntriesSingleAxis(tmp, i-1, i);
tmp.set(0, i, sinw); }
tmp.set(i, 0, -sinw); // Matrix vec = new Matrix(dim, 1);
tmp.set(i, i, cosw); // for (int i=0; i<dim; i++) vec.set(i,0, 1);
// vec = A.times(vec);
A = tmp.times(A); // add to resulting rotation // vec = A.times(vec);
z = tmp.times(z); // z is now 0 in i-th component return A;
}
tmp.set(0, 0, 1); // reset tmp matrix to unity
tmp.set(0, i, 0); /**
tmp.set(i, 0, 0); * Set rotation matrix entries along i/j axis. w is expected in radians.
tmp.set(i, i, 1); *
} * @param tmp
return A; * @param i
} * @param j
* @param w
*/
public static void getRotationEntriesSingleAxis(Matrix tmp, int i, int j, double w) {
double cosw = Math.cos(w);
double sinw = Math.sin(w);
tmp.set(i, i, cosw);
tmp.set(i, j, sinw);
tmp.set(j, i, -sinw);
tmp.set(j, j, cosw);
}
/**
* Reset single axis rotation matrix to unity.
*/
public static void resetRotationEntriesSingleAxis(Matrix tmp, int i, int j) {
tmp.set(i, i, 1);
tmp.set(i, j, 0);
tmp.set(j, i, 0);
tmp.set(j, j, 1);
}
/** /**
* Rotate the vector by angle alpha around axis i/j * Rotate the vector by angle alpha around axis i/j
@ -796,7 +834,23 @@ public class Mathematics {
vect[i] = (xi*Math.cos(alpha))-(xj*Math.sin(alpha)); vect[i] = (xi*Math.cos(alpha))-(xj*Math.sin(alpha));
vect[j] = (xi*Math.sin(alpha))+(xj*Math.cos(alpha)); vect[j] = (xi*Math.sin(alpha))+(xj*Math.cos(alpha));
} }
/**
* Rotate a given double vector using a rotation matrix. If the matrix
* is null, x will be returned unchanged. Matrix dimensions must fit.
*
* @param x
* @param rotMatrix
* @return the rotated vector
*/
public static double[] rotate(double[] x, Matrix rotMatrix) {
if (rotMatrix!=null) {
Matrix resVec = rotMatrix.times(new Matrix(x, x.length));
x = resVec.getColumnPackedCopy();
return x;
} else return x;
}
/** /**
* Rotate the vector along all axes by angle alpha or a uniform random value * Rotate the vector along all axes by angle alpha or a uniform random value
* in [-alpha, alpha] if randomize is true. * in [-alpha, alpha] if randomize is true.

View File

@ -4,27 +4,19 @@ import java.util.ArrayList;
import java.util.Random; import java.util.Random;
/** public class RNG {
*
*/
public class RNG extends Random {
/**
*
*/
private static final long serialVersionUID = 1565216859128723844L;
private static Random random; private static Random random;
private static long randomSeed; private static long randomSeed;
/** /**
* *
*/ */
static { static {
randomSeed = System.currentTimeMillis(); randomSeed=System.currentTimeMillis();
random = new Random(randomSeed); random=new Random(randomSeed);
} }
/** /**
* *
*/ */
public static void setRandomSeed(long new_seed) { public static void setRandomSeed(long new_seed) {
// counter++; // counter++;
randomSeed = new_seed; randomSeed = new_seed;
@ -43,23 +35,23 @@ public class RNG extends Random {
} }
/** /**
* *
*/ */
public static void setRandomSeed() { public static void setRandomSeed() {
randomSeed = System.currentTimeMillis(); randomSeed = System.currentTimeMillis();
random = new Random(randomSeed); random = new Random(randomSeed);
} }
/** /**
* *
*/ */
public static void setRandom(Random base_random) { public static void setRandom(Random base_random) {
random = base_random; random = base_random;
} }
/** /**
* *
*/ */
public static long getRandomSeed() { public static long getRandomSeed() {
return randomSeed; return randomSeed;
} }
@ -157,6 +149,25 @@ public class RNG extends Random {
return result; return result;
} }
/** This method returns a evenly distributed int value.
* The boundarys are included.
* @param lo Lower bound.
* @param hi Upper bound.
* @return int
*/
public static int randomInt(Random rand, int lo,int hi) {
if (hi<lo) {
System.err.println("Invalid boundary values! Returning zero.");
return -1;
}
int result = (Math.abs(rand.nextInt())%(hi-lo+1))+lo;
if ((result < lo) || (result > hi)) {
System.err.println("Error, invalid value " + result + " in RNG.randomInt! boundaries were lo/hi: " + lo + " / " + hi);
result = Math.abs(rand.nextInt()%(hi-lo+1))+lo;
}
return result;
}
/** /**
* Returns a random long between 0 and Long.MAX_VALUE-1 (inclusively). * Returns a random long between 0 and Long.MAX_VALUE-1 (inclusively).
*/ */
@ -172,15 +183,15 @@ public class RNG extends Random {
} }
/** /**
* *
*/ */
public static float randomFloat() { public static float randomFloat() {
return random.nextFloat(); return random.nextFloat();
} }
/** /**
* *
*/ */
public static float randomFloat(float lo, float hi) { public static float randomFloat(float lo, float hi) {
return (hi - lo) * random.nextFloat() + lo; return (hi - lo) * random.nextFloat() + lo;
} }
@ -193,19 +204,23 @@ public class RNG extends Random {
} }
/** /**
* *
*/ */
public static double randomDouble(double lo, double hi) { public static double randomDouble(double lo,double hi) {
return (hi - lo) * random.nextDouble() + lo; return (hi-lo)*random.nextDouble()+lo;
}
public static double randomDouble(Random rand, double lo,double hi) {
return (hi-lo)*rand.nextDouble()+lo;
} }
/** /**
* Create a uniform random vector within the given bounds. * Create a uniform random vector within the given bounds.
*/ */
public static double[] randomDoubleArray(double[] lo, double[] hi) { public static double[] randomDoubleArray(double[] lo,double[] hi) {
double[] xin = new double[lo.length]; double[] xin = new double[lo.length];
for (int i = 0; i < lo.length; i++) for (int i=0;i<lo.length;i++)
xin[i] = (hi[i] - lo[i]) * random.nextDouble() + lo[i]; xin[i] = (hi[i]-lo[i])*random.nextDouble()+lo[i];
return xin; return xin;
} }
@ -214,48 +229,50 @@ public class RNG extends Random {
*/ */
public static double[] randomDoubleArray(double[][] range) { public static double[] randomDoubleArray(double[][] range) {
double[] xin = new double[range.length]; double[] xin = new double[range.length];
for (int i = 0; i < xin.length; i++) for (int i=0;i<xin.length;i++)
xin[i] = (range[i][1] - range[i][0]) * random.nextDouble() xin[i] = (range[i][1]-range[i][0])*random.nextDouble()+range[i][0];
+ range[i][0];
return xin; return xin;
} }
/** /**
* Create a uniform random double vector within the given bounds (inclusive) * Create a uniform random double vector within the given bounds (inclusive) in every dimension.
* in every dimension.
* *
* @param lower * @param lower
* @param upper * @param upper
* @param size * @param size
* @return * @return
*/ */
public static double[] randomDoubleArray(double lower, double upper, public static double[] randomDoubleArray(double lower, double upper, int size) {
int size) {
double[] result = new double[size]; double[] result = new double[size];
for (int i = 0; i < result.length; i++) { for (int i = 0; i < result.length; i++) {
result[i] = RNG.randomDouble(lower, upper); result[i] = RNG.randomDouble(lower, upper);
} }
return result; return result;
// double[] xin = new double[size]; // double[] xin = new double[size];
// for (int i=0;i<size;i++) // for (int i=0;i<size;i++)
// xin[i] = (hi-lo)*random.nextDouble()+lo; // xin[i] = (hi-lo)*random.nextDouble()+lo;
// return xin; // return xin;
} }
public static double[] randomDoubleArray(Random rand, double lower, double upper, int size) {
double[] result = new double[size];
for (int i = 0; i < result.length; i++) {
result[i] = RNG.randomDouble(rand, lower, upper);
}
return result;
}
/** /**
* *
*/ */
public static double[] randomDoubleArray(double[] lo, double[] hi, public static double[] randomDoubleArray(double[] lo,double[] hi,double[] xin) {
double[] xin) { //counter++;
// counter++; for (int i=0;i<lo.length;i++)
for (int i = 0; i < lo.length; i++) xin[i] = (hi[i]-lo[i])*random.nextDouble()+lo[i];
xin[i] = (hi[i] - lo[i]) * random.nextDouble() + lo[i];
return xin; return xin;
} }
/** /**
* Create a uniform random integer vector within the given bounds * Create a uniform random integer vector within the given bounds (inclusive) in every dimension.
* (inclusive) in every dimension.
* *
* @param n * @param n
* @param lower * @param lower
@ -270,17 +287,24 @@ public class RNG extends Random {
return result; return result;
} }
public static int[] randomIntArray(Random rand, int lower, int upper, int size) {
int[] result = new int[size];
for (int i = 0; i < result.length; i++) {
result[i] = RNG.randomInt(rand, lower, upper);
}
return result;
}
/** /**
* *
*/ */
public static boolean randomBoolean() { public static boolean randomBoolean() {
// counter++; // counter++;
return (randomInt() == 1); return (randomInt() == 1);
} }
/** /**
* *
*/ */
public static int randomBit() { public static int randomBit() {
// counter++; // counter++;
return randomInt(); return randomInt();
@ -298,8 +322,8 @@ public class RNG extends Random {
} }
/** /**
* *
*/ */
public static float gaussianFloat(float dev) { public static float gaussianFloat(float dev) {
// counter++; // counter++;
return (float) random.nextGaussian() * dev; return (float) random.nextGaussian() * dev;
@ -318,16 +342,16 @@ public class RNG extends Random {
} }
/** /**
* *
*/ */
public static float exponentialFloat(float mean) { public static float exponentialFloat(float mean) {
// counter++; // counter++;
return (float) (-mean * Math.log(randomDouble())); return (float) (-mean * Math.log(randomDouble()));
} }
/** /**
* *
*/ */
public static double exponentialDouble(double mean) { public static double exponentialDouble(double mean) {
// counter++; // counter++;
return -mean * Math.log(randomDouble()); return -mean * Math.log(randomDouble());