Merging MK branch revs. 214,447-448,451,452,456-459.
This commit is contained in:
parent
edbaf50447
commit
2f33a002e2
@ -21,9 +21,11 @@ import eva2.server.go.operators.archiving.InformationRetrievalInserting;
|
||||
import eva2.server.go.operators.archiving.InterfaceArchiving;
|
||||
import eva2.server.go.operators.archiving.InterfaceInformationRetrieval;
|
||||
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.InterfaceCrossover;
|
||||
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.MutateESCovarianceMatrixAdaption;
|
||||
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.MonteCarloSearch;
|
||||
import eva2.server.go.strategies.MultiObjectiveEA;
|
||||
import eva2.server.go.strategies.NelderMeadSimplex;
|
||||
import eva2.server.go.strategies.ParticleSwarmOptimization;
|
||||
import eva2.server.go.strategies.PopulationBasedIncrementalLearning;
|
||||
import eva2.server.go.strategies.SimulatedAnnealing;
|
||||
@ -117,6 +120,12 @@ public class OptimizerFactory {
|
||||
|
||||
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.
|
||||
*
|
||||
@ -424,7 +433,7 @@ public class OptimizerFactory {
|
||||
* @param popsize
|
||||
* @param phi1
|
||||
* @param phi2
|
||||
* @param k
|
||||
* @param speedLim
|
||||
* @param listener
|
||||
* @param topology
|
||||
* @see ParticleSwarmOpimization
|
||||
@ -433,9 +442,8 @@ public class OptimizerFactory {
|
||||
*/
|
||||
public static final ParticleSwarmOptimization createParticleSwarmOptimization(
|
||||
AbstractOptimizationProblem problem, int popsize, double phi1,
|
||||
double phi2, double k,
|
||||
InterfacePopulationChangedEventListener listener,
|
||||
PSOTopologyEnum selectedTopology) {
|
||||
double phi2, double speedLim, PSOTopologyEnum selectedTopology, int topologyRange,
|
||||
InterfacePopulationChangedEventListener listener) {
|
||||
|
||||
problem.initProblem();
|
||||
|
||||
@ -450,9 +458,10 @@ public class OptimizerFactory {
|
||||
pso.getPopulation().setTargetSize(popsize);
|
||||
pso.setPhi1(phi1);
|
||||
pso.setPhi2(phi2);
|
||||
pso.setSpeedLimit(k);
|
||||
pso.setSpeedLimit(speedLim);
|
||||
// pso.getTopology().setSelectedTag(selectedTopology);
|
||||
pso.setTopology(selectedTopology);
|
||||
pso.setTopologyRange(topologyRange);
|
||||
pso.addPopulationChangedEventListener(listener);
|
||||
pso.init();
|
||||
|
||||
@ -581,13 +590,13 @@ public class OptimizerFactory {
|
||||
case HILLCL:
|
||||
return hillClimbing(problem);
|
||||
case CBN_ES:
|
||||
return cbnES(problem);
|
||||
return standardCbnES(problem);
|
||||
case CL_HILLCL:
|
||||
return stdClusteringHillClimbing(problem);
|
||||
case CMA_ES_IPOP:
|
||||
return cmaESIPOP(problem);
|
||||
case CBN_GA:
|
||||
return cbnGA(problem);
|
||||
return standardCbnGA(problem);
|
||||
case PBIL:
|
||||
return standardPBIL(problem);
|
||||
default:
|
||||
@ -1171,31 +1180,99 @@ public class OptimizerFactory {
|
||||
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();
|
||||
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();
|
||||
es.setMu(15);
|
||||
es.setLambda(50);
|
||||
es.setPlusStrategy(false);
|
||||
cbn.setOptimizer(es);
|
||||
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());
|
||||
return createCbn(problem, es, cbnDefaultClusterSigma, cbnDefaultMinGroupSize, cbnDefaultMaxGroupSize, cbnDefaultHaltingWindowLength, cbnDefaultHaltingWindowEpsilon, 100);
|
||||
}
|
||||
|
||||
public static final GOParameters cbnGA(AbstractOptimizationProblem problem) {
|
||||
ClusterBasedNichingEA cbn = new ClusterBasedNichingEA();
|
||||
GeneticAlgorithm ga = new GeneticAlgorithm();
|
||||
cbn.setOptimizer(ga);
|
||||
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());
|
||||
/**
|
||||
* A standard CBNES which employs a CMA-ES, see {@link #cmaES(AbstractOptimizationProblem)}.
|
||||
*
|
||||
* @param problem
|
||||
* @return
|
||||
*/
|
||||
public static final GOParameters standardCbnCmaES(AbstractOptimizationProblem problem) {
|
||||
GOParameters cmaEsParams = cmaES(problem);
|
||||
EvolutionStrategies cmaES = (EvolutionStrategies)cmaEsParams.getOptimizer();
|
||||
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) {
|
||||
@ -1306,6 +1383,10 @@ public class OptimizerFactory {
|
||||
* @return
|
||||
*/
|
||||
public static final GOParameters cmaESIPOP(AbstractOptimizationProblem problem) {
|
||||
return createCmaEsIPop(problem, 2.);
|
||||
}
|
||||
|
||||
public static final GOParameters createCmaEsIPop(AbstractOptimizationProblem problem, double incLambdaFact) {
|
||||
EvolutionStrategies es = new EvolutionStrategyIPOP();
|
||||
|
||||
AbstractEAIndividual indyTemplate = problem.getIndividualTemplate();
|
||||
@ -1317,6 +1398,7 @@ public class OptimizerFactory {
|
||||
int lambda = (int) (4.0 + 3.0 * Math.log(dim));
|
||||
es.setGenerationStrategy((int)Math.floor(lambda/2.),lambda, false);
|
||||
es.setForceOrigPopSize(false);
|
||||
((EvolutionStrategyIPOP)es).setIncPopSizeFact(incLambdaFact);
|
||||
// Set CMA operator for mutation
|
||||
AbstractEAIndividual indy = (AbstractEAIndividual) indyTemplate;
|
||||
MutateESRankMuCMA cmaMut = new MutateESRankMuCMA();
|
||||
@ -1330,6 +1412,11 @@ public class OptimizerFactory {
|
||||
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(
|
||||
AbstractOptimizationProblem problem) {
|
||||
DifferentialEvolution de = new DifferentialEvolution();
|
||||
@ -1370,13 +1457,14 @@ public class OptimizerFactory {
|
||||
|
||||
return makeParams(ga, 100, problem, randSeed, makeDefaultTerminator());
|
||||
}
|
||||
|
||||
|
||||
public static final GOParameters standardPSO(
|
||||
AbstractOptimizationProblem problem) {
|
||||
ParticleSwarmOptimization pso = new ParticleSwarmOptimization();
|
||||
pso.setPhiValues(2.05, 2.05);
|
||||
// pso.getTopology().setSelectedTag("Grid");
|
||||
pso.setTopology(PSOTopologyEnum.grid);
|
||||
pso.setTopologyRange(1);
|
||||
return makeParams(pso, 30, problem, randSeed, makeDefaultTerminator());
|
||||
}
|
||||
|
||||
|
@ -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 postProcessOnly = false;
|
||||
private InterfaceTextListener listener = null;
|
||||
private String ident="OptimizerRunnable";
|
||||
|
||||
/**
|
||||
* Construct an OptimizerRunnable with given parameters and a StatisticsStandalone instance without restart,
|
||||
@ -87,6 +88,14 @@ public class OptimizerRunnable implements Runnable {
|
||||
doRestart = restart;
|
||||
}
|
||||
|
||||
public void setIdentifier(String id) {
|
||||
ident=id;
|
||||
}
|
||||
|
||||
public String getIdentifier() {
|
||||
return ident;
|
||||
}
|
||||
|
||||
public InterfaceGOParameters getGOParams() {
|
||||
return proc.getGOParams();
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import eva2.server.go.populations.Population;
|
||||
import eva2.tools.Pair;
|
||||
import eva2.tools.SelectedTag;
|
||||
import eva2.tools.Tag;
|
||||
|
||||
@ -131,7 +132,9 @@ public class BeanInspector {
|
||||
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.
|
||||
* 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
|
||||
* @return Description of the Return Value
|
||||
*/
|
||||
public static String toString(Object Target) {
|
||||
public static String toString(Object Target, char delim, boolean tight) {
|
||||
String ret = "";
|
||||
if (Target == null) return "null";
|
||||
// try the object itself
|
||||
@ -149,13 +152,18 @@ public class BeanInspector {
|
||||
Class<? extends Object> type = Target.getClass();
|
||||
|
||||
if (type.isArray()) { // handle the array case
|
||||
StringBuffer sbuf = new StringBuffer("[ ");
|
||||
StringBuffer sbuf = new StringBuffer("[");
|
||||
if (!tight) sbuf.append(" ");
|
||||
int len = Array.getLength(Target);
|
||||
for (int i=0; i<len; 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();
|
||||
}
|
||||
|
||||
@ -164,13 +172,15 @@ public class BeanInspector {
|
||||
}
|
||||
|
||||
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;
|
||||
for (Object o : lst) {
|
||||
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, ']');
|
||||
return sbuf.toString();
|
||||
}
|
||||
@ -192,20 +202,48 @@ public class BeanInspector {
|
||||
}
|
||||
|
||||
// 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;
|
||||
PropertyDescriptor[] Properties = null;
|
||||
// MethodDescriptor[] Methods = null;
|
||||
try {
|
||||
Info = Introspector.getBeanInfo(Target.getClass());
|
||||
Info = Introspector.getBeanInfo(target.getClass());
|
||||
Properties = Info.getPropertyDescriptors();
|
||||
Info.getMethodDescriptors();
|
||||
} catch (IntrospectionException ex) {
|
||||
System.err.println("BeanTest: Couldn't introspect");
|
||||
return ret;
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuffer sbuf = new StringBuffer(type.getName());
|
||||
sbuf.append("{");
|
||||
String[] nameArray = new String[Properties.length];
|
||||
Object[] valArray = new Object[Properties.length];
|
||||
for (int i = 0; i < Properties.length; i++) {
|
||||
if (Properties[i].isHidden() || Properties[i].isExpert()) {
|
||||
continue;
|
||||
@ -217,7 +255,7 @@ public class BeanInspector {
|
||||
Method getter = Properties[i].getReadMethod();
|
||||
Method setter = Properties[i].getWriteMethod();
|
||||
// Only display read/write properties.
|
||||
if (getter == null || setter == null) {
|
||||
if (getter == null || (setter == null && requireSetter)) {
|
||||
continue;
|
||||
}
|
||||
//System.out.println("name = "+name );
|
||||
@ -226,20 +264,16 @@ public class BeanInspector {
|
||||
//System.out.println("m_Target"+m_Target.toString());
|
||||
|
||||
try {
|
||||
Object value = getter.invoke(Target, args);
|
||||
sbuf.append(name);
|
||||
sbuf.append("=");
|
||||
sbuf.append(toString(value));
|
||||
sbuf.append("; ");
|
||||
nameArray[i]=name;
|
||||
valArray[i] = getter.invoke(target, args);
|
||||
} catch (Exception e) {
|
||||
System.err.println("BeanTest ERROR +"+ e.getMessage());
|
||||
return sbuf.toString();
|
||||
}
|
||||
}
|
||||
sbuf.append("}");
|
||||
return sbuf.toString();
|
||||
Pair<String[],Object[]> nameVals = new Pair<String[],Object[]>(nameArray, valArray);
|
||||
return nameVals;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*@param Target Description of the Parameter
|
||||
|
@ -20,6 +20,7 @@ import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
@ -31,7 +32,6 @@ import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyEditor;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.DefaultListModel;
|
||||
@ -71,15 +71,26 @@ implements PropertyEditor {
|
||||
private JButton m_DeleteBut = new JButton("Delete");
|
||||
/** Click to add the current object configuration to the array */
|
||||
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 */
|
||||
private ActionListener m_InnerActionListener =
|
||||
new ActionListener() {
|
||||
//
|
||||
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) {
|
||||
int [] selected = m_ElementList.getSelectedIndices();
|
||||
if (selected != null) {
|
||||
for (int i = 0; i < selected.length; i++) {
|
||||
for (int i = selected.length-1; i>=0; i--) {
|
||||
int current = selected[i];
|
||||
m_ListModel.removeElementAt(current);
|
||||
if (m_ListModel.size() > current) {
|
||||
@ -113,6 +124,27 @@ implements PropertyEditor {
|
||||
} catch (Exception ex) {
|
||||
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) {
|
||||
m_DeleteBut.setEnabled(true);
|
||||
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);
|
||||
m_DeleteBut.addActionListener(m_InnerActionListener);
|
||||
m_AddBut.addActionListener(m_InnerActionListener);
|
||||
m_SetAllBut.addActionListener(m_InnerActionListener);
|
||||
m_SetBut.addActionListener(m_InnerActionListener);
|
||||
m_ElementList.addListSelectionListener(m_InnerSelectionListener);
|
||||
m_AddBut.setToolTipText("Add the current item to the list");
|
||||
m_DeleteBut.setToolTipText("Delete the selected list item");
|
||||
@ -248,7 +283,7 @@ implements PropertyEditor {
|
||||
Class elementClass = arrayInstance.getClass().getComponentType();
|
||||
PropertyEditor editor = PropertyEditorProvider.findEditor(elementClass);
|
||||
if (editor instanceof EnumEditor) editor.setValue(obj);
|
||||
Component view = null;
|
||||
m_View = null;
|
||||
ListCellRenderer lcr = new DefaultListCellRenderer();
|
||||
if (editor != null) {
|
||||
if (editor instanceof GenericObjectEditor) {
|
||||
@ -256,15 +291,15 @@ implements PropertyEditor {
|
||||
((GenericObjectEditor) editor).setClassType(elementClass);
|
||||
}
|
||||
if (editor.isPaintable() && editor.supportsCustomEditor()) {
|
||||
view = new PropertyPanel(editor);
|
||||
m_View = new PropertyPanel(editor);
|
||||
lcr = new EditorListCellRenderer(editor.getClass(), elementClass);
|
||||
} else if (editor.getTags() != null) {
|
||||
view = new PropertyValueSelector(editor);
|
||||
m_View = new PropertyValueSelector(editor);
|
||||
} 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: "
|
||||
+ elementClass.getName());
|
||||
} else {
|
||||
@ -296,12 +331,18 @@ implements PropertyEditor {
|
||||
}
|
||||
}
|
||||
|
||||
setPreferredSize(new Dimension(300,300));
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new BorderLayout());
|
||||
panel.add(view, BorderLayout.CENTER);
|
||||
panel.add(m_AddBut, BorderLayout.EAST);
|
||||
add(panel, BorderLayout.NORTH);
|
||||
setPreferredSize(new Dimension(300,400));
|
||||
// JPanel panel = new JPanel();
|
||||
// panel.setLayout(new BorderLayout());
|
||||
// panel.add(view, BorderLayout.CENTER);
|
||||
// panel.add(m_AddBut, BorderLayout.EAST);
|
||||
// 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(m_DeleteBut, BorderLayout.SOUTH);
|
||||
m_ElementEditor.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
@ -454,7 +495,7 @@ implements PropertyEditor {
|
||||
editor.setValue(initial);
|
||||
PropertyDialog pd = new PropertyDialog(editor,EVAHELP.cutClassName(editor.getClass().getName())
|
||||
, 100, 100);
|
||||
pd.setSize(200,200);
|
||||
// pd.setSize(200,200);
|
||||
pd.addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
System.exit(0);
|
||||
|
@ -15,8 +15,6 @@ package eva2.gui;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
import eva2.EvAInfo;
|
||||
@ -55,7 +53,9 @@ public class PropertyDialog extends JEFrame {
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,6 +84,7 @@ public class TopoPlot extends Plot {
|
||||
double deltaY = sizeXY[1]/gridy;
|
||||
double maxDeriv=0;
|
||||
double[] pos = new double[2];
|
||||
boolean TRACEMETH=false;
|
||||
//double fitRange = java.lang.Math.abs(problem.getMinFitness()-problem.getMaxFitness() );
|
||||
double fitRange = 0, max = -Double.MAX_VALUE, min = Double.MAX_VALUE, tmp;
|
||||
for (int x=0; x<gridx; x++) {
|
||||
@ -91,12 +92,14 @@ public class TopoPlot extends Plot {
|
||||
pos[0] = border[0][0]+x*deltaX;
|
||||
pos[1] = border[1][0]+y*deltaY;
|
||||
tmp = (float)(problem.functionValue(pos));
|
||||
if (TRACEMETH) System.out.println(pos[0] + " " + pos[1] + " " + tmp);
|
||||
if (tmp < min) min = tmp;
|
||||
if (tmp > max) max = tmp;
|
||||
if (problem instanceof InterfaceFirstOrderDerivableProblem) {
|
||||
if (withGradientsIfAvailable && (problem instanceof InterfaceFirstOrderDerivableProblem)) {
|
||||
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 y
|
||||
} // for x
|
||||
fitRange = java.lang.Math.abs(max - min);
|
||||
|
@ -1,5 +1,5 @@
|
||||
package eva2.server.go.enums;
|
||||
|
||||
public enum ESMutationInitialSigma {
|
||||
halfRange, avgInitialDistance, userDefined;
|
||||
halfRange, quarterRange, avgInitialDistance, userDefined;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
||||
|
||||
protected double[] m_Fitness = new double[1];
|
||||
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_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_dataHash = (HashMap<String,Object>)(individual.m_dataHash.clone());
|
||||
m_ConstraintViolation = individual.m_ConstraintViolation;
|
||||
m_AreaConst4ParallelViolated = individual.m_AreaConst4ParallelViolated;
|
||||
// m_AreaConst4ParallelViolated = individual.m_AreaConst4ParallelViolated;
|
||||
m_Marked = individual.m_Marked;
|
||||
m_isPenalized = individual.m_isPenalized;
|
||||
individualIndex = individual.individualIndex;
|
||||
@ -181,7 +181,7 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
||||
// checking in mutation/crossover operators
|
||||
if (!this.m_MutationOperator.equals(indy.m_MutationOperator)) 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;
|
||||
} else {
|
||||
return false;
|
||||
@ -640,6 +640,28 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
||||
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.
|
||||
* Note this is dominance! If the individuals are not comparable this method will
|
||||
* return false!
|
||||
@ -647,16 +669,9 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
||||
* @return True if the own fitness dominates the other indy's
|
||||
*/
|
||||
public boolean isDominatingDebConstraints(AbstractEAIndividual indy) {
|
||||
double[] tmpFitness = indy.getFitness();
|
||||
if (this.m_AreaConst4ParallelViolated) return false;
|
||||
if (indy.m_AreaConst4ParallelViolated) return true;
|
||||
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);
|
||||
int constrViolComp = compareConstraintViolation(indy);
|
||||
if (constrViolComp==0) return isDominatingFitness(getFitness(), indy.getFitness());
|
||||
else return (constrViolComp > 0);
|
||||
// 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;
|
||||
@ -677,7 +692,8 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
||||
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
|
||||
* return false!
|
||||
*
|
||||
@ -686,19 +702,10 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
||||
*/
|
||||
public boolean isDominatingDebConstraintsEqual(AbstractEAIndividual indy) {
|
||||
// TODO: should this method really be called "..Equal"?
|
||||
if (this.m_AreaConst4ParallelViolated) return false;
|
||||
if (indy.m_AreaConst4ParallelViolated) return true;
|
||||
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;
|
||||
}
|
||||
// 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());
|
||||
int constrViolComp = compareConstraintViolation(indy);
|
||||
if (constrViolComp==0) return isDominatingFitnessNotEqual(getFitness(), indy.getFitness());
|
||||
else return (constrViolComp > 0);
|
||||
// return isDominatingFitnessNotEqual(getFitness(), indy.getFitness());
|
||||
}
|
||||
|
||||
/** 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) {
|
||||
// Note that changing this method might change the hashcode of an individual
|
||||
// which might interfere with some functionality.
|
||||
StringBuffer sb = new StringBuffer(getDefaultDataString(individual));
|
||||
|
||||
sb.append(", fitness: ");
|
||||
StringBuffer sb = new StringBuffer("Fit.: ");
|
||||
sb.append(BeanInspector.toString(individual.getFitness()));
|
||||
if (individual.isMarkedPenalized() || individual.violatesConstraint())
|
||||
sb.append(", X");
|
||||
sb.append(", ID: ");
|
||||
sb.append(individual.getIndyID());
|
||||
sb.append(", ");
|
||||
sb.append(getDefaultDataString(individual));
|
||||
|
||||
if (individual.getParentIDs()!=null) {
|
||||
sb.append(", parents: ");
|
||||
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];
|
||||
return pos;
|
||||
} // TODO check some more types here?
|
||||
EVAERROR.errorMsgOnce("Unhandled case in AbstractEAIndividual.getPosition()!");
|
||||
EVAERROR.errorMsgOnce("Unhandled case in AbstractEAIndividual.getDoublePosition()!");
|
||||
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.
|
||||
* Returns null if there is no conversion available.
|
||||
|
@ -23,31 +23,31 @@ import java.util.Comparator;
|
||||
public class AbstractEAIndividualComparator implements Comparator<Object>, Serializable {
|
||||
|
||||
// flag whether a data field should be used.
|
||||
String indyDataKey = "";
|
||||
int fitCriterion = -1;
|
||||
private String indyDataKey = "";
|
||||
private int fitCriterion = -1;
|
||||
private boolean preferFeasible = true;
|
||||
|
||||
/**
|
||||
* Comparator implementation which compares two individuals based on their fitness.
|
||||
* The default version calls isDominatingDebConstraints() of the AbstractEAIndividual
|
||||
* class and assigns -1 if first is dominant, 1 if second is dominant, 0 if the two ind.s
|
||||
* are not comparable.
|
||||
* The default version calls compares based on dominance with priority of feasibility if there are constraints.
|
||||
* It assigns -1 if first is better, 1 if second is better, 0 if the two ind.s are not comparable.
|
||||
*
|
||||
*/
|
||||
public AbstractEAIndividualComparator() {
|
||||
this("", -1);
|
||||
this("", -1, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 given key and return a double array of the same dimension. No constraints are
|
||||
* regarded for this comparison.
|
||||
* the given key and return a double array of the same dimension. Constraints are
|
||||
* also regarded by default.
|
||||
* If indyDataKey is null, the default comparison is used.
|
||||
*
|
||||
* @param 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
|
||||
*/
|
||||
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)
|
||||
* @param indyDataKey
|
||||
* @param fitnessCriterion
|
||||
* @param priorizeConstraints
|
||||
*/
|
||||
public AbstractEAIndividualComparator(String indDataKey, int fitnessCriterion) {
|
||||
indyDataKey = indDataKey;
|
||||
fitCriterion = fitnessCriterion;
|
||||
public AbstractEAIndividualComparator(String indDataKey, int fitnessCriterion, boolean preferFeasible) {
|
||||
this.indyDataKey = indDataKey;
|
||||
this.fitCriterion = fitnessCriterion;
|
||||
this.preferFeasible = preferFeasible;
|
||||
}
|
||||
|
||||
public AbstractEAIndividualComparator(AbstractEAIndividualComparator other) {
|
||||
indyDataKey = other.indyDataKey;
|
||||
fitCriterion = other.fitCriterion;
|
||||
preferFeasible = other.preferFeasible;
|
||||
}
|
||||
|
||||
|
||||
public Object clone() {
|
||||
return new AbstractEAIndividualComparator(this);
|
||||
}
|
||||
@ -92,9 +100,16 @@ public class AbstractEAIndividualComparator implements Comparator<Object>, Seria
|
||||
public int compare(Object o1, Object o2) {
|
||||
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[] 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) {
|
||||
o1domO2 = AbstractEAIndividual.isDominatingFitness(fit1, fit2);
|
||||
o2domO1 = AbstractEAIndividual.isDominatingFitness(fit2, fit1);
|
||||
@ -104,15 +119,15 @@ public class AbstractEAIndividualComparator implements Comparator<Object>, Seria
|
||||
}
|
||||
} else {
|
||||
if (fitCriterion < 0) {
|
||||
o1domO2 = ((AbstractEAIndividual) o1).isDominatingDebConstraints((AbstractEAIndividual) o2);
|
||||
o2domO1 = ((AbstractEAIndividual) o2).isDominatingDebConstraints((AbstractEAIndividual) o1);
|
||||
o1domO2 = ((AbstractEAIndividual) o1).isDominating((AbstractEAIndividual) o2);
|
||||
o2domO1 = ((AbstractEAIndividual) o2).isDominating((AbstractEAIndividual) o1);
|
||||
} else {
|
||||
if (((AbstractEAIndividual) o1).getFitness()[fitCriterion] == ((AbstractEAIndividual) o2).getFitness()[fitCriterion]) return 0;
|
||||
return (((AbstractEAIndividual) o1).getFitness()[fitCriterion] < ((AbstractEAIndividual) o2).getFitness()[fitCriterion]) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
if (o1domO2 ^ o2domO1) return (o1domO2 ? -1 : 1);
|
||||
else return 0; // these are not comparable
|
||||
if (o1domO2 ^ o2domO1) return (o1domO2 ? -1 : 1); // they are comparable
|
||||
else return 0; // they are not comparable
|
||||
}
|
||||
|
||||
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)";
|
||||
}
|
||||
|
||||
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() {
|
||||
return "A comparator class for general EA individuals. Compares individuals based on their fitness in context of minimization.";
|
||||
}
|
||||
|
@ -46,6 +46,16 @@ public class ClusteringDensityBased implements InterfaceClustering, java.io.Seri
|
||||
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) {
|
||||
if (a.m_Metric != null) this.m_Metric = (InterfaceDistanceMetric)a.m_Metric.clone();
|
||||
this.m_TestConvergingSpeciesOnBestOnly = a.m_TestConvergingSpeciesOnBestOnly;
|
||||
|
@ -11,6 +11,8 @@ import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
import eva2.server.go.individuals.AbstractEAIndividualComparator;
|
||||
import eva2.server.go.operators.distancemetric.InterfaceDistanceMetric;
|
||||
import eva2.server.go.operators.distancemetric.PhenotypeMetric;
|
||||
import eva2.server.go.operators.paramcontrol.ParamAdaption;
|
||||
import eva2.server.go.operators.paramcontrol.ParameterControlManager;
|
||||
import eva2.server.go.populations.Population;
|
||||
import eva2.tools.Pair;
|
||||
|
||||
@ -34,7 +36,8 @@ public class ClusteringNearestBetter implements InterfaceClustering, Serializabl
|
||||
private double currentMeanDistance = -1.;
|
||||
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
|
||||
|
||||
protected ParameterControlManager paramControl = new ParameterControlManager();
|
||||
|
||||
private int[] uplink;
|
||||
private double[] uplinkDist;
|
||||
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 initializedRefData = "initializedClustNearestBetterData";
|
||||
|
||||
private static boolean TRACE = true;
|
||||
private static boolean TRACE = false;
|
||||
|
||||
public ClusteringNearestBetter() {
|
||||
}
|
||||
@ -58,9 +61,35 @@ public class ClusteringNearestBetter implements InterfaceClustering, Serializabl
|
||||
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());
|
||||
}
|
||||
|
||||
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
|
||||
* the object
|
||||
@ -289,7 +318,10 @@ public class ClusteringNearestBetter implements InterfaceClustering, Serializabl
|
||||
// so add it to the cluster, mark it, and proceed recursively.
|
||||
currentClust.add(sorted.get(children[current].get(i)));
|
||||
clustered[children[current].get(i)]=true;
|
||||
if (TRACE) System.out.println("Assigned " + current);
|
||||
addChildren(children[current].get(i), clustered, sorted, currentClust);
|
||||
} else {
|
||||
if (TRACE) System.out.println("Not assigned " + current);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -7,7 +7,8 @@ import eva2.server.go.problems.InterfaceOptimizationProblem;
|
||||
import eva2.tools.math.RNG;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* Default 1-point-Crossover on InterfaceESIndividual instances.
|
||||
*
|
||||
* User: streiche
|
||||
* Date: 25.03.2003
|
||||
* Time: 11:16:39
|
||||
|
@ -1,5 +1,6 @@
|
||||
package eva2.server.go.operators.mutation;
|
||||
|
||||
import eva2.gui.BeanInspector;
|
||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
import eva2.server.go.individuals.InterfaceESIndividual;
|
||||
import eva2.server.go.populations.Population;
|
||||
@ -34,7 +35,7 @@ public class MutateESCovarianceMatrixAdaption implements InterfaceMutation, java
|
||||
protected Matrix m_C;
|
||||
protected Matrix B;
|
||||
protected boolean m_CheckConstraints = false;
|
||||
protected int m_constraint = 20;
|
||||
protected int m_constraintMaxTries = 50;
|
||||
protected int m_Counter;
|
||||
protected int m_frequency = 1;
|
||||
protected double[] m_Eigenvalues;
|
||||
@ -46,7 +47,7 @@ public class MutateESCovarianceMatrixAdaption implements InterfaceMutation, java
|
||||
this.m_Counter = mutator.m_Counter;
|
||||
this.m_frequency = mutator.m_frequency;
|
||||
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_D = mutator.m_D;
|
||||
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;
|
||||
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) {
|
||||
@ -218,8 +219,10 @@ public class MutateESCovarianceMatrixAdaption implements InterfaceMutation, java
|
||||
// }
|
||||
// }
|
||||
// for (int i = 0; i < N; i++) x[i] = tmpD[i];
|
||||
// conservation of mutaion direction:
|
||||
double[] old = (double[]) this.m_Z.clone();
|
||||
// conservation of mutation direction:
|
||||
//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);
|
||||
|
||||
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();
|
||||
|
||||
}
|
||||
boolean constraint = false;
|
||||
boolean isNewPosFeasible = false;
|
||||
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++) {
|
||||
this.Bz[i] = 0;
|
||||
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
|
||||
}
|
||||
constraint = true;
|
||||
isNewPosFeasible = true;
|
||||
if (this.m_CheckConstraints == true) {
|
||||
for (int i = 0; i < m_D; i++) {
|
||||
if (x[i] < range[i][0] || x[i] > range[i][1]) {
|
||||
// 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];
|
||||
this.m_Z[i] = RNG.gaussianDouble(1.0);
|
||||
constraint = false;
|
||||
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); // TODO is this feasible? mal mit rank-mu testen
|
||||
isNewPosFeasible = false;
|
||||
counter++;
|
||||
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);
|
||||
// System.err.println("PROJECTING BY FORCE");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ import eva2.server.go.InterfacePopulationChangedEventListener;
|
||||
import eva2.server.go.enums.ESMutationInitialSigma;
|
||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
import eva2.server.go.individuals.InterfaceDataTypeDouble;
|
||||
import eva2.server.go.operators.distancemetric.EuclideanMetric;
|
||||
import eva2.server.go.populations.Population;
|
||||
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
||||
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));
|
||||
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) {
|
||||
EVAERROR.errorMsgOnce("warning: initial sigma <= zero! Working with converged population?");
|
||||
initialSigma = 10e-10;
|
||||
@ -248,7 +252,7 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
|
||||
// instance, however this would create quite a big baustelle.
|
||||
private static transient CMAParamSet lastParams=null;
|
||||
|
||||
private ESMutationInitialSigma initializeSig = ESMutationInitialSigma.avgInitialDistance;
|
||||
private ESMutationInitialSigma initializeSig = ESMutationInitialSigma.quarterRange;
|
||||
private double userDefInitSig = 0.2;
|
||||
public static final String cmaParamsKey = "RankMuCMAParameters";
|
||||
|
||||
@ -263,6 +267,7 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
|
||||
this.c_c = mutator.c_c;
|
||||
this.expRandStepLen = mutator.expRandStepLen;
|
||||
this.initializeSig = mutator.initializeSig;
|
||||
this.userDefInitSig = mutator.userDefInitSig;
|
||||
}
|
||||
|
||||
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.
|
||||
* 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
|
||||
* @return
|
||||
*/
|
||||
@ -282,11 +288,13 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
|
||||
// scaled by average range as the measures are normed
|
||||
//return initGen.getPopulationMeasures(null)[0]*getAvgRange();
|
||||
// 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 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
|
||||
* 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)
|
||||
* params.weights[k] * (x_k[i] - params.meanX[i])
|
||||
* (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;
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -764,6 +773,7 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
|
||||
// % (the latter will decrease the overall step size) and
|
||||
// % recalculate arx accordingly. Do not change arx or arz in any
|
||||
// % other way.
|
||||
EVAERROR.errorMsgOnce("Warning, brute-forcing constraints! Too large initial sigma? (pot. multiple errors)");
|
||||
Mathematics.projectToRange(x, range);
|
||||
return x;
|
||||
}
|
||||
@ -896,4 +906,8 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali
|
||||
public void setUserDefInitSig(double userDefInitSig) {
|
||||
this.userDefInitSig = userDefInitSig;
|
||||
}
|
||||
|
||||
public String userDefInitSigTipText() {
|
||||
return "Set a manual initial sigma which should be related to the initial individual distribution.";
|
||||
}
|
||||
}
|
@ -113,7 +113,7 @@ public class MutateGIOrdinal implements InterfaceMutation, java.io.Serializable
|
||||
* @return description
|
||||
*/
|
||||
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.
|
||||
|
@ -1,11 +1,13 @@
|
||||
package eva2.server.go.operators.paramcontrol;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Vector;
|
||||
|
||||
import eva2.gui.BeanInspector;
|
||||
import eva2.server.go.populations.Population;
|
||||
import eva2.server.modules.Processor;
|
||||
import eva2.tools.Pair;
|
||||
|
||||
/**
|
||||
* The ParameterControlManager handles an array of ParamAdaption instances which dynamically adapt
|
||||
@ -144,4 +146,25 @@ public class ParameterControlManager implements InterfaceParameterControl, Seria
|
||||
public String getName() {
|
||||
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()]);
|
||||
}
|
||||
}
|
||||
|
@ -34,8 +34,11 @@ import eva2.server.go.problems.AbstractMultiModalProblemKnown;
|
||||
import eva2.server.go.problems.AbstractOptimizationProblem;
|
||||
import eva2.server.go.problems.FM0Problem;
|
||||
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.strategies.EvolutionStrategies;
|
||||
import eva2.server.go.strategies.GradientDescentAlgorithm;
|
||||
import eva2.server.go.strategies.HillClimbing;
|
||||
import eva2.server.go.strategies.NelderMeadSimplex;
|
||||
import eva2.server.modules.GOParameters;
|
||||
@ -61,6 +64,8 @@ public class PostProcess {
|
||||
private static double minMutationStepSize = 0.0000000000000001;
|
||||
// used for hill climbing post processing and only alive during that period
|
||||
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_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
|
||||
* 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
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
* @param pop
|
||||
@ -231,9 +236,9 @@ public class PostProcess {
|
||||
* @param upper
|
||||
* @return
|
||||
*/
|
||||
public static Population filterFitnessIn(Population pop, double lower, double upper) {
|
||||
Population result = filterFitness(pop, upper, true);
|
||||
return filterFitness(result, lower, false);
|
||||
public static Population filterFitnessIn(Population pop, double lower, double upper, int crit) {
|
||||
Population result = filterFitness(pop, upper, true, crit);
|
||||
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
|
||||
* @return
|
||||
*/
|
||||
public static Population filterFitness(Population pop, double fitNorm, boolean bSmallerEq) {
|
||||
public static Population filterFitnessNormed(Population pop, double fitNorm, boolean bSmallerEq) {
|
||||
AbstractEAIndividual indy;
|
||||
Population result = new Population();
|
||||
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.
|
||||
* 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.
|
||||
* Filter the individuals of a population which have a fitness below a given value.
|
||||
* If the single fitness criterion is valid (within the range of the fitness array),
|
||||
* 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 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()
|
||||
* @param pop
|
||||
* @param fitNorm
|
||||
* @param bSmaller if true, return individuals with lower or equal, else with higher fitness only
|
||||
* @param crit index of the fitness criterion or -1 to use the norm
|
||||
* @return
|
||||
*/
|
||||
public static int[] createFitNormHistogram(Population pop, double lowerBound, double upperBound, int nBins) {
|
||||
int[] res = new int[nBins];
|
||||
double lower = lowerBound;
|
||||
double step = (upperBound - lowerBound) / nBins;
|
||||
for (int i=0; i<nBins; i++) {
|
||||
// if (TRACE) System.out.println("checking between " + lower + " and " + (lower+step));
|
||||
res[i] = filterFitnessIn(pop, lower, lower+step).size();
|
||||
// if (TRACE) System.out.println("found " + res[i]);
|
||||
lower += step;
|
||||
}
|
||||
return res;
|
||||
public static Population filterFitness(Population pop, double fitThresh, boolean bSmallerEq, int crit) {
|
||||
double curFit;
|
||||
AbstractEAIndividual indy;
|
||||
Population result = new Population();
|
||||
for (int i=0; i<pop.size(); i++) {
|
||||
indy = pop.getEAIndividual(i);
|
||||
if ((crit>=0) && (crit<indy.getFitness().length)) curFit = indy.getFitness(crit);
|
||||
else curFit = PhenotypeMetric.norm(indy.getFitness());
|
||||
|
||||
if (bSmallerEq && (curFit<=fitThresh)) result.add(indy);
|
||||
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.
|
||||
// * The individuals returned are to be nearer than epsilon to a given optimum. It is not
|
||||
@ -399,6 +406,28 @@ public class PostProcess {
|
||||
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
|
||||
* (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
|
||||
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();
|
||||
|
||||
// if (problem instanceof InterfaceFirstOrderDerivableProblem) {
|
||||
// double[] x = pop.getBestEAIndividual().getDoublePosition();
|
||||
// System.out.println("grads: " + BeanInspector.toString(((InterfaceFirstOrderDerivableProblem)problem).getFirstOrderGradients(x)));
|
||||
// }
|
||||
|
||||
int funCallsDone = pop.getFunctionCalls()-baseEvals;
|
||||
pop.SetFunctionCalls(funCallsBefore);
|
||||
@ -520,25 +559,46 @@ public class PostProcess {
|
||||
* @param maxPerturbation
|
||||
* @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;
|
||||
switch (method) {
|
||||
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;
|
||||
case hillClimber:
|
||||
System.err.println("INVALID in createLSSupPopulation");
|
||||
break;
|
||||
case nelderMead:
|
||||
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);
|
||||
subPop = NelderMeadSimplex.createNMSPopulation(candidates.getEAIndividual(index), perturb, range, false);
|
||||
subPop = NelderMeadSimplex.createNMSPopulation(candidates.getEAIndividual(index), absToRelPerturb(perturb, range), range, false);
|
||||
}
|
||||
// subPop.setSameParams(candidates);
|
||||
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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* @see #findNMSPerturb(Population, int, double)
|
||||
@ -598,17 +659,17 @@ public class PostProcess {
|
||||
* @param method NM or CMA is allowed here
|
||||
* @param candidates
|
||||
* @param term
|
||||
* @param maxPerturbation perturbation for the sub population
|
||||
* @param maxRelativePerturbation perturbation for the sub population relative to problem range
|
||||
* @param prob
|
||||
* @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>();
|
||||
int stepsPerf = 0;
|
||||
Population subPop;
|
||||
|
||||
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);
|
||||
stepsPerf += subPop.size();
|
||||
@ -642,7 +703,9 @@ public class PostProcess {
|
||||
// if (subPop.getBestEAIndividual().isDominant(candidates.getEAIndividual(i))) { // TODO Multiobjective???
|
||||
if (subPop.getBestEAIndividual().getFitness(0)<candidates.getEAIndividual(i).getFitness(0)) {
|
||||
// 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());
|
||||
}
|
||||
} 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.
|
||||
*
|
||||
* @param searchBoxLen
|
||||
* @param prob
|
||||
* @param indy
|
||||
* @return
|
||||
*/
|
||||
private static Population createPopInSubRange(double searchBoxLen,
|
||||
AbstractOptimizationProblem prob,
|
||||
public static void createPopInSubRange(Population destPop, double searchBoxLen,
|
||||
int targetSize,
|
||||
AbstractEAIndividual indy) {
|
||||
if (isDoubleCompliant(indy)) {
|
||||
double[][] range = getDoubleRange(indy);
|
||||
double[] data = getDoubleData(indy);
|
||||
int lambda= (int) (4.0 + 3.0 * Math.log(range.length));
|
||||
double[][] newRange = new double[range.length][2];
|
||||
for (int dim=0; dim<range.length; dim++) {
|
||||
// create a small range array around the expected local optimum
|
||||
newRange[dim][0] = Math.max(range[dim][0], data[dim]-(searchBoxLen/2.));
|
||||
newRange[dim][1] = Math.min(range[dim][1], data[dim]+(searchBoxLen/2.));
|
||||
}
|
||||
Population pop = new Population();
|
||||
for (int i=0; i<lambda-1; i++) { // minus one because indy is added later
|
||||
// Population pop = new Population();
|
||||
destPop.clear();
|
||||
for (int i=0; i<targetSize; i++) {
|
||||
AbstractEAIndividual tmpIndy = (AbstractEAIndividual)indy.clone();
|
||||
data = getDoubleData(tmpIndy);
|
||||
ESIndividualDoubleData.defaultInit(data, newRange);
|
||||
setDoubleData(tmpIndy, data);
|
||||
pop.addIndividual(tmpIndy);
|
||||
destPop.addIndividual(tmpIndy);
|
||||
}
|
||||
pop.synchSize();
|
||||
return pop;
|
||||
destPop.synchSize();
|
||||
} else {
|
||||
System.err.println("invalid individual type!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -760,7 +820,7 @@ public class PostProcess {
|
||||
if (plot == null) {
|
||||
plot = new TopoPlot("PostProcessing: " + title, "x", "y",range[0],range[1]);
|
||||
if (prob instanceof Interface2DBorderProblem) {
|
||||
plot.setParams(60, 60);
|
||||
plot.setParams(60, 60);
|
||||
plot.setTopology((Interface2DBorderProblem)prob);
|
||||
}
|
||||
}
|
||||
@ -860,9 +920,9 @@ public class PostProcess {
|
||||
if (prob instanceof InterfaceMultimodalProblemKnown) {
|
||||
InterfaceMultimodalProblemKnown mmkProb = (InterfaceMultimodalProblemKnown)prob;
|
||||
listener.println("number of known optima is " + mmkProb.getRealOptima().size());
|
||||
listener.println("default epsilon is " + mmkProb.getEpsilon());
|
||||
listener.println("optima found with default epsilon: " + getFoundOptima(solutions, mmkProb.getRealOptima(), mmkProb.getEpsilon(), true).size());
|
||||
listener.println("max peak ratio is " + mmkProb.getMaximumPeakRatio(getFoundOptima(solutions, mmkProb.getRealOptima(), mmkProb.getEpsilon(), true)));
|
||||
listener.println("default epsilon is " + mmkProb.getDefaultAccuracy());
|
||||
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.getDefaultAccuracy(), true)));
|
||||
for (double epsilon=0.1; epsilon > 0.00000001; epsilon/=10.) {
|
||||
// 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));
|
||||
@ -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.
|
||||
* 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
|
||||
*/
|
||||
public static Population postProcess(InterfacePostProcessParams params, Population inputPop, AbstractOptimizationProblem problem, InterfaceTextListener listener) {
|
||||
if (params.isDoPostProcessing()) {
|
||||
if (params.isDoPostProcessing() && (inputPop!=null)) {
|
||||
Plot plot;
|
||||
|
||||
Population clusteredPop, outputPop, stateBeforeLS;
|
||||
@ -945,11 +1023,17 @@ public class PostProcess {
|
||||
double upBnd = PhenotypeMetric.norm(outputPop.getWorstEAIndividual().getFitness())*1.1;
|
||||
upBnd = Math.pow(10,Math.floor(Math.log10(upBnd)+1));
|
||||
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());
|
||||
if (outputPop.size()>1) {
|
||||
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
|
||||
@ -1002,7 +1086,7 @@ public class PostProcess {
|
||||
* @param maxPerturb optional upper bound of the returned perturbation
|
||||
* @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;
|
||||
AbstractEAIndividual indy = candidates.getEAIndividual(i);
|
||||
boolean found=false;
|
||||
@ -1019,13 +1103,13 @@ public class PostProcess {
|
||||
}
|
||||
if (!found) {
|
||||
// System.err.println("warning, equal candidates in PostProcess.findNMSPerturb - converged population?!");
|
||||
if (maxPerturb>0) return maxPerturb;
|
||||
if (maxAbsPerturb>0) return maxAbsPerturb;
|
||||
else {
|
||||
System.err.println("error, unable to select perturbance value in PostProcess.findNMSPerturb since all candidates are equal. Converged population?!");
|
||||
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.;
|
||||
}
|
||||
|
||||
|
166
src/eva2/server/go/operators/postprocess/SolutionHistogram.java
Normal file
166
src/eva2/server/go/operators/postprocess/SolutionHistogram.java
Normal 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);
|
||||
}
|
||||
}
|
@ -88,7 +88,8 @@ public class CombinedTerminator implements InterfaceTerminator, Serializable {
|
||||
// make sure that both terminators are triggered by every call, because some judge
|
||||
// time-dependently and store information on the population.
|
||||
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();
|
||||
} else { // OR
|
||||
// make sure that both terminators are triggered on every call, because some judge
|
||||
|
@ -91,11 +91,11 @@ Serializable {
|
||||
public boolean isTerminated(PopulationInterface Pop) {
|
||||
if (!firstTime && isStillConverged(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);
|
||||
return true;
|
||||
} else {
|
||||
// population hasnt improved much for i<max time, keep running
|
||||
// population hasnt changed much for i<max time, keep running
|
||||
return false;
|
||||
}
|
||||
} 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).
|
||||
*
|
||||
* @param curFit
|
||||
@ -160,13 +160,6 @@ Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
// public String toString() {
|
||||
// return BeanTest.toString(this);
|
||||
// }
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -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.";
|
||||
}
|
||||
|
||||
}
|
@ -8,16 +8,17 @@ import java.util.List;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
|
||||
import eva2.gui.GenericObjectEditor;
|
||||
import eva2.server.go.IndividualInterface;
|
||||
import eva2.server.go.InterfacePopulationChangedEventListener;
|
||||
import eva2.server.go.PopulationInterface;
|
||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
import eva2.server.go.individuals.AbstractEAIndividualComparator;
|
||||
import eva2.server.go.individuals.GAIndividualBinaryData;
|
||||
import eva2.server.go.individuals.InterfaceDataTypeDouble;
|
||||
import eva2.server.go.operators.distancemetric.EuclideanMetric;
|
||||
import eva2.server.go.operators.distancemetric.InterfaceDistanceMetric;
|
||||
import eva2.server.go.operators.distancemetric.PhenotypeMetric;
|
||||
import eva2.server.go.operators.postprocess.PostProcess;
|
||||
import eva2.server.go.operators.selection.probability.AbstractSelProb;
|
||||
import eva2.tools.EVAERROR;
|
||||
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 {
|
||||
|
||||
protected int m_Generation = 0;
|
||||
protected int m_FunctionCalls = 0;
|
||||
protected int m_TargetSize = 50;
|
||||
@ -62,13 +62,16 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
public static final String nextGenerationPerformed = "NextGenerationPerformed";
|
||||
|
||||
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
|
||||
private int lastQModCount = -1;
|
||||
// a sorted queue (for efficiency)
|
||||
transient private ArrayList<AbstractEAIndividual> sortedArr = null;
|
||||
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;
|
||||
|
||||
// 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) {
|
||||
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();
|
||||
@ -161,6 +168,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
this.m_TargetSize = population.m_TargetSize;
|
||||
this.useHistory = population.useHistory;
|
||||
this.notifyEvalInterval = population.notifyEvalInterval;
|
||||
this.initMethod = population.initMethod;
|
||||
if (population.seedPos!=null) this.seedPos = population.seedPos.clone();
|
||||
// this.m_Listener = population.m_Listener;
|
||||
if (population.listeners != null) this.listeners = (ArrayList<InterfacePopulationChangedEventListener>)population.listeners.clone();
|
||||
else listeners = null;
|
||||
@ -236,22 +245,53 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
case randomLatinHypercube:
|
||||
createRLHSampling(this, false);
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
// * are reset and m_Size default Individuals are created and initialized by
|
||||
// * 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_FunctionCalls = 0;
|
||||
// this.m_Archive = null;
|
||||
// this.clear();
|
||||
// for (int i = 0; i < this.m_TargetSize; i++) {
|
||||
// AbstractEAIndividual tmpIndy = (AbstractEAIndividual)template.clone();
|
||||
// tmpIndy.defaultInit(null);
|
||||
// tmpIndy.defaultInit();
|
||||
// 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
|
||||
* generation in the incrGeneration() method.
|
||||
* generation in the incrGeneration() method. This uses a default individual comparator
|
||||
* which is based on fitness.
|
||||
*
|
||||
* @param 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;
|
||||
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.
|
||||
@ -396,7 +462,9 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
* Stagnation measured etc. pp.
|
||||
*/
|
||||
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();
|
||||
this.m_Generation++;
|
||||
firePropertyChangedEvent(nextGenerationPerformed);
|
||||
@ -591,9 +659,9 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
* @see getIndexOfBestOrWorstIndividual()
|
||||
* @return The index of the best individual.
|
||||
*/
|
||||
public int getIndexOfBestIndividual() {
|
||||
public int getIndexOfBestIndividualPrefFeasible() {
|
||||
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()
|
||||
* @return The index of the best individual.
|
||||
*/
|
||||
public int getIndexOfWorstIndividual() {
|
||||
return getIndexOfBestOrWorstIndividual(false, false, -1);
|
||||
public int getIndexOfWorstIndividualNoConstr() {
|
||||
return getIndexOfBestOrWorstIndy(false, false, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -615,9 +683,9 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
* @see getIndexOfBestOrWorstIndividual()
|
||||
* @return The index of the best individual.
|
||||
*/
|
||||
public int getIndexOfBestIndividual(int fitIndex) {
|
||||
public int getIndexOfBestIndividualPrefFeasible(int fitIndex) {
|
||||
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()
|
||||
* @return The index of the best individual.
|
||||
*/
|
||||
public int getIndexOfWorstIndividual(int fitIndex) {
|
||||
return getIndexOfBestOrWorstIndividual(false, false, fitIndex);
|
||||
public int getIndexOfWorstIndividualNoConstr(int 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
|
||||
* @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());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
public int getIndexOfBestOrWorstIndividual(boolean bBest, AbstractEAIndividualComparator comparator) {
|
||||
ArrayList<AbstractEAIndividual> sorted = getSorted(comparator);
|
||||
if (bBest) return indexOf(sorted.get(0));
|
||||
else return indexOfInstance(sorted.get(sorted.size()-1));
|
||||
}
|
||||
|
||||
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
|
||||
* 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.
|
||||
@ -764,8 +887,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the current best individual from the population
|
||||
* by a given fitness component.
|
||||
* This method returns the currently best individual from the population
|
||||
* by a given fitness component while prioritizing feasible ones.
|
||||
* If the population is empty, null is returned.
|
||||
*
|
||||
* @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) {
|
||||
if (size()<1) return null;
|
||||
int best = this.getIndexOfBestIndividual(fitIndex);
|
||||
int best = this.getIndexOfBestIndividualPrefFeasible(fitIndex);
|
||||
if (best == -1) {
|
||||
System.err.println("This shouldnt happen!");
|
||||
return null;
|
||||
@ -1041,7 +1164,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
}
|
||||
|
||||
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 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
|
||||
*/
|
||||
public String getStringRepresentation() {
|
||||
StringBuilder strB = new StringBuilder(200);
|
||||
strB.append("Population:\nPopulation size: ");
|
||||
strB.append("Population size: ");
|
||||
strB.append(this.size());
|
||||
strB.append("\nFunction calls : ");
|
||||
strB.append(this.m_FunctionCalls);
|
||||
@ -1268,7 +1391,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
modCount++;
|
||||
if (lastFitCrit==fitIndex && (lastQModCount==(modCount-1))) {
|
||||
// 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;
|
||||
AbstractEAIndividualComparator comp = new AbstractEAIndividualComparator(fitIndex);
|
||||
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);
|
||||
}
|
||||
|
||||
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++) {
|
||||
if (ind.equals(this.get(i))) {
|
||||
this.remove(i);
|
||||
return;
|
||||
if (getEAIndividual(i).getIndyID()==id) {
|
||||
removeIndexSwitched(i);
|
||||
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() {
|
||||
return (IndividualInterface)this.getBestEAIndividual();
|
||||
}
|
||||
@ -1382,7 +1520,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
// }
|
||||
// return measures;
|
||||
// }
|
||||
double[] res = calcPopulationMeasures(metric);
|
||||
double[] res = getPopulationMeasures(this, metric);
|
||||
// putData(lastPopMeasuresFlagKey, new Integer(modCount));
|
||||
// putData(lastPopMeasuresDatKey, res);
|
||||
// System.out.println(getStringRepresentation());
|
||||
@ -1390,34 +1528,34 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
return res;
|
||||
}
|
||||
|
||||
private double[] calcPopulationMeasures(InterfaceDistanceMetric metric) {
|
||||
public static double[] getPopulationMeasures(List<AbstractEAIndividual> pop, InterfaceDistanceMetric metric) {
|
||||
double d;
|
||||
double[] res = new double[3];
|
||||
|
||||
double meanDist = 0.;
|
||||
double distSum = 0.;
|
||||
double maxDist = Double.MIN_VALUE;
|
||||
double minDist = Double.MAX_VALUE;
|
||||
|
||||
for (int i = 0; i < this.size(); i++) {
|
||||
for (int j = i+1; j < this.size(); j++) {
|
||||
if (metric == null) d = EuclideanMetric.euclideanDistance(AbstractEAIndividual.getDoublePositionShallow(getEAIndividual(i)),
|
||||
AbstractEAIndividual.getDoublePositionShallow(getEAIndividual(j)));
|
||||
else d = metric.distance((AbstractEAIndividual)this.get(i), (AbstractEAIndividual)this.get(j));
|
||||
meanDist += d;
|
||||
for (int i = 0; i < pop.size(); i++) {
|
||||
for (int j = i+1; j < pop.size(); j++) {
|
||||
if (metric == null) d = EuclideanMetric.euclideanDistance(AbstractEAIndividual.getDoublePositionShallow(pop.get(i)),
|
||||
AbstractEAIndividual.getDoublePositionShallow(pop.get(j)));
|
||||
else d = metric.distance((AbstractEAIndividual)pop.get(i), (AbstractEAIndividual)pop.get(j));
|
||||
distSum += d;
|
||||
if (d < minDist) minDist = d;
|
||||
if (d > maxDist) maxDist = d;
|
||||
}
|
||||
}
|
||||
res[1] = minDist;
|
||||
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?
|
||||
res[1]=0;
|
||||
res[2]=0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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[] res = new double[4];
|
||||
|
||||
@ -1433,23 +1581,23 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
res[2] = Double.MIN_VALUE;
|
||||
res[3] = 0;
|
||||
|
||||
for (int i = 0; i < this.size(); i++) {
|
||||
d = this.getEAIndividual(i).getFitness(fitCrit);
|
||||
for (int i = 0; i < pop.size(); i++) {
|
||||
d = pop.get(i).getFitness(fitCrit);
|
||||
res[0] += d;
|
||||
if (d < res[1]) res[1] = 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;
|
||||
} else {
|
||||
// calc standard deviation
|
||||
res[0] = res[0] / this.size();
|
||||
for (int i=0; i< this.size(); i++) {
|
||||
d = res[0]-this.getEAIndividual(i).getFitness(fitCrit);
|
||||
res[0] = res[0] / pop.size();
|
||||
for (int i=0; i< pop.size(); i++) {
|
||||
d = res[0]-pop.get(i).getFitness(fitCrit);
|
||||
res[3]+=d*d;
|
||||
}
|
||||
res[3] /= this.size();
|
||||
res[3] /= pop.size();
|
||||
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.
|
||||
*
|
||||
* @param indy
|
||||
* @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...
|
||||
int index = -1;
|
||||
int foundIndex = -1;
|
||||
double mindist = Double.POSITIVE_INFINITY;
|
||||
|
||||
for (int i = 0; i < size(); ++i){
|
||||
AbstractEAIndividual currentindy = getEAIndividual(i);
|
||||
if (!indy.equals(currentindy)){ // dont compare particle to itself or a copy of itself
|
||||
double dist = EuclideanMetric.euclideanDistance(AbstractEAIndividual.getDoublePositionShallow(indy),
|
||||
if (i!=neighborIndex){ // dont compare particle to itself or a copy of itself
|
||||
double dist = EuclideanMetric.euclideanDistance(AbstractEAIndividual.getDoublePositionShallow(getEAIndividual(neighborIndex)),
|
||||
AbstractEAIndividual.getDoublePositionShallow(currentindy));
|
||||
if (dist < mindist){
|
||||
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 !?");
|
||||
return -1;
|
||||
}
|
||||
return index;
|
||||
return foundIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1609,7 +1757,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
double d=0;
|
||||
for (int i = 0; i < size(); ++i){
|
||||
AbstractEAIndividual neighbor, indy = getEAIndividual(i);
|
||||
int neighborIndex = getNeighborIndex(indy);
|
||||
int neighborIndex = getNeighborIndex(i);
|
||||
if (neighborIndex >= 0) neighbor = getEAIndividual(neighborIndex);
|
||||
else return null;
|
||||
if (normalizedPhenoMetric){
|
||||
@ -1719,6 +1867,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
|
||||
public void setInitMethod(PopulationInitMethod initMethod) {
|
||||
this.initMethod = initMethod;
|
||||
GenericObjectEditor.setShowProperty(this.getClass(), "initAround", initMethod==PopulationInitMethod.aroundSeed);
|
||||
GenericObjectEditor.setShowProperty(this.getClass(), "initPos", initMethod==PopulationInitMethod.aroundSeed);
|
||||
}
|
||||
|
||||
public String initMethodTipText() {
|
||||
@ -1792,6 +1942,16 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
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
|
||||
// * will invalidate the mark.
|
||||
|
@ -1,5 +1,5 @@
|
||||
package eva2.server.go.populations;
|
||||
|
||||
public enum PopulationInitMethod {
|
||||
individualDefault, randomLatinHypercube;
|
||||
individualDefault, randomLatinHypercube, aroundSeed;
|
||||
}
|
||||
|
@ -99,6 +99,7 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
|
||||
this.m_GlobalOpt = Double.NEGATIVE_INFINITY;
|
||||
m_ListOfOptima = new Population();
|
||||
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
|
||||
@ -106,6 +107,7 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
|
||||
* @return The m-dimensional output vector.
|
||||
*/
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] result = new double[1];
|
||||
result[0] = this.m_GlobalOpt - evalUnnormalized(x)[0];
|
||||
return result;
|
||||
@ -124,7 +126,7 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
|
||||
* @return String
|
||||
*/
|
||||
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 += this.getNumberOfFoundOptima((Population)pop)+"\t";
|
||||
result += this.getMaximumPeakRatio((Population)pop);
|
||||
return result;
|
||||
return result +"\t"+ super.getAdditionalFileStringValue(pop);
|
||||
}
|
||||
//
|
||||
// /** This method returns a string describing the optimization problem.
|
||||
@ -212,6 +214,14 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
|
||||
public Population getRealOptima() {
|
||||
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
|
||||
* @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) {
|
||||
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();
|
||||
}
|
||||
|
||||
@ -241,9 +251,19 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
|
||||
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) {
|
||||
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);
|
||||
sumRealMaxima = maxOpt;
|
||||
for (int i=1; i<realOpts.size(); i++) {
|
||||
@ -306,23 +326,23 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
|
||||
// return range;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @return the m_Epsilon
|
||||
*/
|
||||
public double getEpsilon() {
|
||||
return m_Epsilon;
|
||||
}
|
||||
// /**
|
||||
// * @return the m_Epsilon
|
||||
// */
|
||||
// public double getEpsilon() {
|
||||
// return m_Epsilon;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @param epsilon the m_Epsilon to set
|
||||
*/
|
||||
public void setEpsilon(double epsilon) {
|
||||
m_Epsilon = epsilon;
|
||||
}
|
||||
|
||||
public String epsilonTipText() {
|
||||
return "Epsilon criterion indicating whether an optimum was found";
|
||||
public void setDefaultAccuracy(double epsilon) {
|
||||
super.SetDefaultAccuracy(epsilon);
|
||||
}
|
||||
//
|
||||
// public String epsilonTipText() {
|
||||
// return "Epsilon criterion indicating whether an optimum was found";
|
||||
// }
|
||||
|
||||
@Override
|
||||
public int getProblemDimension() {
|
||||
|
@ -1,11 +1,11 @@
|
||||
package eva2.server.go.problems;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.io.Serializable;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.io.Serializable;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
@ -17,12 +17,16 @@ import eva2.server.go.PopulationInterface;
|
||||
import eva2.server.go.enums.PostProcessMethod;
|
||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
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.PhenotypeMetric;
|
||||
import eva2.server.go.operators.moso.MOSONoConvert;
|
||||
import eva2.server.go.operators.mutation.InterfaceMutation;
|
||||
import eva2.server.go.operators.mutation.MutateESFixedStepSize;
|
||||
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.EvaluationTerminator;
|
||||
import eva2.server.go.operators.terminators.PhenotypeConvergenceTerminator;
|
||||
@ -37,7 +41,8 @@ import eva2.tools.math.Mathematics;
|
||||
* Time: 13:40:12
|
||||
* 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 {
|
||||
AbstractOptimizationProblem prob;
|
||||
AbstractEAIndividual ind;
|
||||
@ -71,6 +76,8 @@ public abstract class AbstractOptimizationProblem implements InterfaceOptimizati
|
||||
protected AbstractEAIndividual m_Template;
|
||||
// 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.
|
||||
* @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.";
|
||||
}
|
||||
|
||||
/** 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();
|
||||
|
||||
@ -231,8 +240,8 @@ public abstract class AbstractOptimizationProblem implements InterfaceOptimizati
|
||||
* @return String
|
||||
*/
|
||||
public String getAdditionalFileStringHeader(PopulationInterface pop) {
|
||||
return "Solution";
|
||||
// return "";
|
||||
if (this instanceof InterfaceInterestingHistogram) return "Solution \t Histogram(c0) \t Score";
|
||||
else return "Solution";
|
||||
}
|
||||
|
||||
/** 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
|
||||
*/
|
||||
public String getAdditionalFileStringValue(PopulationInterface pop) {
|
||||
// return "";
|
||||
return AbstractEAIndividual.getDefaultDataString(pop.getBestIndividual());
|
||||
String solStr = 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 epsilonFitConv if positive: additional absolute convergence criterion (fitness space) as termination criterion of the local search
|
||||
* @param clusterSigma minimum cluster distance
|
||||
* @param numOfFailures
|
||||
* @param maxEvalsPerIndy
|
||||
* @see #isPotentialOptimumNMS(AbstractEAIndividual, double, double, int)
|
||||
* @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();
|
||||
for (int i = 0; i < pop.size(); ++i){
|
||||
AbstractEAIndividual indy = pop.getEAIndividual(i);
|
||||
// System.out.println("bef: " + indy.toString());
|
||||
if (isPotentialOptimumNMS(indy, epsilonPhenoSpace, epsilonFitConv, numOfFailures)){
|
||||
// if (isPotentialOptimum(indy, epsilon,-1,-1)){
|
||||
boolean isConverged = AbstractOptimizationProblem.isPotentialOptimumNMS(prob, indy, epsilonPhenoSpace, epsilonFitConv, maxEvalsPerIndy);
|
||||
if (isConverged) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
* distance from the original individual in phenotype space. The numOfFailures parameter gives the maximum evaluations
|
||||
* for the local search Using the epsilonFitConv parameter may define a convergence criterion as PhenotypeConvergenceTerminator
|
||||
* distance from the original individual in phenotype space. The maxEvaluations parameter gives the maximum evaluations
|
||||
* for the local search. Using the epsilonFitConv parameter one may define a convergence criterion as PhenotypeConvergenceTerminator
|
||||
* which is combined (using OR) with the evaluation counter.
|
||||
* If 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.
|
||||
* A double value for the distance by which it was moved is added to the individual using the key PostProcess.movedDistanceKey.
|
||||
*
|
||||
* @param orig
|
||||
* @param epsilonPhenoSpace
|
||||
* @param epsilonFitConv
|
||||
* @param numOfFailures
|
||||
* @param epsilonPhenoSpace allowed distance for a solution moved by local search
|
||||
* @param epsilonFitConv if the fitness changes below the threshold, the search is stopped earlier. Set to -1 to deactivate.
|
||||
* @param maxEvaluations maximal number of evaluations or -1
|
||||
* @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();
|
||||
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();
|
||||
double overallDist = 0;
|
||||
double initPerturb = -1;
|
||||
double initRelPerturb = -1;
|
||||
int dim = -1;
|
||||
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;
|
||||
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 {
|
||||
System.err.println("Cannot initialize NMS on non-double valued individuals!");
|
||||
return false;
|
||||
@ -439,14 +460,31 @@ public abstract class AbstractOptimizationProblem implements InterfaceOptimizati
|
||||
|
||||
Population pop = new Population(1);
|
||||
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);
|
||||
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());
|
||||
// System.out.println("aft: " + pop.getBestEAIndividual().toString() + ", evals performed: " + evalsPerf + ", opt moved by " + overallDist);
|
||||
// System.out.println("terminated because: " + term.lastTerminationMessage());
|
||||
if (overallDist < epsilonPhenoSpace) return true;
|
||||
else return false;
|
||||
orig.putData(PostProcess.movedDistanceKey, overallDist);
|
||||
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.";
|
||||
}
|
||||
|
||||
// /**********************************************************************************************************************
|
||||
|
@ -2,6 +2,7 @@ package eva2.server.go.problems;
|
||||
|
||||
import eva2.gui.BeanInspector;
|
||||
import eva2.gui.GenericObjectEditor;
|
||||
import eva2.gui.TopoPlot;
|
||||
import eva2.server.go.PopulationInterface;
|
||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
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.strategies.InterfaceOptimizer;
|
||||
import eva2.tools.Pair;
|
||||
import eva2.tools.diagram.ColorBarCalculator;
|
||||
import eva2.tools.math.Mathematics;
|
||||
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()}
|
||||
@ -37,10 +41,14 @@ import eva2.tools.math.RNG;
|
||||
public abstract class AbstractProblemDouble extends AbstractOptimizationProblem implements InterfaceProblemDouble, Interface2DBorderProblem/*, InterfaceParamControllable */{
|
||||
private double m_DefaultRange = 10;
|
||||
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()});
|
||||
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 AbstractProblemDouble() {
|
||||
@ -66,12 +74,16 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
|
||||
protected void cloneObjects(AbstractProblemDouble o) {
|
||||
this.m_DefaultRange = o.m_DefaultRange;
|
||||
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.constraintArray!=null) {
|
||||
this.constraintArray=o.constraintArray.clone();
|
||||
for (int i=0; i<constraintArray.length; i++) constraintArray[i]=(AbstractConstraint)o.constraintArray[i].clone();
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
@ -140,6 +160,8 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return the target function value
|
||||
@ -202,6 +224,28 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
|
||||
@Override
|
||||
public void initProblem() {
|
||||
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";
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
@ -388,4 +443,19 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
|
||||
}
|
||||
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).";
|
||||
}
|
||||
}
|
||||
|
@ -39,13 +39,6 @@ public abstract class AbstractProblemDoubleOffset extends AbstractProblemDouble
|
||||
setDefaultRange(defRange);
|
||||
}
|
||||
|
||||
/** This method inits the Problem to log multiruns
|
||||
*/
|
||||
public void initProblem() {
|
||||
// this.m_OverallBest = null;
|
||||
initTemplate();
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************
|
||||
* These are for GUI
|
||||
*/
|
||||
|
@ -51,6 +51,7 @@ public class ConstrHimmelblauProblem extends AbstractProblemDouble implements Se
|
||||
|
||||
@Override
|
||||
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;
|
||||
if (useYOffset) v+=yOffset;
|
||||
return new double[]{v};
|
||||
|
@ -37,6 +37,7 @@ public class F10Problem extends AbstractProblemDoubleOffset implements Interface
|
||||
* @return The m-dimensional output vector.
|
||||
*/
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] result = new double[1];
|
||||
double c1 = this.calculateC(1);
|
||||
result[0] = m_YOffSet;
|
||||
|
@ -39,6 +39,7 @@ public class F11Problem extends AbstractProblemDoubleOffset implements Interface
|
||||
* @return The m-dimensional output vector.
|
||||
*/
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] result = new double[1];
|
||||
double tmpProd = 1;
|
||||
for (int i = 0; i < x.length; i++) {
|
||||
|
@ -34,13 +34,14 @@ public class F12Problem extends AbstractProblemDoubleOffset implements java.io.S
|
||||
* @return The m-dimensional output vector.
|
||||
*/
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] result = new double[1];
|
||||
double tmp = -5;
|
||||
double tmp = 0;//-5;
|
||||
for (int i = 1; i < x.length-1; i++) {
|
||||
tmp += Math.pow(x[i]-m_XOffSet, 2);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,14 @@
|
||||
package eva2.server.go.problems;
|
||||
|
||||
import eva2.gui.GenericObjectEditor;
|
||||
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.
|
||||
* 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() {
|
||||
this.m_Template = new ESIndividualDoubleData();
|
||||
@ -27,28 +29,37 @@ public class F13Problem extends AbstractProblemDoubleOffset implements Interface
|
||||
return (Object) new F13Problem(this);
|
||||
}
|
||||
|
||||
// public double[][] makeRange() {
|
||||
// double[][] range = new double[this.m_ProblemDimension][2];
|
||||
// for (int i = 0; i < range.length; i++) {
|
||||
// range[i][0] = -512.03;
|
||||
// range[i][1] = 511.97;
|
||||
// }
|
||||
// return range;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public double getRangeLowerBound(int dim) {
|
||||
return -512.03;
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
* @param x The n-dimensional input vector
|
||||
* @return The m-dimensional output vector.
|
||||
*/
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] result = new double[1];
|
||||
result[0] = m_YOffSet;
|
||||
|
||||
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] += (418.9829 * m_ProblemDimension);
|
||||
// res = cn-sum_i(xi*sin(sqrt(abs(xi))))
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -67,6 +78,11 @@ public class F13Problem extends AbstractProblemDoubleOffset implements Interface
|
||||
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
|
||||
*/
|
||||
@ -85,4 +101,7 @@ public class F13Problem extends AbstractProblemDoubleOffset implements Interface
|
||||
return "Schwefels sine-root Function (multimodal, 1981). Remember to use range check!";
|
||||
}
|
||||
|
||||
public void setDefaultAccuracy(double v) {
|
||||
super.SetDefaultAccuracy(v);
|
||||
}
|
||||
}
|
102
src/eva2/server/go/problems/F15Problem.java
Normal file
102
src/eva2/server/go/problems/F15Problem.java
Normal 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;
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ public class F16Problem extends AbstractProblemDouble implements InterfaceMultim
|
||||
|
||||
@Override
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] res = new double[1];
|
||||
double sum = 0;
|
||||
|
||||
@ -50,6 +51,6 @@ public class F16Problem extends AbstractProblemDouble implements InterfaceMultim
|
||||
}
|
||||
|
||||
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.";
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,33 @@
|
||||
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
|
||||
InterfaceMultimodalProblem {
|
||||
InterfaceMultimodalProblem, InterfaceInterestingHistogram{
|
||||
int dim = 10;
|
||||
|
||||
public F17Problem() {
|
||||
setDefaultRange(10.);
|
||||
dim=10;
|
||||
}
|
||||
|
||||
public F17Problem(int dimension) {
|
||||
this();
|
||||
setProblemDimension(dimension);
|
||||
}
|
||||
|
||||
public F17Problem(F17Problem other) {
|
||||
super(other);
|
||||
dim=other.dim;
|
||||
}
|
||||
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] res = new double[1];
|
||||
double sum = 0;
|
||||
for (int i=0; i<getProblemDimension()-1; i++) {
|
||||
@ -30,7 +45,7 @@ public class F17Problem extends AbstractProblemDouble implements
|
||||
public void setProblemDimension(int newDim) {
|
||||
dim = newDim;
|
||||
}
|
||||
|
||||
|
||||
public Object clone() {
|
||||
return new F17Problem(this);
|
||||
}
|
||||
@ -42,4 +57,9 @@ public class F17Problem extends AbstractProblemDouble implements
|
||||
public String globalInfo() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ InterfaceMultimodalProblem {
|
||||
}
|
||||
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] res = new double[1];
|
||||
double sum = 0;
|
||||
for (int i=0; i<getProblemDimension(); i++) {
|
||||
|
@ -1,14 +1,23 @@
|
||||
package eva2.server.go.problems;
|
||||
|
||||
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
|
||||
InterfaceMultimodalProblem {
|
||||
InterfaceMultimodalProblem, InterfaceInterestingHistogram {
|
||||
int dim = 10;
|
||||
transient private double[] alphas, As;
|
||||
transient private int[] A,B;
|
||||
private long randSeed = 23;
|
||||
|
||||
public F19Problem() {
|
||||
alphas=null;
|
||||
@ -21,15 +30,21 @@ InterfaceMultimodalProblem {
|
||||
alphas=null;
|
||||
}
|
||||
|
||||
public F19Problem(int d) {
|
||||
this();
|
||||
setProblemDimension(d);
|
||||
}
|
||||
|
||||
public void initProblem() {
|
||||
super.initProblem();
|
||||
if (alphas==null) {
|
||||
// if (alphas==null) {
|
||||
// create static random data
|
||||
alphas = RNG.randomVector(dim, -Math.PI, Math.PI);
|
||||
A = RNG.randomVector(dim*dim, -100, 100);
|
||||
B = RNG.randomVector(dim*dim, -100, 100);
|
||||
Random rand = new Random(randSeed);
|
||||
alphas = RNG.randomDoubleArray(rand, -Math.PI, Math.PI, dim);
|
||||
A = RNG.randomIntArray(rand, -100, 100, dim*dim);
|
||||
B = RNG.randomIntArray(rand, -100, 100, dim*dim);
|
||||
As = transform(alphas);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
private double[] transform(double[] x) {
|
||||
@ -55,6 +70,7 @@ InterfaceMultimodalProblem {
|
||||
}
|
||||
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] res = new double[1];
|
||||
double[] Bs = transform(x);
|
||||
|
||||
@ -88,7 +104,12 @@ InterfaceMultimodalProblem {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ public class F1Problem extends AbstractProblemDoubleOffset implements Interface2
|
||||
* @return The m-dimensional output vector.
|
||||
*/
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] result = new double[1];
|
||||
result[0] = m_YOffSet;
|
||||
// add an offset in solution space
|
||||
@ -89,6 +90,7 @@ public class F1Problem extends AbstractProblemDoubleOffset implements Interface2
|
||||
}
|
||||
|
||||
public double[] getFirstOrderGradients(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
// first order partial derivation in direction x_i is 2*x_i
|
||||
double[] grads=new double[x.length];
|
||||
for (int i=0; i<x.length; i++) {
|
||||
|
117
src/eva2/server/go/problems/F20Problem.java
Normal file
117
src/eva2/server/go/problems/F20Problem.java
Normal 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);
|
||||
}
|
||||
}
|
77
src/eva2/server/go/problems/F21Problem.java
Normal file
77
src/eva2/server/go/problems/F21Problem.java
Normal 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)";
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
package eva2.server.go.problems;
|
||||
|
||||
import eva2.server.go.individuals.ESIndividualDoubleData;
|
||||
import eva2.server.go.populations.Population;
|
||||
import eva2.server.go.strategies.GradientDescentAlgorithm;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
@ -9,9 +11,12 @@ import eva2.server.go.individuals.ESIndividualDoubleData;
|
||||
* Time: 19:03:09
|
||||
* 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();
|
||||
}
|
||||
public F2Problem(F2Problem b) {
|
||||
@ -33,6 +38,7 @@ public class F2Problem extends AbstractProblemDoubleOffset implements InterfaceM
|
||||
* @return The m-dimensional output vector.
|
||||
*/
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] result = new double[1];
|
||||
result[0] = m_YOffSet;
|
||||
double xi, xii;
|
||||
@ -46,6 +52,7 @@ public class F2Problem extends AbstractProblemDoubleOffset implements InterfaceM
|
||||
}
|
||||
|
||||
public double[] getFirstOrderGradients(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
int dim = x.length;
|
||||
double[] result = new double[dim];
|
||||
double xi, xii;
|
||||
@ -93,4 +100,26 @@ public class F2Problem extends AbstractProblemDoubleOffset implements InterfaceM
|
||||
public String globalInfo() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ public class F3Problem extends AbstractProblemDoubleOffset implements java.io.Se
|
||||
* @return The m-dimensional output vector.
|
||||
*/
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] result = new double[1];
|
||||
result[0] = m_YOffSet+6*x.length;
|
||||
for (int i = 0; i < x.length-1; i++) {
|
||||
|
@ -35,6 +35,7 @@ public class F4Problem extends AbstractProblemDoubleOffset implements java.io.Se
|
||||
* @return The m-dimensional output vector.
|
||||
*/
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] result = new double[1];
|
||||
result[0] = m_YOffSet;
|
||||
for (int i = 0; i < x.length-1; i++) {
|
||||
|
@ -35,6 +35,7 @@ public class F5Problem extends AbstractProblemDoubleOffset implements java.io.Se
|
||||
* @return The m-dimensional output vector.
|
||||
*/
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] result = new double[1];
|
||||
double tmp;
|
||||
result[0] = m_YOffSet;
|
||||
|
@ -2,28 +2,26 @@ package eva2.server.go.problems;
|
||||
|
||||
import eva2.server.go.individuals.ESIndividualDoubleData;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: streiche
|
||||
* Date: 30.06.2005
|
||||
* Time: 13:09:36
|
||||
* To change this template use File | Settings | File Templates.
|
||||
* Generalized Rastrigin's function.
|
||||
*
|
||||
*/
|
||||
public class F6Problem extends AbstractProblemDoubleOffset implements InterfaceMultimodalProblem, InterfaceFirstOrderDerivableProblem, java.io.Serializable {
|
||||
|
||||
private boolean doRotation = false;
|
||||
public class F6Problem extends AbstractProblemDoubleOffset
|
||||
implements InterfaceMultimodalProblem, InterfaceFirstOrderDerivableProblem, InterfaceLocalSearchable, java.io.Serializable, InterfaceInterestingHistogram {
|
||||
private double m_A = 10;
|
||||
private double m_Omega = 2*Math.PI;
|
||||
private Matrix rotation;
|
||||
private transient GradientDescentAlgorithm localSearchOptimizer=null;
|
||||
|
||||
public F6Problem() {
|
||||
this.m_Template = new ESIndividualDoubleData();
|
||||
}
|
||||
public F6Problem(F6Problem b) {
|
||||
super(b);
|
||||
doRotation = b.doRotation;
|
||||
super(b);
|
||||
this.m_A = b.m_A;
|
||||
this.m_Omega = b.m_Omega;
|
||||
}
|
||||
@ -31,17 +29,6 @@ public class F6Problem extends AbstractProblemDoubleOffset implements InterfaceM
|
||||
public F6Problem(int 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.
|
||||
* @return the clone
|
||||
@ -55,10 +42,7 @@ public class F6Problem extends AbstractProblemDoubleOffset implements InterfaceM
|
||||
* @return The m-dimensional output vector.
|
||||
*/
|
||||
public double[] eval(double[] x) {
|
||||
if (doRotation) {
|
||||
Matrix resVec = rotation.times(new Matrix(x, x.length));
|
||||
x = resVec.getColumnPackedCopy();
|
||||
}
|
||||
x = rotateMaybe(x);
|
||||
double[] result = new double[1];
|
||||
result[0] = x.length * this.m_A + m_YOffSet;
|
||||
for (int i = 0; i < x.length; i++) {
|
||||
@ -69,10 +53,7 @@ public class F6Problem extends AbstractProblemDoubleOffset implements InterfaceM
|
||||
}
|
||||
|
||||
public double[] getFirstOrderGradients(double[] x) {
|
||||
if (doRotation) {
|
||||
Matrix resVec = rotation.times(new Matrix(x, x.length));
|
||||
x = resVec.getColumnPackedCopy();
|
||||
}
|
||||
x = rotateMaybe(x);
|
||||
double[] result = new double[x.length];
|
||||
for (int j=0; j<x.length; j++) {
|
||||
result[j]=0;
|
||||
@ -141,10 +122,36 @@ public class F6Problem extends AbstractProblemDoubleOffset implements InterfaceM
|
||||
public String omegaTipText() {
|
||||
return "Choose Omega.";
|
||||
}
|
||||
public boolean isDoRotation() {
|
||||
return doRotation;
|
||||
}
|
||||
public void setDoRotation(boolean doRotation) {
|
||||
this.doRotation = doRotation;
|
||||
|
||||
public void setDefaultAccuracy(double acc) {
|
||||
super.SetDefaultAccuracy(acc);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -70,6 +70,7 @@ public class F7Problem extends AbstractProblemDoubleOffset implements java.io.Se
|
||||
* @return The m-dimensional output vector.
|
||||
*/
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] result = new double[1];
|
||||
result[0] = m_YOffSet;
|
||||
if ((Math.floor(this.m_CurrentTimeStamp / this.m_t)%2) == 0) {
|
||||
|
@ -41,6 +41,7 @@ public class F8Problem extends AbstractProblemDoubleOffset implements InterfaceM
|
||||
* @return The m-dimensional output vector.
|
||||
*/
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] result = new double[1];
|
||||
double sum1 = 0, sum2 = 0, exp1, exp2;
|
||||
|
||||
|
@ -24,6 +24,7 @@ public class F9Problem extends AbstractProblemDoubleOffset implements java.io.Se
|
||||
* @return The m-dimensional output vector.
|
||||
*/
|
||||
public double[] eval(double[] x) {
|
||||
x = rotateMaybe(x);
|
||||
double[] result = new double[1];
|
||||
result[0] = m_YOffSet;
|
||||
for (int i = 0; i < x.length; i++) {
|
||||
|
@ -87,6 +87,7 @@ public class GPFunctionProblem extends AbstractProblemDouble implements Interfac
|
||||
EVAERROR.errorMsgOnce("mismatching dimension of GPFunctionProblem! Setting to " + x.length);
|
||||
setProblemDimension(x.length);
|
||||
}
|
||||
x = rotateMaybe(x);
|
||||
pos = x;
|
||||
Double res = (Double) gpProblem.evaluate(this);
|
||||
double[] fit = new double[1];
|
||||
|
@ -10,6 +10,8 @@ public interface InterfaceFirstOrderDerivableProblem {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return the first order gradients of this problem
|
||||
*/
|
||||
|
@ -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();
|
||||
}
|
@ -19,6 +19,12 @@ public interface InterfaceMultimodalProblemKnown extends InterfaceMultimodalProb
|
||||
*/
|
||||
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
|
||||
* the optima are unknown.
|
||||
@ -48,5 +54,5 @@ public interface InterfaceMultimodalProblemKnown extends InterfaceMultimodalProb
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public double getEpsilon();
|
||||
public double getDefaultAccuracy();
|
||||
}
|
||||
|
@ -267,9 +267,10 @@ public class SimpleProblemWrapper extends AbstractOptimizationProblem {
|
||||
* @return description
|
||||
*/
|
||||
public String globalInfo() {
|
||||
Object maybeAdditionalString = BeanInspector.callIfAvailable(simProb, "globalInfo", null);
|
||||
if (maybeAdditionalString != null) {
|
||||
return "Wrapping a simple problem: " + (String)maybeAdditionalString;
|
||||
} else return "Wrapping a simple problem.";
|
||||
return "Wrapping simple problem implementations.";
|
||||
}
|
||||
|
||||
public String[] getGOEPropertyUpdateLinks() {
|
||||
return new String[] {"globalInfo", "simpleProblem"};
|
||||
}
|
||||
}
|
||||
|
@ -327,7 +327,7 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis
|
||||
* @return True if converged.
|
||||
*/
|
||||
private boolean testSpeciesForConvergence(Population pop) {
|
||||
ArrayList<AbstractEAIndividual> speciesHistory = pop.m_History;
|
||||
ArrayList<AbstractEAIndividual> speciesHistory = pop.getHistory();
|
||||
int histLen = speciesHistory.size();
|
||||
|
||||
if (histLen <= haltingWindow) {
|
||||
@ -762,7 +762,7 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis
|
||||
if (plot && (m_Topology!=null)) plotLine(m_Topology, spec1.getBestEAIndividual(), spec2.getBestEAIndividual());
|
||||
spec1.addPopulation(spec2);
|
||||
// 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());
|
||||
// possibly notify the optimizer of the merging event to merge population based information
|
||||
if (m_Optimizer instanceof InterfaceSpeciesAware) ((InterfaceSpeciesAware)m_Optimizer).mergeToFirstPopulationEvent(spec1, spec2);
|
||||
@ -780,10 +780,10 @@ public class ClusterBasedNichingEA implements InterfacePopulationChangedEventLis
|
||||
newSp.setUseHistory(true);
|
||||
if (startAtP1Gen) { // start explicitely as a child population of p1
|
||||
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)
|
||||
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);
|
||||
|
@ -138,8 +138,7 @@ public class EvolutionStrategyIPOP extends EvolutionStrategies implements Interf
|
||||
protected void firePropertyChangedEvent(String name) {
|
||||
if (name.equals(Population.funCallIntervalReached)) {
|
||||
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() {
|
||||
@ -152,7 +151,7 @@ public class EvolutionStrategyIPOP extends EvolutionStrategies implements Interf
|
||||
super.setLambda(initialLambda);
|
||||
checkPopulationConstraints();
|
||||
setForceOrigPopSize(false);
|
||||
getPopulation().setNotifyEvalInterval(initialLambda);
|
||||
getPopulation().setNotifyEvalInterval(Math.max(initialLambda, 100));
|
||||
super.init();
|
||||
bestList = new LinkedList<AbstractEAIndividual>();
|
||||
best = getPopulation().getBestEAIndividual();
|
||||
@ -291,7 +290,6 @@ public class EvolutionStrategyIPOP extends EvolutionStrategies implements Interf
|
||||
public double getStagThreshold() {
|
||||
return stagThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stagThreshold the stagThreshold to set
|
||||
*/
|
||||
@ -299,6 +297,9 @@ public class EvolutionStrategyIPOP extends EvolutionStrategies implements Interf
|
||||
this.stagThreshold = 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
|
||||
|
@ -1,5 +1,6 @@
|
||||
package eva2.server.go.strategies;
|
||||
|
||||
import eva2.gui.BeanInspector;
|
||||
import eva2.server.go.InterfacePopulationChangedEventListener;
|
||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
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_PartnerSelection.prepareSelection(this.m_Population);
|
||||
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) {
|
||||
((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());
|
||||
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().getArchive() != null) {
|
||||
// System.out.println("Zwei Archive!");
|
||||
|
@ -1,5 +1,6 @@
|
||||
package eva2.server.go.strategies;
|
||||
|
||||
import eva2.gui.BeanInspector;
|
||||
import eva2.server.go.InterfacePopulationChangedEventListener;
|
||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
import eva2.server.go.individuals.InterfaceDataTypeDouble;
|
||||
@ -50,6 +51,8 @@ public class GradientDescentAlgorithm implements InterfaceOptimizer, java.io.Ser
|
||||
transient private String m_Identifier = "";
|
||||
private Population m_Population;
|
||||
|
||||
private static boolean TRACE=false;
|
||||
|
||||
private static final String lockKey = "gdaLockDataKey";
|
||||
private static final String lastFitnessKey = "gdaLastFitDataKey";
|
||||
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.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() {
|
||||
/**@todo Implement InterfaceOptimizer method*/
|
||||
@ -140,6 +160,7 @@ public class GradientDescentAlgorithm implements InterfaceOptimizer, java.io.Ser
|
||||
double[] oldchange = null;
|
||||
|
||||
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
|
||||
for (int li = 0; li < wstepsize.length; 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));
|
||||
// Hashtable history = (Hashtable) indyhash.get(indy);
|
||||
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));
|
||||
double[] changes = (double[]) indy.getData(changesKey);
|
||||
int[] lock = (int[]) indy.getData(lockKey);
|
||||
|
@ -120,7 +120,7 @@ public class MemeticAlgorithm implements InterfaceOptimizer,
|
||||
if (TRACE) System.out.println("global search");
|
||||
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.m_Problem instanceof InterfaceLocalSearchable)) {
|
||||
// here the local search is performed
|
||||
|
@ -83,8 +83,10 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
|
||||
public void addPopulationChangedEventListener(
|
||||
InterfacePopulationChangedEventListener ea) {
|
||||
if (m_Listener == null) m_Listener = new Vector<InterfacePopulationChangedEventListener>();
|
||||
if (!m_Listener.contains(ea)) m_Listener.add(ea);
|
||||
if (ea!=null) {
|
||||
if (m_Listener == null) m_Listener = new Vector<InterfacePopulationChangedEventListener>();
|
||||
if (!m_Listener.contains(ea)) m_Listener.add(ea);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean removePopulationChangedEventListener(
|
||||
@ -270,7 +272,7 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
// m_Problem.evaluate(ind);
|
||||
// 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!!
|
||||
|
||||
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;
|
||||
} while (evalsDone < generationCycle);
|
||||
m_Problem.evaluatePopulationEnd(m_Population);
|
||||
this.m_Population.incrGeneration();
|
||||
}
|
||||
|
||||
public void setPopulation(Population pop) {
|
||||
@ -344,7 +347,7 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
NelderMeadSimplex nms = new NelderMeadSimplex();
|
||||
nms.setProblemAndPopSize(problem);
|
||||
|
||||
nms.addPopulationChangedEventListener(listener);
|
||||
if (listener!=null) nms.addPopulationChangedEventListener(listener);
|
||||
nms.init();
|
||||
|
||||
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.
|
||||
*
|
||||
* @param candidate
|
||||
* @param perturbRatio
|
||||
* @param perturbRelative
|
||||
* @param range
|
||||
* @param includeCand
|
||||
* @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();
|
||||
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)");
|
||||
}
|
||||
addPerturbedPopulation(perturbRatio, initPop, range, candidate);
|
||||
addPerturbedPopulation(perturbRelative, initPop, range, candidate);
|
||||
return initPop;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
package eva2.server.go.strategies;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Vector;
|
||||
|
||||
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.AbstractEAIndividualComparator;
|
||||
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.paramcontrol.ParamAdaption;
|
||||
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();
|
||||
Object[] sortedPop = null;
|
||||
protected AbstractEAIndividual m_BestIndividual;
|
||||
protected AbstractEAIndividual m_BestIndividual = null;
|
||||
protected InterfaceOptimizationProblem m_Problem = new F1Problem();
|
||||
protected boolean m_CheckRange = true;
|
||||
protected boolean checkSpeedLimit = false;
|
||||
@ -127,6 +130,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
transient protected eva2.gui.Plot m_Plot;
|
||||
|
||||
private boolean externalInitialPop = false;
|
||||
private static String lastSuccessKey = "successfulUpdate";
|
||||
// private double lsCandidateRatio=0.25;
|
||||
|
||||
|
||||
@ -137,7 +141,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
algType = new SelectedTag("Inertness", "Constriction");
|
||||
algType.setSelectedTag(1);
|
||||
|
||||
setWithConstriction(getPhi1(), getPhi2());
|
||||
setConstriction(getPhi1(), getPhi2());
|
||||
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
|
||||
initDefaults(this.m_Population);
|
||||
this.evaluatePopulation(this.m_Population);
|
||||
if (m_BestIndividual == null) m_BestIndividual = m_Population.getBestEAIndividual();
|
||||
initByPopulation(null, false);
|
||||
externalInitialPop = false;
|
||||
}
|
||||
@ -673,8 +678,9 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
AbstractEAIndividual indy = (AbstractEAIndividual)pop.get(i);
|
||||
if (isIndividualToUpdate(indy)) {
|
||||
updateIndProps(indy, indy);
|
||||
indy.putData(lastSuccessKey , indy.getData(partVelKey));
|
||||
// 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];
|
||||
|
||||
if (useAlternative) {
|
||||
accel = getAccelerationAlternative(personalBestPos, neighbourBestPos, curPosition, range);
|
||||
accel = getAccelerationAlternative(index, personalBestPos, neighbourBestPos, curPosition, range);
|
||||
} else {
|
||||
accel = getAcceleration(personalBestPos, neighbourBestPos, curPosition, range);
|
||||
}
|
||||
@ -801,33 +807,75 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
return accel;
|
||||
}
|
||||
|
||||
protected double[] getAccelerationAlternative(double[] personalBestPos, double[] neighbourBestPos, double[] curPosition, double[][] range) {
|
||||
double[] accel = new double[curPosition.length];
|
||||
double chi;
|
||||
|
||||
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++) {
|
||||
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);
|
||||
protected double[] getAccelerationAlternative(int index, double[] personalBestPos, double[] neighbourBestPos, double[] curPosition, double[][] range) {
|
||||
double[] accel = getAcceleration(personalBestPos, neighbourBestPos, curPosition, range);
|
||||
double[] successfulVel = getSuccessfulVel(index);
|
||||
// double succW = 0.5;
|
||||
if (successfulVel!=null) {
|
||||
Mathematics.vvAdd(accel, successfulVel, accel);
|
||||
Mathematics.svMult(0.5, accel, 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) {
|
||||
// ParticleSwarmOptimization pso = new ParticleSwarmOptimization();
|
||||
// GVector tmp, vec = new GVector(5);
|
||||
@ -886,6 +934,13 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
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) {
|
||||
if (val < min) return min;
|
||||
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));
|
||||
}
|
||||
}
|
||||
m_BestIndividual = pop.getBestEAIndividual();
|
||||
}
|
||||
public String populationTipText() {
|
||||
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
|
||||
* calling the setAsTau methods. The constriction scheme calculates the speed update in the following
|
||||
* Set the phi values as well as the inertness parameter so as to resemble the constriction scheme.
|
||||
* 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)))
|
||||
* 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
|
||||
@ -1662,11 +1718,14 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
* @param tau1
|
||||
* @param tau2
|
||||
*/
|
||||
protected void setWithConstriction(double tau1, double tau2) {
|
||||
protected void setConstriction(double tau1, double tau2) {
|
||||
double pSum = tau1+tau2;
|
||||
if (pSum <= 4) {
|
||||
System.err.println("error, invalid tauSum value in PSO::setWithConstriction");
|
||||
} 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)))));
|
||||
}
|
||||
}
|
||||
@ -1691,7 +1750,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
*/
|
||||
public void setPhi1 (double l) {
|
||||
this.m_Phi1 = l;
|
||||
if (algType.getSelectedTag().getID() == 1) setWithConstriction(getPhi1(), getPhi2());
|
||||
if (algType.getSelectedTag().getID() == 1) setConstriction(getPhi1(), getPhi2());
|
||||
}
|
||||
public double getPhi1() {
|
||||
return this.m_Phi1;
|
||||
@ -1705,7 +1764,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
*/
|
||||
public void setPhi2 (double l) {
|
||||
this.m_Phi2 = l;
|
||||
if (algType.getSelectedTag().getID() == 1) setWithConstriction(getPhi1(), getPhi2());
|
||||
if (algType.getSelectedTag().getID() == 1) setConstriction(getPhi1(), getPhi2());
|
||||
}
|
||||
public double getPhi2() {
|
||||
return this.m_Phi2;
|
||||
@ -1723,7 +1782,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
public void setPhiValues(double phi1, double phi2) {
|
||||
m_Phi1 = phi1;
|
||||
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) {
|
||||
this.algType = s;
|
||||
if (s.getSelectedTag().getID() == 1) setWithConstriction(getPhi1(), getPhi2());
|
||||
if (s.getSelectedTag().getID() == 1) setConstriction(getPhi1(), getPhi2());
|
||||
}
|
||||
|
||||
public SelectedTag getAlgoType() {
|
||||
@ -1956,7 +2015,10 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
for (int i=0; i<population.size(); i++) {
|
||||
double[] personalBestPos = (double[]) population.getEAIndividual(i).getData(partBestPosKey);
|
||||
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 (Math.abs(relDiff)>1e-20) {
|
||||
System.err.println("Warning: mismatching best fitness by " + relDiff);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package eva2.server.stat;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
@ -14,7 +15,6 @@ import eva2.server.go.IndividualInterface;
|
||||
import eva2.server.go.PopulationInterface;
|
||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
import eva2.server.go.operators.distancemetric.InterfaceDistanceMetric;
|
||||
import eva2.server.go.populations.InterfaceSolutionSet;
|
||||
import eva2.server.go.populations.Population;
|
||||
import eva2.server.go.problems.InterfaceAdditionalPopulationInformer;
|
||||
import eva2.server.go.strategies.InterfaceOptimizer;
|
||||
@ -107,13 +107,18 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
* @param infoString
|
||||
*/
|
||||
protected void initOutput(String infoString) {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("E'_'yyyy.MM.dd'_at_'HH.mm.ss");
|
||||
String startDate = formatter.format(new Date());
|
||||
String startDate = getDateString();
|
||||
// open the result file:
|
||||
if (doFileOutput() // not "text-window only"
|
||||
&& (m_StatsParams.getOutputVerbosity().getSelectedTagID() > StatsParameter.VERBOSITY_NONE)) { // verbosity accordingly high
|
||||
//!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);
|
||||
try {
|
||||
resultOut = new PrintWriter(new FileOutputStream(fname));
|
||||
@ -126,6 +131,16 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
} 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() {
|
||||
return (m_StatsParams.getOutputTo().getSelectedTagID()!=1); // not "text-window only"
|
||||
}
|
||||
@ -319,9 +334,7 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
if (TRACE)
|
||||
System.out.println("End of run");
|
||||
if (resultOut != null) {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat(
|
||||
"E'_'yyyy.MM.dd'_at_'hh:mm:ss");
|
||||
String StopDate = formatter.format(new Date());
|
||||
String StopDate = getDateString();
|
||||
resultOut.println("StopDate:" + StopDate);
|
||||
resultOut.close();
|
||||
}
|
||||
@ -686,11 +699,13 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
}
|
||||
// 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()) {
|
||||
Pair<String,Double[]> addInfo = getOutputLine(informerList, lastSols);
|
||||
|
||||
if (printLineByVerbosity(runIterCnt)) printToTextListener(addInfo.head()+'\n');
|
||||
if (printLineByVerbosity(runIterCnt)) {
|
||||
printToTextListener(addInfo.head()+'\n');
|
||||
}
|
||||
// updateAdditionalInfo(addInfo.tail());
|
||||
if (addInfo.tail()!=null) {
|
||||
additionalInfoSums = updateAdditionalInfo(additionalInfoSums, addInfo.tail());
|
||||
@ -728,7 +743,14 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
}
|
||||
|
||||
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() {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package eva2.tools;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
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.
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
* @param args
|
||||
@ -88,16 +89,30 @@ public class StringTools {
|
||||
for (int i=0; i<args.length; i++) { // loop all arguments
|
||||
boolean found=false;
|
||||
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])))
|
||||
|| (!ignoreCase && (args[i].equals(keys[k])))) { // if the key was found
|
||||
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
|
||||
values[k]=new String[arities[k]];
|
||||
for (int j=0; j<arities[k]; j++) {
|
||||
i++;
|
||||
((String[])values[k])[j]=args[i];
|
||||
try {
|
||||
if (arities[k]==1) {
|
||||
values[k]=args[i+1];
|
||||
} 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()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@ -122,10 +122,10 @@ private static final boolean TRACE = false;
|
||||
*/
|
||||
public DRectangle getDRectangle(){
|
||||
DRectangle rect = (DRectangle)visible_rect.clone();
|
||||
if( min_x != null ) rect.x = Math.max(rect.x, getMinX() );
|
||||
if( min_y != null ) rect.y = Math.max(rect.y, getMinY() );
|
||||
if( max_x != null ) rect.width = Math.min(rect.width, getMaxX() - getMinX());
|
||||
if( max_y != null ) rect.height = Math.min(rect.height, getMaxY() - getMinY());
|
||||
if( min_x != null ) rect.setX(Math.max(rect.getX(), getMinX() ));
|
||||
if( min_y != null ) rect.setY(Math.max(rect.getY(), getMinY() ));
|
||||
if( max_x != null ) rect.setWidth(Math.min(rect.getWidth(), getMaxX() - getMinX()));
|
||||
if( max_y != null ) rect.setHeight(Math.min(rect.getHeight(), getMaxY() - getMinY()));
|
||||
return rect;
|
||||
}
|
||||
|
||||
@ -135,7 +135,7 @@ private static final boolean TRACE = false;
|
||||
* @return DRectangle the size and position of the visible area
|
||||
*/
|
||||
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_y != null ) srect.y = Math.max(srect.y, getMinY() );
|
||||
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"
|
||||
+ "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;
|
||||
visible_rect = (DRectangle)rect.clone();
|
||||
repaint();
|
||||
@ -278,7 +278,7 @@ private static final boolean TRACE = false;
|
||||
* @param mix the minimal x-value
|
||||
*/
|
||||
public void setMinX( double mix ){
|
||||
if( mix > min_rect.x ) throw
|
||||
if( mix > min_rect.getX() ) throw
|
||||
new IllegalArgumentException(
|
||||
"Mimimal y-value axes intersects minmal rectangle.");
|
||||
min_x = new Double( mix );
|
||||
@ -309,7 +309,7 @@ private static final boolean TRACE = false;
|
||||
* @param miy the minimal y-value
|
||||
*/
|
||||
public void setMinY( double miy ){
|
||||
if( miy > min_rect.y ) throw
|
||||
if( miy > min_rect.getY() ) throw
|
||||
new IllegalArgumentException(
|
||||
"Mimimal y-value axes intersects minmal rectangle.");
|
||||
min_y = new Double( miy );
|
||||
@ -341,7 +341,7 @@ private static final boolean TRACE = false;
|
||||
* @param max the maximal x-value
|
||||
*/
|
||||
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(
|
||||
"Maximal x-value axes intersects minmal rectangle.");
|
||||
max_x = new Double( max );
|
||||
@ -373,7 +373,7 @@ private static final boolean TRACE = false;
|
||||
* @param may the maximal y-value
|
||||
*/
|
||||
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(
|
||||
"Maximal y-value axes intersects minmal rectangle.");
|
||||
max_y = new Double( may );
|
||||
@ -432,8 +432,10 @@ private static final boolean TRACE = false;
|
||||
new IllegalArgumentException("Cannot repaint a null DRectangle");
|
||||
if( r.isAll() || auto_focus ) repaint();
|
||||
else{
|
||||
Point p1 = measures.getPoint( r.x, r.y ),
|
||||
p2 = measures.getPoint( r.x + r.width, r.y + r.height);
|
||||
Point p1 = measures.getPoint( r.getX(), r.getY() ),
|
||||
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();
|
||||
else {
|
||||
DBorder b = getDBorder();
|
||||
@ -690,8 +692,8 @@ private static final boolean TRACE = false;
|
||||
return;
|
||||
}
|
||||
else{
|
||||
grid.setDistances(ScaledBorder.aBitBigger( grid.rectangle.width / max_grid ),
|
||||
ScaledBorder.aBitBigger( grid.rectangle.height / max_grid ));
|
||||
grid.setDistances(ScaledBorder.aBitBigger( grid.rectangle.getWidth() / max_grid ),
|
||||
ScaledBorder.aBitBigger( grid.rectangle.getHeight() / max_grid ));
|
||||
}
|
||||
}
|
||||
grid.paint( m );
|
||||
|
@ -96,8 +96,8 @@ public class DGrid extends DComponent
|
||||
DPoint p1, p2;
|
||||
DLine l;
|
||||
|
||||
minX=Mathematics.firstMultipleAbove(rectangle.x, hor_dist);
|
||||
minY=Mathematics.firstMultipleAbove(rectangle.y, ver_dist);
|
||||
minX=Mathematics.firstMultipleAbove(rectangle.getX(), hor_dist);
|
||||
minY=Mathematics.firstMultipleAbove(rectangle.getY(), ver_dist);
|
||||
// minX = (int)( rectangle.x / hor_dist );
|
||||
// if( minX * hor_dist <= rectangle.x ) minX++;
|
||||
// minX *= hor_dist;
|
||||
@ -105,18 +105,18 @@ public class DGrid extends DComponent
|
||||
// if( minY * ver_dist <= rectangle.y ) minY++;
|
||||
// minY *= ver_dist;
|
||||
|
||||
p1 = new DPoint( 0, rectangle.y );
|
||||
p2 = new DPoint( 0, rectangle.y + rectangle.height );
|
||||
for( pos = minX; pos<=rectangle.x + rectangle.width; pos += hor_dist ){
|
||||
p1 = new DPoint( 0, rectangle.getY() );
|
||||
p2 = new DPoint( 0, rectangle.getY() + rectangle.getHeight() );
|
||||
for( pos = minX; pos<=rectangle.getX() + rectangle.getWidth(); pos += hor_dist ){
|
||||
p1.x = p2.x = pos;
|
||||
l = new DLine( p1, p2, color );
|
||||
l.paint( m );
|
||||
}
|
||||
|
||||
p1.x = rectangle.x;
|
||||
p2.x = p1.x + rectangle.width;
|
||||
p1.x = rectangle.getX();
|
||||
p2.x = p1.x + rectangle.getWidth();
|
||||
pos = minY;
|
||||
while ( pos<=rectangle.y + rectangle.height){
|
||||
while ( pos<=rectangle.getY() + rectangle.getHeight()){
|
||||
p1.y = p2.y = pos;
|
||||
l = new DLine( p1, p2, color );
|
||||
l.paint( m );
|
||||
|
@ -24,7 +24,8 @@ import java.awt.* ;
|
||||
|
||||
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;
|
||||
protected int status;
|
||||
protected Color fillColor;
|
||||
@ -38,11 +39,11 @@ public class DRectangle extends DComponent
|
||||
super(true);
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
if( width < 0 ) throw
|
||||
new IllegalArgumentException("Width of a DRectangle has to be >= 0");
|
||||
if( width < 0 || Double.isInfinite(width) || Double.isNaN(width)) throw
|
||||
new IllegalArgumentException("Width of a DRectangle is invalid (" + width + ")");
|
||||
this.width = width;
|
||||
if( height < 0 ) throw
|
||||
new IllegalArgumentException("Height of a DRectangle has to be >= 0");
|
||||
if( height < 0 || Double.isInfinite(height) || Double.isNaN(height)) throw
|
||||
new IllegalArgumentException("Height of a DRectangle is invalid (" + height + ")");
|
||||
this.height = height;
|
||||
status = PART;
|
||||
}
|
||||
@ -78,6 +79,31 @@ public class DRectangle extends DComponent
|
||||
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.
|
||||
*
|
||||
@ -135,7 +161,9 @@ public class DRectangle extends DComponent
|
||||
* @return true when the size of the rectangle changed
|
||||
*/
|
||||
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( contains( p ) ) return false;
|
||||
if( isEmpty() ){
|
||||
|
@ -69,7 +69,7 @@ public class ScaledBorder implements Border
|
||||
* the size of the source rectangle
|
||||
* that means before the values are mdified by scale functions
|
||||
*/
|
||||
SlimRect src_rect;
|
||||
SlimRect src_rect = null;
|
||||
|
||||
/**
|
||||
* 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 );
|
||||
}
|
||||
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 += src_dY;
|
||||
@ -336,6 +336,9 @@ public class ScaledBorder implements Border
|
||||
if( under_construction ) System.out.println("ScaledBorder.getSrcdY()");
|
||||
if( (!do_refresh && src_dY != -1) || !auto_scale_y ) return src_dY;
|
||||
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 <--------------------------
|
||||
src_dY = aBitBigger( minsrc_dY );
|
||||
if( src_dY < minimal_increment ) src_dY = minimal_increment;
|
||||
@ -417,7 +420,7 @@ public class ScaledBorder implements Border
|
||||
* @return the displayable value
|
||||
*/
|
||||
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;
|
||||
if( min < d ){
|
||||
while( d * .5 > min ) {
|
||||
|
@ -69,7 +69,7 @@ public class SlimRect {
|
||||
* @return A rectangle representing the intersection or null
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -743,44 +743,82 @@ public class Mathematics {
|
||||
public static void normalizeSum(double[] v, double[] 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);
|
||||
|
||||
/**
|
||||
* 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();
|
||||
// make partial rotation matrix
|
||||
getRotationEntriesSingleAxis(tmp, 0, i, w);
|
||||
|
||||
A = tmp.times(A); // add to resulting rotation
|
||||
z = tmp.times(z); // z is now 0 in i-th component
|
||||
|
||||
// reset tmp matrix to unity
|
||||
resetRotationEntriesSingleAxis(tmp, 0, i);
|
||||
}
|
||||
return A;
|
||||
}
|
||||
|
||||
double w, cosw, sinw;
|
||||
|
||||
z.multi(z.norm2()); // normalize
|
||||
|
||||
|
||||
for (int i=1; i<vec.getRowDimension(); i++) {
|
||||
w = Math.atan2(z.get(i,0), z.get(0,0));// calc angle between the projection of x and x0 in x0-xi-plane
|
||||
|
||||
cosw = Math.cos(w);
|
||||
sinw = Math.sin(w);
|
||||
tmp.set(0, 0, cosw); // make partial rotation matrix
|
||||
tmp.set(0, i, sinw);
|
||||
tmp.set(i, 0, -sinw);
|
||||
tmp.set(i, i, cosw);
|
||||
|
||||
A = tmp.times(A); // add to resulting rotation
|
||||
z = tmp.times(z); // z is now 0 in i-th component
|
||||
|
||||
tmp.set(0, 0, 1); // reset tmp matrix to unity
|
||||
tmp.set(0, i, 0);
|
||||
tmp.set(i, 0, 0);
|
||||
tmp.set(i, i, 1);
|
||||
}
|
||||
return A;
|
||||
}
|
||||
public static Matrix getRotationMatrix(double w, int dim) {
|
||||
Matrix A = Matrix.identity(dim, dim);
|
||||
Matrix tmp = Matrix.identity(dim, dim);
|
||||
|
||||
for (int i=1; i<dim; i++) {
|
||||
// System.out.println("deg: "+(w/Math.PI)*180);
|
||||
// make partial rotation matrix
|
||||
getRotationEntriesSingleAxis(tmp, i-1, i, w);
|
||||
A = tmp.times(A); // add to resulting rotation
|
||||
// reset tmp matrix to unity
|
||||
resetRotationEntriesSingleAxis(tmp, i-1, i);
|
||||
}
|
||||
// Matrix vec = new Matrix(dim, 1);
|
||||
// for (int i=0; i<dim; i++) vec.set(i,0, 1);
|
||||
// vec = A.times(vec);
|
||||
// vec = A.times(vec);
|
||||
return A;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set rotation matrix entries along i/j axis. w is expected in radians.
|
||||
*
|
||||
* @param tmp
|
||||
* @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
|
||||
@ -796,7 +834,23 @@ public class Mathematics {
|
||||
vect[i] = (xi*Math.cos(alpha))-(xj*Math.sin(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
|
||||
* in [-alpha, alpha] if randomize is true.
|
||||
|
@ -4,27 +4,19 @@ import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class RNG extends Random {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1565216859128723844L;
|
||||
public class RNG {
|
||||
private static Random random;
|
||||
private static long randomSeed;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static {
|
||||
randomSeed = System.currentTimeMillis();
|
||||
random = new Random(randomSeed);
|
||||
randomSeed=System.currentTimeMillis();
|
||||
random=new Random(randomSeed);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
*
|
||||
*/
|
||||
public static void setRandomSeed(long new_seed) {
|
||||
// counter++;
|
||||
randomSeed = new_seed;
|
||||
@ -43,23 +35,23 @@ public class RNG extends Random {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
*
|
||||
*/
|
||||
public static void setRandomSeed() {
|
||||
randomSeed = System.currentTimeMillis();
|
||||
random = new Random(randomSeed);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
*
|
||||
*/
|
||||
public static void setRandom(Random base_random) {
|
||||
random = base_random;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
*
|
||||
*/
|
||||
public static long getRandomSeed() {
|
||||
return randomSeed;
|
||||
}
|
||||
@ -157,6 +149,25 @@ public class RNG extends Random {
|
||||
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).
|
||||
*/
|
||||
@ -172,15 +183,15 @@ public class RNG extends Random {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
*
|
||||
*/
|
||||
public static float randomFloat() {
|
||||
return random.nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
*
|
||||
*/
|
||||
public static float randomFloat(float lo, float hi) {
|
||||
return (hi - lo) * random.nextFloat() + lo;
|
||||
}
|
||||
@ -193,19 +204,23 @@ public class RNG extends Random {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static double randomDouble(double lo, double hi) {
|
||||
return (hi - lo) * random.nextDouble() + lo;
|
||||
*
|
||||
*/
|
||||
public static double randomDouble(double lo,double hi) {
|
||||
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.
|
||||
*/
|
||||
public static double[] randomDoubleArray(double[] lo, double[] hi) {
|
||||
public static double[] randomDoubleArray(double[] lo,double[] hi) {
|
||||
double[] xin = new double[lo.length];
|
||||
for (int i = 0; i < lo.length; i++)
|
||||
xin[i] = (hi[i] - lo[i]) * random.nextDouble() + lo[i];
|
||||
for (int i=0;i<lo.length;i++)
|
||||
xin[i] = (hi[i]-lo[i])*random.nextDouble()+lo[i];
|
||||
return xin;
|
||||
}
|
||||
|
||||
@ -214,48 +229,50 @@ public class RNG extends Random {
|
||||
*/
|
||||
public static double[] randomDoubleArray(double[][] range) {
|
||||
double[] xin = new double[range.length];
|
||||
for (int i = 0; i < xin.length; i++)
|
||||
xin[i] = (range[i][1] - range[i][0]) * random.nextDouble()
|
||||
+ range[i][0];
|
||||
for (int i=0;i<xin.length;i++)
|
||||
xin[i] = (range[i][1]-range[i][0])*random.nextDouble()+range[i][0];
|
||||
return xin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a uniform random double vector within the given bounds (inclusive)
|
||||
* in every dimension.
|
||||
* Create a uniform random double vector within the given bounds (inclusive) in every dimension.
|
||||
*
|
||||
* @param lower
|
||||
* @param upper
|
||||
* @param size
|
||||
* @return
|
||||
*/
|
||||
public static double[] randomDoubleArray(double lower, double upper,
|
||||
int size) {
|
||||
public static double[] randomDoubleArray(double lower, double upper, int size) {
|
||||
double[] result = new double[size];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = RNG.randomDouble(lower, upper);
|
||||
}
|
||||
return result;
|
||||
// double[] xin = new double[size];
|
||||
// for (int i=0;i<size;i++)
|
||||
// xin[i] = (hi-lo)*random.nextDouble()+lo;
|
||||
// return xin;
|
||||
// double[] xin = new double[size];
|
||||
// for (int i=0;i<size;i++)
|
||||
// xin[i] = (hi-lo)*random.nextDouble()+lo;
|
||||
// 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,
|
||||
double[] xin) {
|
||||
// counter++;
|
||||
for (int i = 0; i < lo.length; i++)
|
||||
xin[i] = (hi[i] - lo[i]) * random.nextDouble() + lo[i];
|
||||
*
|
||||
*/
|
||||
public static double[] randomDoubleArray(double[] lo,double[] hi,double[] xin) {
|
||||
//counter++;
|
||||
for (int i=0;i<lo.length;i++)
|
||||
xin[i] = (hi[i]-lo[i])*random.nextDouble()+lo[i];
|
||||
return xin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a uniform random integer vector within the given bounds
|
||||
* (inclusive) in every dimension.
|
||||
* Create a uniform random integer vector within the given bounds (inclusive) in every dimension.
|
||||
*
|
||||
* @param n
|
||||
* @param lower
|
||||
@ -270,17 +287,24 @@ public class RNG extends Random {
|
||||
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() {
|
||||
// counter++;
|
||||
return (randomInt() == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
*
|
||||
*/
|
||||
public static int randomBit() {
|
||||
// counter++;
|
||||
return randomInt();
|
||||
@ -298,8 +322,8 @@ public class RNG extends Random {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
*
|
||||
*/
|
||||
public static float gaussianFloat(float dev) {
|
||||
// counter++;
|
||||
return (float) random.nextGaussian() * dev;
|
||||
@ -318,16 +342,16 @@ public class RNG extends Random {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
*
|
||||
*/
|
||||
public static float exponentialFloat(float mean) {
|
||||
// counter++;
|
||||
return (float) (-mean * Math.log(randomDouble()));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
*
|
||||
*/
|
||||
public static double exponentialDouble(double mean) {
|
||||
// counter++;
|
||||
return -mean * Math.log(randomDouble());
|
||||
|
Loading…
x
Reference in New Issue
Block a user