Merging MK rev. 227 - several minor changes.
This commit is contained in:
parent
245d8892ef
commit
302ca1e02b
@ -101,6 +101,8 @@ public class OptimizerFactory {
|
||||
public final static int CL_HILLCL = 10;
|
||||
|
||||
public final static int CMA_ES_IPOP = 11;
|
||||
|
||||
public final static int CBN_GA = 12;
|
||||
|
||||
public final static int defaultFitCalls = 10000;
|
||||
|
||||
@ -142,6 +144,8 @@ public class OptimizerFactory {
|
||||
de.addPopulationChangedEventListener(listener);
|
||||
de.init();
|
||||
|
||||
listener.registerPopulationStateChanged(de.getPopulation(), "");
|
||||
|
||||
return de;
|
||||
}
|
||||
|
||||
@ -208,13 +212,14 @@ public class OptimizerFactory {
|
||||
AbstractEAIndividual tmpIndi = problem.getIndividualTemplate();
|
||||
AbstractEAIndividual.setOperators(tmpIndi, mutationoperator, pm, crossoveroperator, pc);
|
||||
|
||||
EvolutionStrategies es = new EvolutionStrategies();
|
||||
es.addPopulationChangedEventListener(listener);
|
||||
//es.setParentSelection(selection);
|
||||
//es.setPartnerSelection(selection);
|
||||
es.setEnvironmentSelection(selection);
|
||||
es.SetProblem(problem);
|
||||
es.init();
|
||||
theES.addPopulationChangedEventListener(listener);
|
||||
// theES.setParentSelection(selection);
|
||||
// theES.setPartnerSelection(selection);
|
||||
theES.setEnvironmentSelection(selection);
|
||||
theES.SetProblem(problem);
|
||||
theES.init();
|
||||
|
||||
if (listener != null) listener.registerPopulationStateChanged(theES.getPopulation(), "");
|
||||
|
||||
return theES;
|
||||
}
|
||||
@ -254,6 +259,8 @@ public class OptimizerFactory {
|
||||
ga.addPopulationChangedEventListener(listener);
|
||||
ga.init();
|
||||
|
||||
listener.registerPopulationStateChanged(ga.getPopulation(), "");
|
||||
|
||||
return ga;
|
||||
}
|
||||
|
||||
@ -365,6 +372,8 @@ public class OptimizerFactory {
|
||||
hc.SetProblem(problem);
|
||||
hc.init();
|
||||
|
||||
listener.registerPopulationStateChanged(hc.getPopulation(), "");
|
||||
|
||||
return hc;
|
||||
}
|
||||
|
||||
@ -394,10 +403,11 @@ public class OptimizerFactory {
|
||||
mc.SetProblem(problem);
|
||||
mc.init();
|
||||
|
||||
listener.registerPopulationStateChanged(mc.getPopulation(), "");
|
||||
|
||||
return mc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method performs a particle swarm optimization. Standard topologies are
|
||||
* linear (0), grid (1) and star (2).
|
||||
@ -438,6 +448,8 @@ public class OptimizerFactory {
|
||||
pso.addPopulationChangedEventListener(listener);
|
||||
pso.init();
|
||||
|
||||
listener.registerPopulationStateChanged(pso.getPopulation(), "");
|
||||
|
||||
return pso;
|
||||
}
|
||||
|
||||
@ -477,6 +489,8 @@ public class OptimizerFactory {
|
||||
sa.addPopulationChangedEventListener(listener);
|
||||
sa.init();
|
||||
|
||||
listener.registerPopulationStateChanged(sa.getPopulation(), "");
|
||||
|
||||
return sa;
|
||||
}
|
||||
|
||||
@ -526,9 +540,11 @@ public class OptimizerFactory {
|
||||
case CBN_ES:
|
||||
return cbnES(problem);
|
||||
case CL_HILLCL:
|
||||
return clusteringHillClimbing(problem);
|
||||
return stdClusteringHillClimbing(problem);
|
||||
case CMA_ES_IPOP:
|
||||
return cmaESIPOP(problem);
|
||||
case CBN_GA:
|
||||
return cbnGA(problem);
|
||||
default:
|
||||
System.err.println("Error: optimizer type " + optType
|
||||
+ " is unknown!");
|
||||
@ -602,7 +618,6 @@ public class OptimizerFactory {
|
||||
AbstractOptimizationProblem problem, String outputFilePrefix) {
|
||||
return getOptRunnable(optType, problem, getTerminator(), outputFilePrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current user-defined or, if none was set, the default terminator.
|
||||
*
|
||||
@ -649,6 +664,18 @@ public class OptimizerFactory {
|
||||
return makeParams(opt, popSize, problem, randSeed, makeDefaultTerminator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the population size, initialize the population and return a parameter structure containing all
|
||||
* given parts.
|
||||
*
|
||||
* @see #makeParams(InterfaceOptimizer, Population, AbstractOptimizationProblem, long, InterfaceTerminator)
|
||||
* @param opt
|
||||
* @param popSize
|
||||
* @param problem
|
||||
* @param seed
|
||||
* @param term
|
||||
* @return
|
||||
*/
|
||||
public static GOParameters makeParams(InterfaceOptimizer opt,
|
||||
int popSize, AbstractOptimizationProblem problem, long seed,
|
||||
InterfaceTerminator term) {
|
||||
@ -1035,9 +1062,20 @@ public class OptimizerFactory {
|
||||
*/
|
||||
public static final GOParameters hillClimbing(
|
||||
AbstractOptimizationProblem problem) {
|
||||
return makeParams(new HillClimbing(), 50, problem, randSeed, makeDefaultTerminator());
|
||||
return hillClimbing(problem, 50);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a standard multi-start hill-climber parameter set with the given number of
|
||||
* individuals.
|
||||
*
|
||||
* @return a standard multi-start hill-climber
|
||||
*/
|
||||
public static final GOParameters hillClimbing(
|
||||
AbstractOptimizationProblem problem, int popSize) {
|
||||
return makeParams(new HillClimbing(), popSize, problem, randSeed, makeDefaultTerminator());
|
||||
}
|
||||
|
||||
public static final GOParameters monteCarlo(
|
||||
AbstractOptimizationProblem problem) {
|
||||
return makeParams(new MonteCarloSearch(), 50, problem, randSeed, makeDefaultTerminator());
|
||||
@ -1058,21 +1096,84 @@ public class OptimizerFactory {
|
||||
return makeParams(cbn, 100, problem, randSeed, makeDefaultTerminator());
|
||||
}
|
||||
|
||||
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.setConvergenceCA((ClusteringDensityBased) clustering.clone());
|
||||
cbn.setDifferentationCA(clustering);
|
||||
cbn.setShowCycle(0); // don't do graphical output
|
||||
|
||||
return makeParams(cbn, 100, problem, randSeed, makeDefaultTerminator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a standard clustering hill climbing employing simple ES mutation with adaptive
|
||||
* step size, starting in parallel 100 local searches and clustering intermediate populations
|
||||
* to avoid optima being found several times by the same population (density based clustering with
|
||||
* sigma = 0.05).
|
||||
* The population is reinitialized if the average progress of one cycle does not exceed 1e-6.
|
||||
*
|
||||
* @param problem
|
||||
* @return
|
||||
*/
|
||||
public static final GOParameters stdClusteringHillClimbing(
|
||||
AbstractOptimizationProblem problem) {
|
||||
return clusteringHillClimbing(problem, 1000, 100, 0.000001,
|
||||
PostProcessMethod.hillClimber, 0.05, 0.000001, 0.05);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clustering hillclimber using nelder mead and additional given parameters.
|
||||
*
|
||||
* @param problem
|
||||
* @param evalCycle
|
||||
* @param popSize
|
||||
* @param minImprovement
|
||||
* @param method
|
||||
* @param sigmaClust
|
||||
* @return
|
||||
*/
|
||||
public static final GOParameters clusteringHillClimbingNM(AbstractOptimizationProblem problem,
|
||||
int evalCycle, int popSize, double minImprovement, double sigmaClust) {
|
||||
return clusteringHillClimbing(problem, evalCycle, popSize, minImprovement,
|
||||
PostProcessMethod.nelderMead, 0.01, 0.00000001, sigmaClust);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a custom clustering hillclimber using ES mutation (simple or CMA) or nelder mead.
|
||||
* The parameters hcInitialStep and hcStepThresh are
|
||||
* only relevant for the simple mutation based hc method.
|
||||
*
|
||||
* @param problem
|
||||
* @param evalCycle
|
||||
* @param popSize
|
||||
* @param minImprovement
|
||||
* @param method
|
||||
* @param hcInitialStep
|
||||
* @param hcStepThresh
|
||||
* @param sigmaClust
|
||||
* @return
|
||||
*/
|
||||
public static final GOParameters clusteringHillClimbing(
|
||||
AbstractOptimizationProblem problem) {
|
||||
AbstractOptimizationProblem problem, int evalCycle, int popSize, double minImprovement,
|
||||
PostProcessMethod method, double hcInitialStep, double hcStepThresh, double sigmaClust) {
|
||||
ClusteringHillClimbing chc = new ClusteringHillClimbing();
|
||||
chc.SetProblem(problem);
|
||||
|
||||
chc.setHcEvalCycle(1000);
|
||||
chc.setInitialPopSize(100);
|
||||
chc.setStepSizeInitial(0.05);
|
||||
chc.setMinImprovement(0.000001);
|
||||
chc.setEvalCycle(evalCycle);
|
||||
chc.setInitialPopSize(popSize);
|
||||
chc.setStepSizeInitial(hcInitialStep);
|
||||
chc.setLocalSearchMethod(method);
|
||||
chc.setMinImprovement(minImprovement);
|
||||
chc.setNotifyGuiEvery(0);
|
||||
chc.setStepSizeThreshold(0.000001);
|
||||
chc.setSigmaClust(0.05);
|
||||
return makeParams(chc, 100, problem, randSeed, makeDefaultTerminator());
|
||||
chc.setStepSizeThreshold(hcStepThresh);
|
||||
chc.setSigmaClust(sigmaClust);
|
||||
return makeParams(chc, popSize, problem, randSeed, makeDefaultTerminator());
|
||||
}
|
||||
|
||||
|
||||
public static final GOParameters cmaES(AbstractOptimizationProblem problem) {
|
||||
EvolutionStrategies es = new EvolutionStrategies();
|
||||
es.setMu(15);
|
||||
|
@ -25,67 +25,71 @@ import javax.swing.JPanel;
|
||||
|
||||
import eva2.tools.EVAHELP;
|
||||
/*==========================================================================*
|
||||
* CLASS DECLARATION
|
||||
*==========================================================================*/
|
||||
* CLASS DECLARATION
|
||||
*==========================================================================*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PropertyPanel extends JPanel {
|
||||
private PropertyEditor m_PropertyEditor;
|
||||
private PropertyDialog m_PropertyDialog;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public PropertyPanel(PropertyEditor Editor) {
|
||||
setBorder(BorderFactory.createEtchedBorder());
|
||||
setToolTipText("Click to edit properties for this object");
|
||||
setOpaque(true);
|
||||
m_PropertyEditor = Editor;
|
||||
addMouseListener(new MouseAdapter() {
|
||||
public void mouseClicked(MouseEvent evt) {
|
||||
if (m_PropertyEditor.getValue() != null) {
|
||||
if (m_PropertyDialog == null) {
|
||||
int x = getLocationOnScreen().x;
|
||||
int y = getLocationOnScreen().y;
|
||||
m_PropertyDialog = new PropertyDialog(m_PropertyEditor, EVAHELP.cutClassName(m_PropertyEditor.getClass().getName()) , x, y);
|
||||
}
|
||||
else {
|
||||
m_PropertyDialog.updateFrameTitle(m_PropertyEditor);
|
||||
m_PropertyDialog.setVisible(true);
|
||||
}
|
||||
private PropertyEditor m_PropertyEditor;
|
||||
private PropertyDialog m_PropertyDialog;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public PropertyPanel(PropertyEditor Editor) {
|
||||
setBorder(BorderFactory.createEtchedBorder());
|
||||
setToolTipText("Click to edit properties for this object");
|
||||
setOpaque(true);
|
||||
m_PropertyEditor = Editor;
|
||||
addMouseListener(new MouseAdapter() {
|
||||
public void mouseClicked(MouseEvent evt) {
|
||||
if (m_PropertyEditor.getValue() != null) {
|
||||
if (m_PropertyDialog == null) {
|
||||
int x = getLocationOnScreen().x;
|
||||
int y = getLocationOnScreen().y;
|
||||
m_PropertyDialog = new PropertyDialog(m_PropertyEditor, EVAHELP.cutClassName(m_PropertyEditor.getClass().getName()) , x, y);
|
||||
}
|
||||
else {
|
||||
m_PropertyDialog.updateFrameTitle(m_PropertyEditor);
|
||||
m_PropertyDialog.setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
Dimension newPref = getPreferredSize();
|
||||
newPref.height = getFontMetrics(getFont()).getHeight() * 6 / 4; //6 / 4;
|
||||
newPref.width = newPref.height * 6; //5
|
||||
setPreferredSize(newPref);
|
||||
}
|
||||
}
|
||||
});
|
||||
Dimension newPref = getPreferredSize();
|
||||
newPref.height = getFontMetrics(getFont()).getHeight() * 6 / 4; //6 / 4;
|
||||
newPref.width = newPref.height * 6; //5
|
||||
setPreferredSize(newPref);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void removeNotify() {
|
||||
if (m_PropertyDialog != null) {
|
||||
//System.out.println(" m_PropertyDialog.dispose();");
|
||||
m_PropertyDialog.dispose();
|
||||
m_PropertyDialog = null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void paintComponent(Graphics g) {
|
||||
Insets i = getInsets();
|
||||
Rectangle box = new Rectangle(i.left, i.top,
|
||||
getSize().width - i.left - i.right ,
|
||||
getSize().height - i.top - i.bottom);
|
||||
g.clearRect(i.left, i.top,
|
||||
getSize().width - i.right - i.left,
|
||||
getSize().height - i.bottom - i.top);
|
||||
m_PropertyEditor.paintValue(g, box);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void removeNotify() {
|
||||
if (m_PropertyDialog != null) {
|
||||
//System.out.println(" m_PropertyDialog.dispose();");
|
||||
m_PropertyDialog.dispose();
|
||||
m_PropertyDialog = null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void paintComponent(Graphics g) {
|
||||
Insets i = getInsets();
|
||||
Rectangle box = new Rectangle(i.left, i.top,
|
||||
getSize().width - i.left - i.right ,
|
||||
getSize().height - i.top - i.bottom);
|
||||
g.clearRect(i.left, i.top,
|
||||
getSize().width - i.right - i.left,
|
||||
getSize().height - i.bottom - i.top);
|
||||
m_PropertyEditor.paintValue(g, box);
|
||||
|
||||
// Rectangle box = new Rectangle(i.left,i.top,
|
||||
// this.getWidth() - i.right,
|
||||
// this.getHeight() - i.bottom );
|
||||
}
|
||||
// Rectangle box = new Rectangle(i.left,i.top,
|
||||
// this.getWidth() - i.right,
|
||||
// this.getHeight() - i.bottom );
|
||||
}
|
||||
|
||||
public PropertyEditor getEditor() {
|
||||
return m_PropertyEditor;
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,13 @@ import eva2.tools.StringTools;
|
||||
* CLASS DECLARATION
|
||||
*==========================================================================*/
|
||||
/**
|
||||
*
|
||||
* TODO: document those tricks somewhere
|
||||
* Trick methods:
|
||||
* String[] getGOEPropertyUpdateLinks()
|
||||
* void hideHideable()
|
||||
* void globalInfo()
|
||||
* Trick statics:
|
||||
* boolean hideFromGOE
|
||||
*/
|
||||
public class PropertySheetPanel extends JPanel implements PropertyChangeListener {
|
||||
public final static boolean TRACE = false;
|
||||
@ -232,7 +238,7 @@ public class PropertySheetPanel extends JPanel implements PropertyChangeListener
|
||||
}
|
||||
} // end for (int i = 0; i < m_Methods.length; i++) {
|
||||
|
||||
// Now lets search for the individual properties their
|
||||
// Now lets search for the individual properties, their
|
||||
// values, views and editors...
|
||||
m_Editors = new PropertyEditor[m_Properties.length];
|
||||
m_Values = new Object[m_Properties.length];
|
||||
@ -319,77 +325,7 @@ public class PropertySheetPanel extends JPanel implements PropertyChangeListener
|
||||
} // end try
|
||||
|
||||
// Add some specific display for some greeks here
|
||||
if (name.equalsIgnoreCase("alpha"))
|
||||
name = "\u03B1";
|
||||
if (name.equalsIgnoreCase("beta"))
|
||||
name = "\u03B2";
|
||||
if (name.equalsIgnoreCase("gamma"))
|
||||
name = "\u03B3";
|
||||
if (name.equalsIgnoreCase("gammab"))
|
||||
name = "\u0393";
|
||||
if (name.equalsIgnoreCase("delta"))
|
||||
name = "\u03B4";
|
||||
if (name.equalsIgnoreCase("deltab"))
|
||||
name = "\u0394";
|
||||
if ((name.equalsIgnoreCase("epsi")) || (name.equalsIgnoreCase("epsilon")))
|
||||
name = "\u03B5";
|
||||
if (name.equalsIgnoreCase("zeta"))
|
||||
name = "\u03B6";
|
||||
if (name.equalsIgnoreCase("theta"))
|
||||
name = "\u03D1";
|
||||
if (name.equalsIgnoreCase("thetab"))
|
||||
name = "\u0398";
|
||||
if (name.equalsIgnoreCase("iota"))
|
||||
name = "\u03B9";
|
||||
if (name.equalsIgnoreCase("kappa"))
|
||||
name = "\u03BA";
|
||||
if (name.equalsIgnoreCase("lambda"))
|
||||
name = "\u03BB";
|
||||
if (name.equalsIgnoreCase("lambdab"))
|
||||
name = "\u039B";
|
||||
if (name.equalsIgnoreCase("rho"))
|
||||
name = "\u03C1";
|
||||
if (name.equalsIgnoreCase("sigma"))
|
||||
name = "\u03C3";
|
||||
if (name.equalsIgnoreCase("sigmab"))
|
||||
name = "\u03A3";
|
||||
if (name.equalsIgnoreCase("tau"))
|
||||
name = "\u03C4";
|
||||
if (name.equalsIgnoreCase("upsilon"))
|
||||
name = "\u03C5";
|
||||
if (name.equalsIgnoreCase("upsilonb"))
|
||||
name = "\u03D2";
|
||||
if (name.equalsIgnoreCase("omega"))
|
||||
name = "\u03C9";
|
||||
if (name.equalsIgnoreCase("omegab"))
|
||||
name = "\u03A9";
|
||||
|
||||
// these are too small
|
||||
if (name.equalsIgnoreCase("eta"))
|
||||
name = "\u03B7";
|
||||
if (name.equalsIgnoreCase("psi"))
|
||||
name = "\u03C8";
|
||||
if (name.equalsIgnoreCase("psib"))
|
||||
name = "\u03A8";
|
||||
if (name.equalsIgnoreCase("phi"))
|
||||
name = "\u03D5";
|
||||
if (name.equalsIgnoreCase("phib"))
|
||||
name = "\u03A6";
|
||||
if (name.equalsIgnoreCase("chi"))
|
||||
name = "\u03C7";
|
||||
if ((name.equalsIgnoreCase("mu")) || (name.equalsIgnoreCase("my")) || (name.equalsIgnoreCase("myu")))
|
||||
name = "\u03BC";
|
||||
if (name.equalsIgnoreCase("nu"))
|
||||
name = "\u03BD";
|
||||
if (name.equalsIgnoreCase("xi"))
|
||||
name = "\u03BE";
|
||||
if (name.equalsIgnoreCase("xib"))
|
||||
name = "\u039E";
|
||||
if (name.equalsIgnoreCase("pi"))
|
||||
name = "\u03C0";
|
||||
if (name.equalsIgnoreCase("pib"))
|
||||
name = "\u03A0";
|
||||
|
||||
name = translateGreek(name);
|
||||
|
||||
m_Labels[i] = new JLabel(name, SwingConstants.RIGHT);
|
||||
m_Labels[i].setBorder(BorderFactory.createEmptyBorder(10,10,0,5));
|
||||
@ -449,7 +385,83 @@ public class PropertySheetPanel extends JPanel implements PropertyChangeListener
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
private String translateGreek(String name) {
|
||||
// Add some specific display for some greeks here
|
||||
if (name.equalsIgnoreCase("alpha"))
|
||||
return "\u03B1";
|
||||
if (name.equalsIgnoreCase("beta"))
|
||||
return "\u03B2";
|
||||
if (name.equalsIgnoreCase("gamma"))
|
||||
return "\u03B3";
|
||||
if (name.equalsIgnoreCase("gammab"))
|
||||
return "\u0393";
|
||||
if (name.equalsIgnoreCase("delta"))
|
||||
return "\u03B4";
|
||||
if (name.equalsIgnoreCase("deltab"))
|
||||
return "\u0394";
|
||||
if ((name.equalsIgnoreCase("epsi")) || (name.equalsIgnoreCase("epsilon")))
|
||||
return "\u03B5";
|
||||
if (name.equalsIgnoreCase("zeta"))
|
||||
return "\u03B6";
|
||||
if (name.equalsIgnoreCase("theta"))
|
||||
return "\u03D1";
|
||||
if (name.equalsIgnoreCase("thetab"))
|
||||
return "\u0398";
|
||||
if (name.equalsIgnoreCase("iota"))
|
||||
return "\u03B9";
|
||||
if (name.equalsIgnoreCase("kappa"))
|
||||
return "\u03BA";
|
||||
if (name.equalsIgnoreCase("lambda"))
|
||||
return "\u03BB";
|
||||
if (name.equalsIgnoreCase("lambdab"))
|
||||
return "\u039B";
|
||||
if (name.equalsIgnoreCase("rho"))
|
||||
return "\u03C1";
|
||||
if (name.equalsIgnoreCase("sigma"))
|
||||
return "\u03C3";
|
||||
if (name.equalsIgnoreCase("sigmab"))
|
||||
return "\u03A3";
|
||||
if (name.equalsIgnoreCase("tau"))
|
||||
return "\u03C4";
|
||||
if (name.equalsIgnoreCase("upsilon"))
|
||||
return "\u03C5";
|
||||
if (name.equalsIgnoreCase("upsilonb"))
|
||||
return "\u03D2";
|
||||
if (name.equalsIgnoreCase("omega"))
|
||||
return "\u03C9";
|
||||
if (name.equalsIgnoreCase("omegab"))
|
||||
return "\u03A9";
|
||||
|
||||
// these are too small
|
||||
if (name.equalsIgnoreCase("eta"))
|
||||
return "\u03B7";
|
||||
if (name.equalsIgnoreCase("psi"))
|
||||
return "\u03C8";
|
||||
if (name.equalsIgnoreCase("psib"))
|
||||
return "\u03A8";
|
||||
if (name.equalsIgnoreCase("phi"))
|
||||
return "\u03D5";
|
||||
if (name.equalsIgnoreCase("phib"))
|
||||
return "\u03A6";
|
||||
if (name.equalsIgnoreCase("chi"))
|
||||
return "\u03C7";
|
||||
if ((name.equalsIgnoreCase("mu")) || (name.equalsIgnoreCase("my")) || (name.equalsIgnoreCase("myu")))
|
||||
return "\u03BC";
|
||||
if (name.equalsIgnoreCase("nu"))
|
||||
return "\u03BD";
|
||||
if (name.equalsIgnoreCase("xi"))
|
||||
return "\u03BE";
|
||||
if (name.equalsIgnoreCase("xib"))
|
||||
return "\u039E";
|
||||
if (name.equalsIgnoreCase("pi"))
|
||||
return "\u03C0";
|
||||
if (name.equalsIgnoreCase("pib"))
|
||||
return "\u03A0";
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the html help file name.
|
||||
*
|
||||
* @return
|
||||
@ -496,6 +508,109 @@ public class PropertySheetPanel extends JPanel implements PropertyChangeListener
|
||||
public int editableProperties() {
|
||||
return m_NumEditable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the modification was successful.
|
||||
*
|
||||
* @param i
|
||||
* @param newValue
|
||||
* @return
|
||||
*/
|
||||
synchronized boolean updateValue(int i, Object newValue) {
|
||||
PropertyDescriptor property = m_Properties[i];
|
||||
Method getter = m_Properties[i].getReadMethod();
|
||||
m_Values[i] = newValue;
|
||||
Method setter = property.getWriteMethod();
|
||||
// @todo: Streiche so something was changed, i could check if i have to change the editor
|
||||
|
||||
if (TRACE) System.out.println("Updating prop index " + i + " with " + newValue);
|
||||
PropertyEditor tmpEdit = null;
|
||||
// the findEditor method using properties may retrieve a primitive editor, the other one, for obscure reasons, cant.
|
||||
// so Ill use the mightier first.
|
||||
tmpEdit = PropertyEditorProvider.findEditor(m_Properties[i], newValue);
|
||||
if (tmpEdit == null) tmpEdit = PropertyEditorProvider.findEditor(m_Properties[i].getPropertyType());
|
||||
if (tmpEdit.getClass() != m_Editors[i].getClass()) {
|
||||
m_Values[i] = newValue;
|
||||
m_Editors[i] = tmpEdit;
|
||||
if (tmpEdit instanceof GenericObjectEditor) ((GenericObjectEditor) tmpEdit).setClassType(m_Properties[i].getPropertyType());
|
||||
m_Editors[i].setValue(newValue);
|
||||
JComponent NewView = null;
|
||||
if (tmpEdit instanceof sun.beans.editors.BoolEditor) {
|
||||
NewView = new PropertyBoolSelector(tmpEdit);
|
||||
} else {
|
||||
if (tmpEdit instanceof sun.beans.editors.DoubleEditor) {
|
||||
NewView = new PropertyText(tmpEdit);
|
||||
} else {
|
||||
if (tmpEdit.isPaintable() && tmpEdit.supportsCustomEditor()) {
|
||||
NewView = new PropertyPanel(tmpEdit);
|
||||
} else {
|
||||
if (tmpEdit.getTags() != null ) {
|
||||
NewView = new PropertyValueSelector(tmpEdit);
|
||||
} else {
|
||||
if (tmpEdit.getAsText() != null) {
|
||||
NewView = new PropertyText(tmpEdit);
|
||||
} else {
|
||||
System.out.println("Warning: Property \"" + m_Properties[i].getDisplayName()
|
||||
+ "\" has non-displayabale editor. Skipping.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_Editors[i].addPropertyChangeListener(this);
|
||||
m_Views[i] = NewView;
|
||||
if (m_TipTexts[i] != null) m_Views[i].setToolTipText(m_TipTexts[i]);
|
||||
m_ViewWrapper[i].removeAll();
|
||||
m_ViewWrapper[i].setLayout(new BorderLayout());
|
||||
m_ViewWrapper[i].add(m_Views[i], BorderLayout.CENTER);
|
||||
m_ViewWrapper[i].repaint();
|
||||
}
|
||||
|
||||
// System.out.println("Value: "+value +" / m_Values[i]: " + m_Values[i]);
|
||||
// Now try to update the target with the new value of the property
|
||||
// and allow the target to do some changes to the value, therefore
|
||||
// reread the new value from the target
|
||||
try {
|
||||
Object args[] = { newValue };
|
||||
args[0] = newValue;
|
||||
Object args2[] = { };
|
||||
// setting the current value to the target object
|
||||
setter.invoke(m_Target, args);
|
||||
// i could also get the new value
|
||||
//value = getter.invoke(m_Target, args2);
|
||||
// Now i'm reading the set value from the target to my local values
|
||||
m_Values[i] = getter.invoke(m_Target, args2);
|
||||
|
||||
if (newValue instanceof Integer) {
|
||||
// This could check whether i have to set the value back to
|
||||
// the editor, this would allow to check myu and lambda
|
||||
// why shouldn't i do this for every property!?
|
||||
// System.out.println("value: "+((Integer)value).intValue());
|
||||
// System.out.println(" m_Values[i]: "+ ((Integer) m_Values[i]).intValue());
|
||||
if (((Integer)newValue).intValue() != ((Integer) m_Values[i]).intValue()) {
|
||||
m_Editors[i].setValue(m_Values[i]);
|
||||
}
|
||||
}
|
||||
} catch (InvocationTargetException ex) {
|
||||
if (ex.getTargetException() instanceof PropertyVetoException) {
|
||||
System.out.println("PropertySheetPanel.wasModified(): WARNING: Vetoed; reason is: " + ex.getTargetException().getMessage());
|
||||
} else {
|
||||
System.out.println("PropertySheetPanel.wasModified(): InvocationTargetException while updating " + property.getName());
|
||||
System.out.println("PropertySheetPanel.wasModified(): "+ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.out.println("PropertySheetPanel.wasModified(): Unexpected exception while updating " + property.getName());
|
||||
}
|
||||
//revalidate();
|
||||
if (m_Views[i] != null && m_Views[i] instanceof PropertyPanel) {
|
||||
//System.err.println("Trying to repaint the property canvas");
|
||||
m_Views[i].repaint();
|
||||
revalidate();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Updates the propertysheet when a value has been changed (from outside
|
||||
* the propertysheet?).
|
||||
@ -503,171 +618,48 @@ public class PropertySheetPanel extends JPanel implements PropertyChangeListener
|
||||
*/
|
||||
synchronized void wasModified(PropertyChangeEvent evt) {
|
||||
if (TRACE) {
|
||||
System.out.println("PropertySheetPanel.wasModified(): My Target is "+this.m_Target.getClass());
|
||||
System.out.println("*********** PropertySheetPanel.wasModified(): My Target is "+this.m_Target.getClass());
|
||||
System.out.println("PropertySheetPanel.wasModified(): "+evt.toString()+" - "+evt.getNewValue());
|
||||
}
|
||||
int propIndex=-1;
|
||||
if (evt.getSource() instanceof PropertyEditor) {
|
||||
PropertyEditor editor = (PropertyEditor) evt.getSource();
|
||||
for (int i = 0 ; i < m_Editors.length; i++) {
|
||||
if (m_Editors[i] == editor) {
|
||||
PropertyDescriptor property = m_Properties[i];
|
||||
Method getter = m_Properties[i].getReadMethod();
|
||||
Object value = editor.getValue();
|
||||
m_Values[i] = value;
|
||||
Method setter = property.getWriteMethod();
|
||||
// @todo: Streiche so something was changed, i could check if i have to change the editor
|
||||
|
||||
PropertyEditor tmpEdit = null;
|
||||
Object newValue = evt.getNewValue();
|
||||
if (newValue == null) newValue = editor.getValue();
|
||||
// the findEditor method using properties may retrieve a primitive editor, the other one, for obscure reasons, cant.
|
||||
// so Ill use the mightier first.
|
||||
tmpEdit = PropertyEditorProvider.findEditor(m_Properties[i], newValue);
|
||||
if (tmpEdit == null) tmpEdit = PropertyEditorProvider.findEditor(m_Properties[i].getPropertyType());
|
||||
if (tmpEdit.getClass() != m_Editors[i].getClass()) {
|
||||
value = newValue;
|
||||
m_Values[i] = newValue;
|
||||
m_Editors[i] = tmpEdit;
|
||||
if (tmpEdit instanceof GenericObjectEditor) ((GenericObjectEditor) tmpEdit).setClassType(m_Properties[i].getPropertyType());
|
||||
m_Editors[i].setValue(newValue);
|
||||
JComponent NewView = null;
|
||||
if (tmpEdit instanceof sun.beans.editors.BoolEditor) {
|
||||
NewView = new PropertyBoolSelector(tmpEdit);
|
||||
} else {
|
||||
if (tmpEdit instanceof sun.beans.editors.DoubleEditor) {
|
||||
NewView = new PropertyText(tmpEdit);
|
||||
} else {
|
||||
if (tmpEdit.isPaintable() && tmpEdit.supportsCustomEditor()) {
|
||||
NewView = new PropertyPanel(tmpEdit);
|
||||
} else {
|
||||
if (tmpEdit.getTags() != null ) {
|
||||
NewView = new PropertyValueSelector(tmpEdit);
|
||||
} else {
|
||||
if (tmpEdit.getAsText() != null) {
|
||||
NewView = new PropertyText(tmpEdit);
|
||||
} else {
|
||||
System.out.println("Warning: Property \"" + m_Properties[i].getDisplayName()
|
||||
+ "\" has non-displayabale editor. Skipping.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_Editors[i].addPropertyChangeListener(this);
|
||||
m_Views[i] = NewView;
|
||||
if (m_TipTexts[i] != null) m_Views[i].setToolTipText(m_TipTexts[i]);
|
||||
m_ViewWrapper[i].removeAll();
|
||||
m_ViewWrapper[i].setLayout(new BorderLayout());
|
||||
m_ViewWrapper[i].add(m_Views[i], BorderLayout.CENTER);
|
||||
m_ViewWrapper[i].repaint();
|
||||
}
|
||||
|
||||
// System.out.println("Value: "+value +" / m_Values[i]: " + m_Values[i]);
|
||||
// Now try to update the target with the new value of the property
|
||||
// and allow the target to do some changes to the value, therefore
|
||||
// reread the new value from the target
|
||||
try {
|
||||
Object args[] = { value };
|
||||
args[0] = value;
|
||||
Object args2[] = { };
|
||||
// setting the current value to the target object
|
||||
setter.invoke(m_Target, args);
|
||||
// i could also get the new value
|
||||
//value = getter.invoke(m_Target, args2);
|
||||
// Now i'm reading the set value from the target to my local values
|
||||
m_Values[i] = getter.invoke(m_Target, args2);
|
||||
|
||||
if (value instanceof Integer) {
|
||||
// This could check whether i have to set the value back to
|
||||
// the editor, this would allow to check myu and lambda
|
||||
// why shouldn't i do this for every property!?
|
||||
// System.out.println("value: "+((Integer)value).intValue());
|
||||
// System.out.println(" m_Values[i]: "+ ((Integer) m_Values[i]).intValue());
|
||||
if (((Integer)value).intValue() != ((Integer) m_Values[i]).intValue()) {
|
||||
editor.setValue(m_Values[i]);
|
||||
}
|
||||
}
|
||||
} catch (InvocationTargetException ex) {
|
||||
if (ex.getTargetException() instanceof PropertyVetoException) {
|
||||
System.out.println("PropertySheetPanel.wasModified(): WARNING: Vetoed; reason is: " + ex.getTargetException().getMessage());
|
||||
} else {
|
||||
System.out.println("PropertySheetPanel.wasModified(): InvocationTargetException while updating " + property.getName());
|
||||
System.out.println("PropertySheetPanel.wasModified(): "+ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.out.println("PropertySheetPanel.wasModified(): Unexpected exception while updating " + property.getName());
|
||||
}
|
||||
//revalidate();
|
||||
if (m_Views[i] != null && m_Views[i] instanceof PropertyPanel) {
|
||||
//System.err.println("Trying to repaint the property canvas");
|
||||
m_Views[i].repaint();
|
||||
revalidate();
|
||||
}
|
||||
break;
|
||||
} // end if (m_Editors[i] == editor)
|
||||
} // end for (int i = 0 ; i < m_Editors.length; i++) {
|
||||
boolean doRepaint = false;
|
||||
for (int i = 0 ; i < m_Editors.length; i++) { // check the views for out-of-date information. this is different than checking the editors
|
||||
if (m_Editors[i] != editor) {
|
||||
// looking at another field (not changed explicitly, maybe implicitely
|
||||
boolean valChanged = false;
|
||||
Object args[] = { };
|
||||
Method getter = m_Properties[i].getReadMethod();
|
||||
if (m_Properties[i].isHidden() || m_Properties[i].isExpert()) {
|
||||
if ((m_Labels[i] != null) && (m_Labels[i].isVisible())) {
|
||||
// something is set to hidden but was visible up to now
|
||||
m_ViewWrapper[i].setVisible(false);
|
||||
m_Labels[i].setVisible(false);
|
||||
doRepaint = true;
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
if ((m_Labels[i] != null) && !(m_Labels[i].isVisible())) {
|
||||
// something is invisible but set to not hidden in the mean time
|
||||
m_ViewWrapper[i].setVisible(true);
|
||||
m_Labels[i].setVisible(true);
|
||||
doRepaint = true;
|
||||
}
|
||||
}
|
||||
try { // check if view i is up to date and in sync with the value of the getter
|
||||
if (m_Views[i] != null) {
|
||||
Object val = getter.invoke(m_Target, args);
|
||||
if (m_Views[i] instanceof PropertyBoolSelector) {
|
||||
valChanged = (((PropertyBoolSelector)m_Views[i]).isSelected() != ((Boolean)val));
|
||||
if (valChanged) ((PropertyBoolSelector)m_Views[i]).setSelected(((Boolean)val));
|
||||
} else if (m_Views[i] instanceof PropertyText) {
|
||||
valChanged = !(((PropertyText)m_Views[i]).getText()).equals(val.toString());
|
||||
if (valChanged) ((PropertyText)m_Views[i]).setText(val.toString());
|
||||
} else if (m_Views[i] instanceof PropertyPanel) {
|
||||
valChanged = false;//!((PropertyPanel)m_Views[i]).equals(value);
|
||||
// disregard whole panels and hope for the best
|
||||
if (TRACE) System.out.println("not checking for internal change of PropertyPanel");
|
||||
} else if (m_Views[i] instanceof PropertyValueSelector) {
|
||||
//changed = !((SelectedTag)val).isSelectedString((String)((PropertyValueSelector)m_Views[i]).getSelectedItem());
|
||||
// interestingly there seems to be an implicit update of the ValueSelector, possible changes
|
||||
// are already applied, all we need to see it is a repaint
|
||||
m_Views[i].repaint();
|
||||
} else {
|
||||
System.out.println("Warning: Property \"" + i
|
||||
+ "\" not recognized. Skipping.");
|
||||
}
|
||||
}
|
||||
} catch(Exception exc) {
|
||||
System.err.println("Exception in PropertySheetPanel");
|
||||
}
|
||||
}// end if (m_Editors[i] == editor) {
|
||||
} // end for (int i = 0 ; i < m_Editors.length; i++) {
|
||||
if (doRepaint) { // some components have been hidden or reappeared
|
||||
// MK this finally seems to work right
|
||||
Container p=this;
|
||||
while (p != null) {
|
||||
p.setSize(p.getPreferredSize());
|
||||
p = p.getParent();
|
||||
}
|
||||
propIndex = i;
|
||||
if (wasModified(i, editor.getValue(), true)) break;
|
||||
}
|
||||
}
|
||||
} // end if (evt.getSource() instanceof PropertyEditor) {
|
||||
if (propIndex == -1) System.err.println("error: could not identify event editor! (PropertySheetPanel)");
|
||||
} else System.err.println("unknown event source! (PropertySheetPanel)");
|
||||
}
|
||||
|
||||
/** Updates the propertysheet when a value has been changed (from outside
|
||||
* the propertysheet?).
|
||||
* @param evt a value of type 'PropertyChangeEvent'
|
||||
*/
|
||||
synchronized boolean wasModified(int propIndex, Object value, boolean followDependencies) {
|
||||
if (TRACE) {
|
||||
System.out.println("****PropertySheetPanel.wasModified(): My Target is "+ m_Properties[propIndex].getName() + ", new val: " + BeanInspector.toString(value));
|
||||
}
|
||||
|
||||
if (!updateValue(propIndex, value)) return false;
|
||||
|
||||
boolean doRepaint = false;
|
||||
|
||||
for (int i = 0 ; i < m_Editors.length; i++) { // check the views for out-of-date information. this is different than checking the editors
|
||||
if (i != propIndex) {
|
||||
if (updateFieldView(i)) doRepaint = true;
|
||||
}// end if (m_Editors[i] == editor) {
|
||||
} // end for (int i = 0 ; i < m_Editors.length; i++) {
|
||||
if (doRepaint) { // some components have been hidden or reappeared
|
||||
// MK this finally seems to work right
|
||||
Container p=this;
|
||||
while (p != null) {
|
||||
p.setSize(p.getPreferredSize());
|
||||
p = p.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
// Now re-read all the properties and update the editors
|
||||
// for any other properties that have changed.
|
||||
@ -682,7 +674,8 @@ public class PropertySheetPanel extends JPanel implements PropertyChangeListener
|
||||
} catch (Exception ex) {
|
||||
o = null;
|
||||
}
|
||||
if (o == m_Values[i]) {
|
||||
if (TRACE) System.out.println("# cmp " + BeanInspector.toString(o) + "\n# vs. " + BeanInspector.toString(m_Values[i]));
|
||||
if (o == m_Values[i] && (BeanInspector.isJavaPrimitive(o.getClass()))) {
|
||||
// The property is equal to its old value.
|
||||
continue;
|
||||
}
|
||||
@ -705,14 +698,133 @@ public class PropertySheetPanel extends JPanel implements PropertyChangeListener
|
||||
}
|
||||
}
|
||||
|
||||
if (followDependencies) {
|
||||
// Handle the special method getGOEPropertyUpdateLinks which returns a list of pairs
|
||||
// of strings indicating that on an update if the i-th property, the i+1-th property
|
||||
// should be updated. This is useful for changes within sub-classes of the target
|
||||
// which are not directly displayed in this panel but in sub-panels (and there have an own view etc.)
|
||||
Object o = BeanInspector.callIfAvailable(m_Target, "getGOEPropertyUpdateLinks", null);
|
||||
if ((o != null) && (o instanceof String[])) {
|
||||
maybeTriggerUpdates(propIndex, (String[])o);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the target bean gets repainted.
|
||||
if (Beans.isInstanceOf(m_Target, Component.class)) {
|
||||
//System.out.println("Beans.getInstanceOf repaint ");
|
||||
((Component)(Beans.getInstanceOf(m_Target, Component.class))).repaint();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** This method simply looks for an appropriate tiptext
|
||||
/**
|
||||
* Check a property for consistency with the object data and update the
|
||||
* view if necessary. Return true if a repaint is necessary.
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
private boolean updateFieldView(int i) {
|
||||
// looking at another field (not changed explicitly, maybe implicitely
|
||||
boolean valChanged = false;
|
||||
boolean doRepaint = false;
|
||||
Object args[] = { };
|
||||
Method getter = m_Properties[i].getReadMethod();
|
||||
if (m_Properties[i].isHidden() || m_Properties[i].isExpert()) {
|
||||
if ((m_Labels[i] != null) && (m_Labels[i].isVisible())) {
|
||||
// something is set to hidden but was visible up to now
|
||||
m_ViewWrapper[i].setVisible(false);
|
||||
m_Labels[i].setVisible(false);
|
||||
doRepaint = true;
|
||||
}
|
||||
return doRepaint;
|
||||
} else {
|
||||
if ((m_Labels[i] != null) && !(m_Labels[i].isVisible())) {
|
||||
// something is invisible but set to not hidden in the mean time
|
||||
m_ViewWrapper[i].setVisible(true);
|
||||
m_Labels[i].setVisible(true);
|
||||
doRepaint = true;
|
||||
}
|
||||
}
|
||||
try { // check if view i is up to date and in sync with the value of the getter
|
||||
if (m_Views[i] != null) {
|
||||
Object val = getter.invoke(m_Target, args);
|
||||
if (m_Views[i] instanceof PropertyBoolSelector) {
|
||||
valChanged = (((PropertyBoolSelector)m_Views[i]).isSelected() != ((Boolean)val));
|
||||
if (valChanged) ((PropertyBoolSelector)m_Views[i]).setSelected(((Boolean)val));
|
||||
} else if (m_Views[i] instanceof PropertyText) {
|
||||
valChanged = !(((PropertyText)m_Views[i]).getText()).equals(val.toString());
|
||||
if (valChanged) ((PropertyText)m_Views[i]).setText(val.toString());
|
||||
} else if (m_Views[i] instanceof PropertyPanel) {
|
||||
valChanged = false;//!((PropertyPanel)m_Views[i]).equals(value);
|
||||
// disregard whole panels and hope for the best
|
||||
if (TRACE) {
|
||||
System.out.println("not checking for internal change of PropertyPanel " + !((PropertyPanel)m_Views[i]).equals(val));
|
||||
if (!((PropertyPanel)m_Views[i]).equals(val)) {
|
||||
System.out.println("# " + BeanInspector.toString(m_Views[i]));
|
||||
System.out.println("# " + BeanInspector.toString(val));
|
||||
System.out.println("Ed.: " + BeanInspector.toString(((PropertyPanel)m_Views[i]).getEditor()));
|
||||
}
|
||||
}
|
||||
} else if (m_Views[i] instanceof PropertyValueSelector) {
|
||||
//changed = !((SelectedTag)val).isSelectedString((String)((PropertyValueSelector)m_Views[i]).getSelectedItem());
|
||||
// interestingly there seems to be an implicit update of the ValueSelector, possible changes
|
||||
// are already applied, all we need to see it is a repaint
|
||||
m_Views[i].repaint();
|
||||
} else {
|
||||
System.out.println("Warning: Property \"" + i
|
||||
+ "\" not recognized. Skipping.");
|
||||
}
|
||||
}
|
||||
} catch(Exception exc) {
|
||||
System.err.println("Exception in PropertySheetPanel");
|
||||
}
|
||||
return doRepaint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the given link list and trigger updates of indicated properties.
|
||||
*
|
||||
* @param propIndex
|
||||
* @param links
|
||||
*/
|
||||
private void maybeTriggerUpdates(int propIndex, String[] links) {
|
||||
int max = links.length;
|
||||
if (max % 2 == 1) {
|
||||
System.err.println("Error in PropertySheetPanel:maybeTriggerUpdates: odd number of strings provided!");
|
||||
max -= 1;
|
||||
}
|
||||
if (TRACE) System.out.println("maybeTriggerUpdates: " + BeanInspector.toString(links));
|
||||
for (int i = 0; i<max; i+=2) {
|
||||
if (links[i].equals(m_Properties[propIndex].getName())) {
|
||||
if (TRACE) System.out.println("updating linked property " + links[i+1]);
|
||||
updateLinkedProperty(links[i+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLinkedProperty(String propName) {
|
||||
for (int i=0; i<m_Properties.length; i++) {
|
||||
if (m_Properties[i].getName().equals(propName)) {
|
||||
if (TRACE) System.out.println("Found linked property " + propName);
|
||||
Method getter = m_Properties[i].getReadMethod();
|
||||
Object val = null;
|
||||
try {
|
||||
val = getter.invoke(m_Target, (Object[])null);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
val = null;
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (val != null) {
|
||||
m_Editors[i].setValue(val);
|
||||
// wasModified(i, val, false);
|
||||
} else System.err.println("Error in PropertySheetPanel:updateLinkedProperty");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** This method simply looks for an appropriate tiptext
|
||||
* @param name The name of the property
|
||||
* @param methods A list of methods to search.
|
||||
* @param target The target object
|
||||
|
@ -62,7 +62,7 @@ public class PropertyText extends JTextField {
|
||||
protected void updateEditor() {
|
||||
try {
|
||||
String x = getText();
|
||||
m_Editor.setAsText(x);
|
||||
if (!m_Editor.getAsText().equals(x)) m_Editor.setAsText(x);
|
||||
} catch (IllegalArgumentException ex) {}
|
||||
}
|
||||
}
|
||||
|
@ -920,7 +920,9 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
||||
* @return double valued position of an individual or null
|
||||
*/
|
||||
public static double[] getDoublePosition(AbstractEAIndividual indy) {
|
||||
if (indy instanceof InterfaceDataTypeDouble) {
|
||||
if (indy instanceof InterfaceESIndividual) {
|
||||
return ((InterfaceESIndividual)indy).getDGenotype();
|
||||
} else if (indy instanceof InterfaceDataTypeDouble) {
|
||||
return ((InterfaceDataTypeDouble)indy).getDoubleData();
|
||||
} else if (indy instanceof InterfaceDataTypeInteger) {
|
||||
int[] intData = ((InterfaceDataTypeInteger)indy).getIntegerData();
|
||||
|
@ -166,8 +166,8 @@ public class GAIndividualBinaryData extends AbstractEAIndividual implements Inte
|
||||
}
|
||||
|
||||
/** This method allows the user to read the length of the genotype.
|
||||
* This may be necessary since BitSet.lenght only returns the index
|
||||
* of the last significat bit.
|
||||
* This may be necessary since BitSet.length only returns the index
|
||||
* of the last significant bit.
|
||||
* @return The length of the genotype.
|
||||
*/
|
||||
public int getGenotypeLength() {
|
||||
|
@ -110,13 +110,14 @@ public class PhenotypeMetric implements InterfaceDistanceMetric, java.io.Seriali
|
||||
if ((indy1 instanceof InterfaceDataTypeDouble) && (indy2 instanceof InterfaceDataTypeDouble)) {
|
||||
double[] d1, d2;
|
||||
double[][] r1, r2;
|
||||
double tmpResult = 0;
|
||||
double tmpResult = 0, tmp=0;
|
||||
d1 = ((InterfaceDataTypeDouble) indy1).getDoubleData();
|
||||
r1 = ((InterfaceDataTypeDouble) indy1).getDoubleRange();
|
||||
d2 = ((InterfaceDataTypeDouble) indy2).getDoubleData();
|
||||
r2 = ((InterfaceDataTypeDouble) indy2).getDoubleRange();
|
||||
for (int i = 0; (i < d1.length) && (i < d2.length); i++) {
|
||||
tmpResult += Math.pow(((d1[i] - r1[i][0])/(r1[i][1] - r1[i][0])) - ((d2[i] - r2[i][0])/(r2[i][1] - r2[i][0])), 2);
|
||||
tmp=((d1[i] - r1[i][0])/(r1[i][1] - r1[i][0])) - ((d2[i] - r2[i][0])/(r2[i][1] - r2[i][0]));
|
||||
tmpResult += (tmp*tmp);
|
||||
}
|
||||
result += Math.sqrt(tmpResult);
|
||||
}
|
||||
@ -158,13 +159,33 @@ public class PhenotypeMetric implements InterfaceDistanceMetric, java.io.Seriali
|
||||
}
|
||||
|
||||
public static double euclidianDistance(double[] v1, double[] v2) {
|
||||
double result = 0;
|
||||
double result = 0, tmp=0;
|
||||
for (int i = 0; (i < v1.length) && (i < v2.length); i++) {
|
||||
result += Math.pow(v1[i] - v2[i], 2);
|
||||
tmp = v1[i] - v2[i];
|
||||
result += (tmp*tmp);
|
||||
}
|
||||
return Math.sqrt(result);
|
||||
}
|
||||
|
||||
public static double squaredEuclidianDistance(double[] v1, double[] v2) {
|
||||
double tmp, result = 0;
|
||||
for (int i = 0; (i < v1.length) && (i < v2.length); i++) {
|
||||
tmp=v1[i] - v2[i];
|
||||
result += (tmp*tmp);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static double normedDistance(double[] pos1, double[][] range1, double[] pos2, double[][] range2) {
|
||||
double tmpResult = 0, tmp=0;
|
||||
|
||||
for (int i = 0; (i < pos1.length) && (i < pos2.length); i++) {
|
||||
tmp=((pos1[i] - range1[i][0])/(range1[i][1] - range1[i][0])) - ((pos2[i] - range2[i][0])/(range2[i][1] - range2[i][0]));
|
||||
tmpResult += (tmp*tmp);
|
||||
}
|
||||
return Math.sqrt(tmpResult);
|
||||
}
|
||||
|
||||
public static double norm(AbstractEAIndividual indy) {
|
||||
double result = 0;
|
||||
if (indy instanceof InterfaceDataTypeBinary) {
|
||||
|
@ -99,7 +99,7 @@ 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 = getAvgRange(params.range);
|
||||
if (initialSigma<0) initialSigma = Mathematics.getAvgRange(params.range);
|
||||
if (initialSigma <= 0) {
|
||||
EVAERROR.errorMsgOnce("warning: initial sigma <= zero! Working with converged population?");
|
||||
initialSigma = 10e-10;
|
||||
@ -160,18 +160,6 @@ class CMAParamSet implements InterfacePopulationChangedEventListener, Serializab
|
||||
// default parameter value ( HK03, sec. 2)
|
||||
return getMuEff(weights, mu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the average length of the range intervals over all dimensions.
|
||||
*
|
||||
* @param range
|
||||
* @return
|
||||
*/
|
||||
public static double getAvgRange(double[][] range) {
|
||||
double sum = 0.;
|
||||
for (int i=0; i<range.length; i++) sum+=(range[i][1]-range[i][0]);
|
||||
return sum/range.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that the parameter sets of each population are updated (reinitialized)
|
||||
@ -255,7 +243,7 @@ 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(null)[0];
|
||||
return initGen.getPopulationMeasures()[0];
|
||||
//case halfRange: return getAvgRange(range)/2.;
|
||||
case userDefined: return userDefInitSig ;
|
||||
default: return -1.;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package eva2.server.go.operators.postprocess;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import eva2.OptimizerFactory;
|
||||
@ -8,6 +9,7 @@ import eva2.OptimizerRunnable;
|
||||
import eva2.gui.BeanInspector;
|
||||
import eva2.gui.Plot;
|
||||
import eva2.gui.TopoPlot;
|
||||
import eva2.server.go.IndividualInterface;
|
||||
import eva2.server.go.InterfaceTerminator;
|
||||
import eva2.server.go.enums.ESMutationInitialSigma;
|
||||
import eva2.server.go.enums.PostProcessMethod;
|
||||
@ -66,6 +68,7 @@ public class PostProcess {
|
||||
public static final int KEEP_LONERS = 11;
|
||||
public static final int DISCARD_LONERS = 12;
|
||||
public static final int LONERS_AS_CLUSTERS = 13;
|
||||
|
||||
/**
|
||||
* 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. For each optimum, there is
|
||||
@ -137,7 +140,7 @@ public class PostProcess {
|
||||
/**
|
||||
* Calls clusterBest with a ClusteringDensitiyBased clustering object with the given sigma and a
|
||||
* minimum group size of 2.
|
||||
* @see clusterBest(Population pop, InterfaceClustering clustering, double returnQuota, int lonerMode, int takeOverMode)
|
||||
* @see #clusterBest(Population pop, InterfaceClustering clustering, double returnQuota, int lonerMode, int takeOverMode)
|
||||
* @param pop
|
||||
* @param sigmaCluster
|
||||
* @param returnQuota
|
||||
@ -398,19 +401,24 @@ public class PostProcess {
|
||||
* 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
|
||||
* meaning that typically only one best is returned.
|
||||
* Returns the number of function calls really performed by the method; sets the number of function calls
|
||||
* in the population back to the original count.
|
||||
* If the baseEvals parameter (which should be >= 0) is > 0, then the number of evaluations is set as
|
||||
* number of evaluations before the optimization using the given terminator.
|
||||
*
|
||||
* @param pop
|
||||
* @param problem
|
||||
* @param term
|
||||
* @param baseEvals
|
||||
* @return
|
||||
*/
|
||||
public static int processWithNMS(Population pop, AbstractOptimizationProblem problem, InterfaceTerminator term) {
|
||||
public static int processWithNMS(Population pop, AbstractOptimizationProblem problem, InterfaceTerminator term, int baseEvals) {
|
||||
NelderMeadSimplex nms = new NelderMeadSimplex();
|
||||
nms.setProblemAndPopSize(problem);
|
||||
nms.setGenerationCycle(5);
|
||||
nms.initByPopulation(pop, false);
|
||||
int funCallsBefore = pop.getFunctionCalls();
|
||||
pop.SetFunctionCalls(0);
|
||||
pop.SetFunctionCalls(baseEvals);
|
||||
|
||||
ppRunnable = new OptimizerRunnable(OptimizerFactory.makeParams(nms, pop, problem, 0, term), true);
|
||||
// as nms creates a new population and has already evaluated them, send a signal to stats
|
||||
@ -418,8 +426,8 @@ public class PostProcess {
|
||||
|
||||
runPP();
|
||||
|
||||
int funCallsDone = pop.getFunctionCalls();
|
||||
pop.SetFunctionCalls(funCallsBefore+funCallsDone);
|
||||
int funCallsDone = pop.getFunctionCalls()-baseEvals;
|
||||
pop.SetFunctionCalls(funCallsBefore);
|
||||
|
||||
return funCallsDone;
|
||||
}
|
||||
@ -428,13 +436,18 @@ public class PostProcess {
|
||||
* 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
|
||||
* meaning that typically only one best is returned.
|
||||
* Returns the number of function calls really performed by the method; sets the number of function calls
|
||||
* in the population back to the original count. If the baseEvals parameter (which should be >= 0) is > 0,
|
||||
* then the number of evaluations is set as
|
||||
* number of evaluations before the optimization using the given terminator.
|
||||
*
|
||||
* @param pop
|
||||
* @param problem
|
||||
* @param term
|
||||
* @param baseEvals
|
||||
* @return
|
||||
*/
|
||||
public static int processWithCMA(Population pop, AbstractOptimizationProblem problem, InterfaceTerminator term) {
|
||||
public static int processWithCMA(Population pop, AbstractOptimizationProblem problem, InterfaceTerminator term, int baseEvals) {
|
||||
// GOParameters cmaParams = OptimizerFactory.cmaESIPOP(problem);
|
||||
MutateESRankMuCMA mutator = new MutateESRankMuCMA();
|
||||
mutator.setInitializeSigma(ESMutationInitialSigma.avgInitialDistance);
|
||||
@ -449,7 +462,7 @@ public class PostProcess {
|
||||
GOParameters cmaParams = OptimizerFactory.makeParams(es, pop, problem, 0, term);
|
||||
|
||||
int funCallsBefore = pop.getFunctionCalls();
|
||||
pop.SetFunctionCalls(0);
|
||||
pop.SetFunctionCalls(baseEvals);
|
||||
|
||||
ppRunnable = new OptimizerRunnable(cmaParams, true);
|
||||
ppRunnable.getStats().createNextGenerationPerformed(cmaParams.getOptimizer().getPopulation(), null);
|
||||
@ -458,8 +471,8 @@ public class PostProcess {
|
||||
pop.clear();
|
||||
pop.addPopulation(es.getPopulation());
|
||||
|
||||
int funCallsDone = es.getPopulation().getFunctionCalls();
|
||||
pop.SetFunctionCalls(funCallsBefore+funCallsDone);
|
||||
int funCallsDone = es.getPopulation().getFunctionCalls()-baseEvals;
|
||||
pop.SetFunctionCalls(funCallsBefore);
|
||||
|
||||
return funCallsDone;
|
||||
}
|
||||
@ -488,42 +501,26 @@ public class PostProcess {
|
||||
|
||||
Population pop = new Population(1);
|
||||
pop.add(cand);
|
||||
int evalsDone = processSingleCandidates(PostProcessMethod.nelderMead, pop, hcSteps, initPerturbation, prob);
|
||||
int evalsDone = processSingleCandidates(PostProcessMethod.nelderMead, pop, hcSteps, initPerturbation, prob, null);
|
||||
|
||||
return new Pair<AbstractEAIndividual, Integer>(pop.getBestEAIndividual(), evalsDone);
|
||||
|
||||
// Population candidates = NelderMeadSimplex.createNMSPopulation(cand, initPerturbation , range, false);
|
||||
// prob.evaluate(candidates);
|
||||
//// refSet.incrFunctionCallsby(candidates.size());
|
||||
// int evalsDone = candidates.size();
|
||||
// int hcStepsRest = hcSteps - candidates.size();
|
||||
//
|
||||
// candidates.add(cand);
|
||||
// candidates.setPopulationSize(candidates.size());
|
||||
// if (hcStepsRest < 1) {
|
||||
// System.err.println("Error: Less steps than dimensions! " + hcSteps + " vs " + candidates.size());
|
||||
// return new Pair<AbstractEAIndividual, Integer>(candidates.getBestEAIndividual(), evalsDone);
|
||||
// } else {
|
||||
//// candidates.setEvaluated(); // they have all been evaluated at this point and no mod. is due
|
||||
//// if (!candidates.isEvaluated()) {
|
||||
//// System.err.println("this is bad!");
|
||||
//// }
|
||||
// InterfaceTerminator term = new EvaluationTerminator(hcStepsRest);
|
||||
//
|
||||
// evalsDone += PostProcess.processWithNMS(candidates, prob, term);
|
||||
// if (Math.abs(evalsDone-hcSteps)>1) {
|
||||
// System.err.println("Error in localSolverNMS " + evalsDone + " / " + hcSteps);
|
||||
// }
|
||||
// }
|
||||
// return new Pair<AbstractEAIndividual, Integer>(candidates.getBestEAIndividual(), evalsDone);
|
||||
return new Pair<AbstractEAIndividual, Integer>(pop.getBestEAIndividual(), evalsDone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a subpopulation around an indicated individual from the candidate set.
|
||||
* Create a sub-population around an indicated individual from the candidate set.
|
||||
* Depending on the post processing method, this is done slightly differently. For hill-climbing,
|
||||
* an error message is produced.
|
||||
*
|
||||
* @see #createPopInSubRange(double, AbstractOptimizationProblem, AbstractEAIndividual)
|
||||
* @see #NelderMeadSimplex.createNMSPopulation(AbstractEAIndividual, double, double[][], boolean)
|
||||
* @param method
|
||||
* @param problem
|
||||
* @param candidates
|
||||
* @param index index of the individual for which to produce the sub population
|
||||
* @param maxPerturbation
|
||||
* @param includeCand
|
||||
*/
|
||||
private 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 maxPerturbation, boolean includeCand) {
|
||||
Population subPop = null;
|
||||
switch (method) {
|
||||
case cmaES:
|
||||
@ -534,27 +531,78 @@ public class PostProcess {
|
||||
break;
|
||||
case nelderMead:
|
||||
double[][] range = ((InterfaceDataTypeDouble)candidates.getEAIndividual(index)).getDoubleRange();
|
||||
double perturb = findNMSPerturn(candidates, index, maxPerturbation);
|
||||
double perturb = findNMSPerturb(candidates, index, maxPerturbation);
|
||||
if (TRACE) System.out.println("perturb " + index + " is " + perturb);
|
||||
subPop = NelderMeadSimplex.createNMSPopulation(candidates.getEAIndividual(index), perturb, range, false);
|
||||
}
|
||||
// subPop.setSameParams(candidates);
|
||||
return subPop;
|
||||
}
|
||||
|
||||
/**
|
||||
* For each candidate individual, create an own nm-population and optimize it separately.
|
||||
* The allowed steps must be large enough to perform a Nelder-Mead-Simplex step for all individuals, namely
|
||||
* for problem dimension n it should be (n+k)*candPopSize for a positive integer k.
|
||||
* At the moment, the function calls are distributed evenly between all candidate solutions. This could be
|
||||
* improved by checking the convergence state in the future.
|
||||
* Employ hill-climbing directly or NM/CMA on the candidates. The candidate population
|
||||
* must not be empty and candidates must implement InterfaceDataTypeDouble.
|
||||
* The given number of steps gives the number of evaluations which may not be hit exactly.
|
||||
* The population will not be altered for Nelder-Mead or CMA-ES, and the evaluation calls will not be added to
|
||||
* the candidate population!
|
||||
*
|
||||
* @see #processWithHC(Population, AbstractOptimizationProblem, InterfaceTerminator, InterfaceMutation)
|
||||
* @see #processSingleCandidatesNMCMA(PostProcessMethod, Population, InterfaceTerminator, double, AbstractOptimizationProblem)
|
||||
* @param method
|
||||
* @param candidates
|
||||
* @param steps
|
||||
* @param steps number of evaluations to be performed (summed up)
|
||||
* @param maxPerturbation
|
||||
* @param prob
|
||||
* @return
|
||||
* @param mute the mutator to use (in case of HC)
|
||||
* @return the evaluations performed
|
||||
*/
|
||||
public static int processSingleCandidates(PostProcessMethod method, Population candidates, int steps, double maxPerturbation, AbstractOptimizationProblem prob) {
|
||||
public static int processSingleCandidates(PostProcessMethod method, Population candidates, int steps, double maxPerturbation, AbstractOptimizationProblem prob, InterfaceMutation mute) {
|
||||
int dim=((InterfaceDataTypeDouble)candidates.getEAIndividual(0)).getDoubleRange().length;
|
||||
int candCnt = candidates.size();
|
||||
|
||||
if (method == PostProcessMethod.hillClimber) {
|
||||
int evalsOld = candidates.getFunctionCalls();
|
||||
processWithHC(candidates, prob, new EvaluationTerminator(evalsOld+steps), mute);
|
||||
int evalsDone = candidates.getFunctionCalls()-evalsOld;
|
||||
candidates.SetFunctionCalls(evalsOld);
|
||||
return evalsDone;
|
||||
} else {
|
||||
int stepsPerCand = (steps-(candCnt*(dim-1)))/candCnt;
|
||||
if (TRACE) System.out.println("employing " + stepsPerCand + " steps per cand.");
|
||||
if (stepsPerCand < dim) {
|
||||
System.err.println("Too few steps allowed in processSingleCandidates!");
|
||||
System.err.println("Method: " + method + ", cands: " + candidates.size() + ", steps: " + steps);
|
||||
return 0;
|
||||
} else {
|
||||
EvaluationTerminator term = new EvaluationTerminator(stepsPerCand);
|
||||
return processSingleCandidatesNMCMA(method, candidates, term, maxPerturbation, prob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For each candidate individual, create an own sub-population and optimize it separately. Candidates must have
|
||||
* been evaluated earlier. The candidates population is not altered.
|
||||
* The performed evaluation calls for problem dimension n will be (n+k)*candPopSize for a positive integer k.
|
||||
* At the moment, the function calls are distributed evenly between all candidate solutions. This could be
|
||||
* 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".
|
||||
* It indicates the phenotype distance the found solution has moved relatively to the original candidate.
|
||||
*
|
||||
* @see #findNMSPerturb(Population, int, double)
|
||||
* @see #createLSSupPopulation(PostProcessMethod, AbstractOptimizationProblem, Population, int, double, boolean)
|
||||
* @see #processWithCMA(Population, AbstractOptimizationProblem, InterfaceTerminator, int)
|
||||
* @see #processWithNMS(Population, AbstractOptimizationProblem, InterfaceTerminator, int)
|
||||
* @param method NM or CMA is allowed here
|
||||
* @param candidates
|
||||
* @param term
|
||||
* @param maxPerturbation perturbation for the sub population
|
||||
* @param prob
|
||||
* @return the number of evaluations performed
|
||||
*/
|
||||
public static int processSingleCandidatesNMCMA(PostProcessMethod method, Population candidates, InterfaceTerminator term, double maxPerturbation, AbstractOptimizationProblem prob) {
|
||||
ArrayList<Population> nmPops = new ArrayList<Population>();
|
||||
int stepsPerf = 0;
|
||||
Population subPop;
|
||||
@ -568,31 +616,39 @@ public class PostProcess {
|
||||
nmPops.add(subPop);
|
||||
}
|
||||
|
||||
int stepsPerCand = (steps-stepsPerf)/candidates.size();
|
||||
if (TRACE) System.out.println("rest is " + (steps-stepsPerf) + ", thats " + stepsPerCand + " per candidate.");
|
||||
if (stepsPerCand < 1) System.err.println("Too few steps allowed!");
|
||||
else {
|
||||
for (int i=0; i<candidates.size(); i++) { // improve each single sub pop
|
||||
subPop = nmPops.get(i);
|
||||
EvaluationTerminator term = new EvaluationTerminator(stepsPerCand);
|
||||
if (TRACE) System.out.println("*** before " + subPop.getBestEAIndividual().getStringRepresentation());
|
||||
|
||||
switch (method) {
|
||||
case nelderMead: stepsPerf += PostProcess.processWithNMS(subPop, prob, term);
|
||||
break;
|
||||
case cmaES: stepsPerf += PostProcess.processWithCMA(subPop, prob, term);
|
||||
break;
|
||||
}
|
||||
if (checkRange(subPop.getBestEAIndividual())) {
|
||||
// and replace corresponding individual (should usually be better)
|
||||
if (subPop.getBestEAIndividual().isDominant(candidates.getEAIndividual(i))) candidates.set(i, subPop.getBestEAIndividual());
|
||||
} else {
|
||||
// TODO esp. in nelder mead
|
||||
//System.err.println("Warning, individual left the problem range during PP!");
|
||||
}
|
||||
if (term==null) {
|
||||
int stepsPerCand = 10*(nmPops.get(0).size()-1); // == 10*dim for NM
|
||||
if (TRACE) System.out.println("employing " + stepsPerCand + " per candidate.");
|
||||
if (stepsPerCand < 1) {
|
||||
System.err.println("Too few steps allowed!");
|
||||
return 0;
|
||||
}
|
||||
term = new EvaluationTerminator(stepsPerCand);
|
||||
}
|
||||
for (int i=0; i<candidates.size(); i++) { // improve each single sub pop
|
||||
subPop = nmPops.get(i);
|
||||
term.init(prob);
|
||||
// if (TRACE) System.out.println("*** before " + subPop.getBestEAIndividual().getStringRepresentation());
|
||||
|
||||
if (TRACE) System.out.println("refined to " + subPop.getBestEAIndividual().getStringRepresentation());
|
||||
}
|
||||
switch (method) {
|
||||
case nelderMead: stepsPerf += PostProcess.processWithNMS(subPop, prob, term, subPop.size()-1);
|
||||
break;
|
||||
case cmaES: stepsPerf += PostProcess.processWithCMA(subPop, prob, term, subPop.size()-1);
|
||||
break;
|
||||
}
|
||||
if (checkRange(subPop.getBestEAIndividual())) {
|
||||
// and replace corresponding individual (should usually be better)
|
||||
if (subPop.getBestEAIndividual().isDominant(candidates.getEAIndividual(i))) {
|
||||
// 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())));
|
||||
candidates.set(i, subPop.getBestEAIndividual());
|
||||
}
|
||||
} else {
|
||||
// TODO esp. in nelder mead
|
||||
System.err.println("Warning, individual left the problem range during PP!");
|
||||
}
|
||||
|
||||
// if (TRACE) System.out.println("refined to " + subPop.getBestEAIndividual().getStringRepresentation());
|
||||
}
|
||||
|
||||
return stepsPerf;
|
||||
@ -642,7 +698,7 @@ public class PostProcess {
|
||||
double[][] range = getDoubleRange(indy);
|
||||
double[] data = getDoubleData(indy);
|
||||
int lambda= (int) (4.0 + 3.0 * Math.log(range.length));
|
||||
double[][] newRange = new double[2][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.));
|
||||
@ -732,7 +788,7 @@ public class PostProcess {
|
||||
public static void main(String[] args) {
|
||||
AbstractOptimizationProblem problem = new FM0Problem();
|
||||
InterfaceMultimodalProblemKnown mmp = (InterfaceMultimodalProblemKnown)problem;
|
||||
OptimizerRunnable runnable = OptimizerFactory.getOptRunnable(OptimizerFactory.STD_GA, problem, 500, null);
|
||||
OptimizerRunnable runnable = OptimizerFactory.getOptRunnable(OptimizerFactory.STD_GA, problem, 100, null);
|
||||
runnable.run();
|
||||
Population pop = runnable.getGOParams().getOptimizer().getPopulation();
|
||||
// System.out.println("no optima found: " + mmp.getNumberOfFoundOptima(pop));
|
||||
@ -742,12 +798,13 @@ public class PostProcess {
|
||||
Pair<Population, Double> popD = new Pair<Population, Double>(pop, 1.);
|
||||
int i=0;
|
||||
int evalCnt = 0;
|
||||
while (popD.tail() > 0.01) {
|
||||
while (popD.tail() > 0.001) {
|
||||
i++;
|
||||
// public static PopDoublePair clusterHC(pop, problem, sigmaCluster, funCalls, keepClusterRatio, mute) {
|
||||
|
||||
popD = clusterHC(popD.head(), problem, 0.01, 1000 - (evalCnt % 1000), 0.5, new MutateESFixedStepSize(0.02));
|
||||
popD = clusterLocalSearch(PostProcessMethod.hillClimber, popD.head(), problem, 0.01, 1500, 0.1, new MutateESFixedStepSize(0.02));
|
||||
evalCnt += popD.head().getFunctionCalls();
|
||||
System.out.println("popsize is " + popD.head().size());
|
||||
}
|
||||
found = getFoundOptima(popD.head(), mmp.getRealOptima(), 0.05, true);
|
||||
System.out.println("found at " + i + " (" + found.size() + "): " + BeanInspector.toString(found));
|
||||
@ -760,11 +817,12 @@ public class PostProcess {
|
||||
}
|
||||
|
||||
/**
|
||||
* Cluster a population and reduce it by a certain ratio, then optimize the remaining individuals for a given number of function calls with a HC.
|
||||
* Return a pair of the optimized population and the improvement in the mean fitness (not normed) that was achieved by the HC run. The returned
|
||||
* Cluster a population and reduce it by a certain ratio, then optimize the remaining individuals for a given number of function calls with a LS.
|
||||
* Return a pair of the optimized population and the improvement in the mean fitness (not normed) that was achieved by the LS run. The returned
|
||||
* individuals are deep clones, so the given population is not altered. Of a cluster of individuals, the given
|
||||
* ratio of individuals is kept, more precisely, the best one is kept while the remaining are selected randomly. All loners are kept.
|
||||
*
|
||||
* @param method the local search method to be used
|
||||
* @param pop the population to work on
|
||||
* @param problem the target problem instance
|
||||
* @param sigmaCluster minimum clustering distance
|
||||
@ -773,71 +831,33 @@ public class PostProcess {
|
||||
* @param mute the mutation operator to be used by the hill climber
|
||||
* @return a pair of the optimized population and the improvement in the mean fitness (not normed) achieved by the HC run
|
||||
*/
|
||||
public static Pair<Population, Double> clusterHC(Population pop, AbstractOptimizationProblem problem, double sigmaCluster, int funCalls, double keepClusterRatio, InterfaceMutation mute) {
|
||||
public static Pair<Population, Double> clusterLocalSearch(PostProcessMethod method, Population pop, AbstractOptimizationProblem problem, double sigmaCluster, int funCalls, double keepClusterRatio, InterfaceMutation mute) {
|
||||
int evalsBefore = pop.getFunctionCalls();
|
||||
|
||||
Population clust = (Population)clusterBest(pop, new ClusteringDensityBased(sigmaCluster, 2), keepClusterRatio, KEEP_LONERS, BEST_RAND).clone();
|
||||
// System.out.println("keeping " + clust.size() + " for hc....");
|
||||
|
||||
//clust.addPopulationChangedEventListener()
|
||||
double[] meanFit = clust.getMeanFitness();
|
||||
processWithHC(clust, problem, new EvaluationTerminator(pop.getFunctionCalls()+funCalls), mute);
|
||||
|
||||
if (TRACE) System.out.println("BEF: funcalls done: " + pop.getFunctionCalls() + ", now allowed: " + funCalls);
|
||||
|
||||
int evalsDone = processSingleCandidates(method, clust, funCalls, sigmaCluster/2., problem, mute);
|
||||
|
||||
clust.SetFunctionCalls(evalsBefore + evalsDone);
|
||||
|
||||
double improvement = PhenotypeMetric.euclidianDistance(meanFit, clust.getMeanFitness());
|
||||
if (TRACE) System.out.println("improvement by " + improvement);
|
||||
if (TRACE) System.out.println("improvement by " + improvement + " funcalls done: " + evalsDone);
|
||||
return new Pair<Population, Double>(clust, improvement);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Do some post processing on a multimodal problem. If the real optima are known, only the number of
|
||||
// * found optima is printed. Otherwise, the population is clustered and for the population of cluster-representatives,
|
||||
// * some diversity measures and a fitness histogram are printed.
|
||||
// *
|
||||
// * @see Population.getPopulationMeasures()
|
||||
// * @see createFitNormHistogram
|
||||
// * @param mmProb the target problem
|
||||
// * @param pop the solution set
|
||||
// * @param sigmaCluster the min clustering distance
|
||||
// * @param out a PrintStream for data output
|
||||
// * @param minBnd lower fitness bound
|
||||
// * @param maxBnd upper fitness bound
|
||||
// * @param bins number of bins for the fitness histogram
|
||||
// * @return
|
||||
// */
|
||||
// public static Population outputResult(AbstractOptimizationProblem mmProb, Population pop, double sigmaCluster, PrintStream out, double minBnd, double maxBnd, int bins, int hcSteps) {
|
||||
// ClusteringDensityBased clust = new ClusteringDensityBased(sigmaCluster);
|
||||
// clust.setMinimumGroupSize(2);
|
||||
// Population clusteredBest = clusterBest(pop, clust, 0, KEEP_LONERS, BEST_ONLY);
|
||||
// if (hcSteps > 0) { // HC post process
|
||||
// Population tmpPop = (Population)clusteredBest.clone();
|
||||
// processWithHC(tmpPop, (AbstractOptimizationProblem)mmProb, hcSteps, 0.001);
|
||||
// clusteredBest = clusterBest(tmpPop, clust, 0, KEEP_LONERS, BEST_ONLY);
|
||||
// }
|
||||
// double[] meas = clusteredBest.getPopulationMeasures();
|
||||
// int[] sols = createFitNormHistogram(clusteredBest, minBnd, maxBnd, bins);
|
||||
// out.println("measures: " + BeanInspector.toString(meas));
|
||||
// out.println("solution hist.: " + BeanInspector.toString(sols));
|
||||
//
|
||||
// Object[] bestArr = clusteredBest.toArray();
|
||||
// for (Object locOpt : bestArr) {
|
||||
//// out.print((AbstractEAIndividual.getDefaultDataString((IndividualInterface)locOpt)));
|
||||
// out.println(AbstractEAIndividual.getDefaultStringRepresentation(((AbstractEAIndividual)locOpt)));
|
||||
// }
|
||||
// return clusteredBest;
|
||||
// }
|
||||
|
||||
// public static Population outputResultKnown(InterfaceMultimodalProblemKnown mmProb, Population pop, double sigmaCluster, PrintStream out, double minBnd, double maxBnd, int bins) {
|
||||
// Population found = getFoundOptima(pop, ((InterfaceMultimodalProblemKnown)mmProb).getRealOptima(), ((InterfaceMultimodalProblemKnown)mmProb).getEpsilon(), true);
|
||||
// for (double epsilon=0.1; epsilon > 0.00000001; epsilon/=10.) {
|
||||
// //out.println("no optima found: " + ((InterfaceMultimodalProblemKnown)mmProb).getNumberOfFoundOptima(pop));
|
||||
// out.println("found " + getFoundOptima(pop, ((InterfaceMultimodalProblemKnown)mmProb).getRealOptima(), epsilon, true).size() + " for epsilon = " + epsilon);
|
||||
// }
|
||||
// out.println("max peak ratio is " + mmProb.getMaximumPeakRatio(found));
|
||||
// return found;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Do some data output for multimodal problems with known optima. The listener may be null, but then the method is
|
||||
* not really doing much at this state.
|
||||
* Do some data output for multimodal problems to the listener.
|
||||
* This may be expensive computationally.
|
||||
*/
|
||||
public static void procMultiModalKnown(Population solutions, InterfaceMultimodalProblemKnown mmkProb, InterfaceTextListener listener) {
|
||||
// Population found = getFoundOptima(solutions, mmkProb.getRealOptima(), mmkProb.getEpsilon(), true);
|
||||
if (listener != null) {
|
||||
public static void evaluateMultiModal(Population solutions, AbstractOptimizationProblem prob, InterfaceTextListener listener) {
|
||||
if (listener == null) return;
|
||||
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());
|
||||
@ -846,6 +866,21 @@ public class PostProcess {
|
||||
// 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));
|
||||
}
|
||||
} else {
|
||||
// TODO in this form it may cost a lot of time and cant be stopped, which is bad
|
||||
// double epsilonPhenoSpace = 0.01, epsilonFitConv = 1e-10, clusterSigma = 0.;
|
||||
// Population extrOpts;
|
||||
// for (int k=0; k<3; k++) {
|
||||
// extrOpts = prob.extractPotentialOptima(solutions, epsilonPhenoSpace, epsilonFitConv, clusterSigma, -1);
|
||||
// listener.println("estimated number of found optima: " + extrOpts.size() + " with crit. " + epsilonPhenoSpace);
|
||||
// if (extrOpts.size() > 0) {
|
||||
// listener.println("fit measures: ");
|
||||
// int critCnt = extrOpts.getEAIndividual(0).getFitness().length;
|
||||
// for (int i=0; i<critCnt; i++) listener.print(BeanInspector.toString(extrOpts.getFitnessMeasures(i)) + " ");
|
||||
// listener.println("");
|
||||
// }
|
||||
// epsilonPhenoSpace /= 10.;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@ -880,11 +915,14 @@ public class PostProcess {
|
||||
double stepSize = selectMaxSearchRange(params.getPPMethod(), params.getPostProcessClusterSigma());
|
||||
stateBeforeLS = (Population)clusteredPop.clone();
|
||||
// Actual local search comes here
|
||||
InterfaceMutation mutator;
|
||||
if (params.getPPMethod() == PostProcessMethod.hillClimber){
|
||||
stepsDone = processWithHC(clusteredPop, problem, params.getPostProcessSteps(), stepSize, minMutationStepSize);
|
||||
mutator = new MutateESMutativeStepSizeControl(stepSize, minMutationStepSize, stepSize);
|
||||
// stepsDone = processWithHC(clusteredPop, problem, params.getPostProcessSteps(), stepSize, minMutationStepSize);
|
||||
} else {
|
||||
stepsDone = processSingleCandidates(params.getPPMethod(), clusteredPop, params.getPostProcessSteps(), stepSize, problem);
|
||||
mutator = null;
|
||||
}
|
||||
stepsDone = processSingleCandidates(params.getPPMethod(), clusteredPop, params.getPostProcessSteps(), stepSize, problem, mutator);
|
||||
|
||||
if (listener != null) listener.println("Post processing: " + stepsDone + " steps done.");
|
||||
if (params.isWithPlot()) {
|
||||
@ -913,15 +951,16 @@ public class PostProcess {
|
||||
if (listener != null) listener.println("solution histogram in [" + lowBnd + "," + upBnd + "]: " + BeanInspector.toString(sols));
|
||||
}
|
||||
|
||||
//////////// multimodal data output?
|
||||
if (problem instanceof InterfaceMultimodalProblemKnown) procMultiModalKnown(outputPop, (InterfaceMultimodalProblemKnown)problem, listener);
|
||||
|
||||
//////////// multimodal data output
|
||||
evaluateMultiModal(outputPop, problem, listener);
|
||||
|
||||
Population nBestPop = outputPop.getBestNIndividuals(params.getPrintNBest()); // n individuals are returned and sorted, all of them if n<=0
|
||||
if (listener != null) listener.println("Best after post process:" + ((outputPop.size()>nBestPop.size()) ? ( "(first " + nBestPop.size() + " of " + outputPop.size() + ")") : ""));
|
||||
//////////// output some individual data
|
||||
if (listener != null) for (int i=0; i<nBestPop.size(); i++) {
|
||||
listener.println(AbstractEAIndividual.getDefaultStringRepresentation(nBestPop.getEAIndividual(i)));
|
||||
}
|
||||
// System.out.println(nBestPop);
|
||||
return nBestPop;
|
||||
} else return inputPop;
|
||||
}
|
||||
@ -962,13 +1001,15 @@ public class PostProcess {
|
||||
* @param maxPerturb optional upper bound of the returned perturbation
|
||||
* @return
|
||||
*/
|
||||
private static double findNMSPerturn(Population candidates, int i, double maxPerturb) {
|
||||
public static double findNMSPerturb(Population candidates, int i, double maxPerturb) {
|
||||
double minDistNeighbour = Double.MAX_VALUE;
|
||||
AbstractEAIndividual indy = candidates.getEAIndividual(i);
|
||||
for (int k=0; k<candidates.size(); k++) {
|
||||
if (k!=i) {
|
||||
double dist = PhenotypeMetric.euclidianDistance(AbstractEAIndividual.getDoublePosition(indy), AbstractEAIndividual.getDoublePosition(candidates.getEAIndividual(k)));
|
||||
if (dist < minDistNeighbour) {
|
||||
if (dist == 0.) {
|
||||
System.err.println("error, equal candidates in findNMSPerturb!");
|
||||
} else if (dist < minDistNeighbour) {
|
||||
minDistNeighbour = dist;
|
||||
}
|
||||
}
|
||||
@ -976,5 +1017,101 @@ public class PostProcess {
|
||||
if (maxPerturb>0) return Math.min(maxPerturb, minDistNeighbour/3.);
|
||||
else return minDistNeighbour/3.;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sample a given problem randomly for the number of times specified and calculate the average
|
||||
* fitness returned after evaluation. This may give a general measure of how good an optimum is
|
||||
* on an unknown function. Of course its expensive for problems with considerable computational
|
||||
* cost.
|
||||
*
|
||||
* @param steps
|
||||
* @param prob
|
||||
* @return an averaged fitness vector
|
||||
*/
|
||||
public static double[] calcAvgRandomFunctionValue(int steps, AbstractOptimizationProblem prob) {
|
||||
int cnt = 0;
|
||||
int portion = 100;
|
||||
int curPopSize = Math.min(portion, steps);
|
||||
double[] portionFitSum = null;
|
||||
double[] avgFit = null;
|
||||
Population pop = new Population(portion);
|
||||
IndividualInterface indy;
|
||||
prob.initProblem();
|
||||
while (cnt < steps) {
|
||||
pop.clear();
|
||||
for (int i=0; i<curPopSize; i++) {
|
||||
// fill pop randomly
|
||||
indy = prob.getIndividualTemplate().getClone();
|
||||
indy.defaultInit();
|
||||
pop.add(indy);
|
||||
}
|
||||
pop.synchSize();
|
||||
// evaluate pop
|
||||
prob.evaluate(pop);
|
||||
if (portionFitSum==null) {
|
||||
portionFitSum = new double[pop.getEAIndividual(0).getFitness().length];
|
||||
avgFit = new double[portionFitSum.length];
|
||||
Arrays.fill(avgFit, 0.);
|
||||
}
|
||||
Arrays.fill(portionFitSum, 0.);
|
||||
for (int i=0; i<curPopSize; i++) {
|
||||
// calc fit-sum
|
||||
Mathematics.vvAdd(portionFitSum, pop.getEAIndividual(i).getFitness(), portionFitSum);
|
||||
}
|
||||
// add to average
|
||||
Mathematics.svvAddScaled(1./(steps), portionFitSum, avgFit, avgFit);
|
||||
// select next population size
|
||||
cnt += curPopSize;
|
||||
curPopSize = Math.min(portion, steps-cnt); // the new population size.
|
||||
}
|
||||
return avgFit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the average Euclidian distance between the individual with given index
|
||||
* within the population to the other members of the population.
|
||||
* If the population has only one member, zero is returned.
|
||||
*
|
||||
* @param index
|
||||
* @param pop
|
||||
* @return
|
||||
*/
|
||||
public static double getAvgDistToNeighbor(int index, Population pop) {
|
||||
double distSum = 0;
|
||||
int cnt = pop.size()-1;
|
||||
if (cnt == 0) return 0.;
|
||||
else {
|
||||
double[] indyPos = AbstractEAIndividual.getDoublePosition(pop.getEAIndividual(index));
|
||||
for (int i=0; i<pop.size(); i++) {
|
||||
if (i!=index) distSum += PhenotypeMetric.euclidianDistance(AbstractEAIndividual.getDoublePosition(pop.getEAIndividual(i)), indyPos);
|
||||
}
|
||||
return distSum/((double)cnt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate a score for a given population of solutions to a problem. The score depends on the
|
||||
* quality and the diversity of the solutions, growing with both. It is expected that the
|
||||
* population is clustered beforehand. This method is rather experimental.
|
||||
*
|
||||
* @param avgFitSteps
|
||||
* @param solutions
|
||||
* @param criterion
|
||||
* @param problem
|
||||
* @return
|
||||
*/
|
||||
public static double calcQualityMeasure(int avgFitSteps, Population solutions, int criterion, AbstractOptimizationProblem problem) {
|
||||
int solCnt = solutions.size();
|
||||
double indyQual, indyAvgDist, indyScore = 0.;
|
||||
double scoreSum = 0.;
|
||||
double[] avgFit = calcAvgRandomFunctionValue(avgFitSteps, problem);
|
||||
for (int i=0; i<solCnt; i++) {
|
||||
indyQual = avgFit[criterion] - solutions.getEAIndividual(i).getFitness(criterion);
|
||||
indyAvgDist = getAvgDistToNeighbor(i, solutions);
|
||||
indyScore = Math.pow(indyQual, 2) + Math.pow(1+indyAvgDist, 2);
|
||||
scoreSum += indyScore;
|
||||
}
|
||||
return Math.sqrt(scoreSum);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,11 +40,21 @@ public class PostProcessParams implements InterfacePostProcessParams, Serializab
|
||||
}
|
||||
|
||||
public PostProcessParams(PostProcessMethod meth, int steps, double clusterSigma, int nBest) {
|
||||
reset(meth, steps, clusterSigma, nBest, false);
|
||||
}
|
||||
|
||||
public PostProcessParams(PostProcessMethod meth, int steps, double clusterSigma, int nBest, boolean doPlot) {
|
||||
reset(meth, steps, clusterSigma, nBest, doPlot);
|
||||
}
|
||||
|
||||
public PostProcessParams reset(PostProcessMethod meth, int steps, double clusterSigma, int nBest, boolean doPlot) {
|
||||
method = meth;
|
||||
postProcessSteps = steps;
|
||||
postProcess = true;
|
||||
postProcessClusterSigma = clusterSigma;
|
||||
printNBest = nBest;
|
||||
withPlot = doPlot;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void hideHideable() {
|
||||
|
@ -2,7 +2,6 @@ package eva2.server.go.populations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@ -40,7 +39,6 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
protected int m_Size = 50;
|
||||
protected Population m_Archive = null;
|
||||
|
||||
transient private ArrayList<AbstractEAIndividual> sortedArr = null;
|
||||
transient private ArrayList<InterfacePopulationChangedEventListener> listeners = null;
|
||||
// transient protected InterfacePopulationChangedEventListener m_Listener = null;
|
||||
|
||||
@ -57,6 +55,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
|
||||
// remember when the last sorted queue was prepared
|
||||
private int lastQModCount = -1;
|
||||
// a sorted queue (for efficiency)
|
||||
transient private ArrayList<AbstractEAIndividual> sortedArr = null;
|
||||
// remember when the last evaluation was performed
|
||||
private Pair<Integer,Integer> evaluationTimeHashes = null;
|
||||
// remember when the last evaluation was performed
|
||||
@ -513,7 +513,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
*
|
||||
*/
|
||||
public Population getSortedNIndividuals(int n, boolean bBestOrWorst) {
|
||||
Population result = new Population(n);
|
||||
Population result = new Population((n > 0) ? n : this.size());
|
||||
getSortedNIndividuals(n, bBestOrWorst, result);
|
||||
return result;
|
||||
}
|
||||
@ -557,7 +557,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
if (sortedArr == null || (super.modCount != lastQModCount)) {
|
||||
PriorityQueue<AbstractEAIndividual> sQueue = new PriorityQueue<AbstractEAIndividual>(super.size(), new AbstractEAIndividualComparator());
|
||||
for (int i = 0; i < super.size(); i++) {
|
||||
sQueue.add(getEAIndividual(i));
|
||||
AbstractEAIndividual indy = getEAIndividual(i);
|
||||
if (indy != null) sQueue.add(indy);
|
||||
}
|
||||
lastQModCount = super.modCount;
|
||||
if (sortedArr==null) sortedArr = new ArrayList<AbstractEAIndividual>(this.size());
|
||||
@ -794,24 +795,28 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
return "A population stores the individuals of a generation.";
|
||||
}
|
||||
|
||||
/** This method allows you to set the population size
|
||||
/**
|
||||
* This method allows you to set the population size. Be aware that this will not
|
||||
* directly alter the number of individuals stored. The actual size will be
|
||||
* adapted on a reinitialization, for example.
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
public void setPopulationSize(int size) {
|
||||
this.m_Size = size;
|
||||
// int rand;
|
||||
// if (this.size() != 0) {
|
||||
// while (this.size() < size) {
|
||||
// rand = RNG.randomInt(0, this.size()-1);
|
||||
// this.add(((AbstractEAIndividual)this.get(rand)).clone());
|
||||
// }
|
||||
// while (this.size() > size) {
|
||||
// rand = RNG.randomInt(0, this.size()-1);
|
||||
// this.remove(rand);
|
||||
// }
|
||||
// }
|
||||
// System.out.println("This.size() = "+this.size() +" this.getSize() = " + this.m_Size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method.
|
||||
*
|
||||
* @param size
|
||||
* @return
|
||||
*/
|
||||
public Population setPopSize(int size) {
|
||||
this.m_Size = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getPopulationSize() {
|
||||
return this.m_Size;
|
||||
}
|
||||
@ -949,9 +954,51 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
if (d > maxDist) maxDist = d;
|
||||
}
|
||||
}
|
||||
res[0] = meanDist / (this.size() * (this.size()-1) / 2);
|
||||
res[1] = minDist;
|
||||
res[2] = maxDist;
|
||||
if (this.size() > 1) res[0] = meanDist / (this.size() * (this.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.
|
||||
*
|
||||
* @param fitCrit fitness dimension to be used
|
||||
* @return the average, minimal, maximal and std dev. of fitness of individuals in an array
|
||||
*/
|
||||
public double[] getFitnessMeasures(int fitCrit) {
|
||||
double d;
|
||||
double[] res = new double[4];
|
||||
|
||||
res[0] = 0.;
|
||||
res[1] = Double.MAX_VALUE;
|
||||
res[2] = Double.MIN_VALUE;
|
||||
res[3] = 0;
|
||||
|
||||
for (int i = 0; i < this.size(); i++) {
|
||||
d = this.getEAIndividual(i).getFitness(fitCrit);
|
||||
res[0] += d;
|
||||
if (d < res[1]) res[1] = d;
|
||||
if (d > res[2]) res[2] = d;
|
||||
}
|
||||
|
||||
if (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[3]+=d*d;
|
||||
}
|
||||
res[3] /= this.size();
|
||||
res[3] = Math.sqrt(res[3]);
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -1012,6 +1059,80 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
return mean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the closest individual which is not equal to the given individual. 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) {
|
||||
// get the neighbor...
|
||||
int index = -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 = PhenotypeMetric.euclidianDistance(AbstractEAIndividual.getDoublePosition(indy),
|
||||
AbstractEAIndividual.getDoublePosition(currentindy));
|
||||
if (dist < mindist){
|
||||
mindist = dist;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (index == -1){
|
||||
System.err.println("Pop too small or all individuals in population are equal !?");
|
||||
return -1;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the average of the distance of each individual to its closest neighbor in the population.
|
||||
* The boolean parameter switches between range-normalized and simple euclidian distance. If calcVariance
|
||||
* is true, the variance is calculated and returned as second entry
|
||||
*
|
||||
* @param normalizedPhenoMetric
|
||||
* @return a double array containing the average (or average and variance) of the distance of each individual to its closest neighbor
|
||||
*/
|
||||
public double[] getAvgDistToClosestNeighbor(boolean normalizedPhenoMetric, boolean calcVariance){
|
||||
PhenotypeMetric metric = new PhenotypeMetric();
|
||||
ArrayList<Double> distances = null;
|
||||
if (calcVariance) distances = new ArrayList<Double>(size());
|
||||
double sum = 0;
|
||||
double d=0;
|
||||
for (int i = 0; i < size(); ++i){
|
||||
AbstractEAIndividual neighbor, indy = getEAIndividual(i);
|
||||
int neighborIndex = getNeighborIndex(indy);
|
||||
if (neighborIndex >= 0) neighbor = getEAIndividual(neighborIndex);
|
||||
else return null;
|
||||
if (normalizedPhenoMetric){
|
||||
d = metric.distance(indy, neighbor);
|
||||
} else {
|
||||
d = PhenotypeMetric.euclidianDistance(AbstractEAIndividual.getDoublePosition(indy),
|
||||
AbstractEAIndividual.getDoublePosition(neighbor));
|
||||
}
|
||||
if (calcVariance) distances.add(d);
|
||||
sum += d;
|
||||
}
|
||||
double avg = sum/(double)size();
|
||||
double[] res;
|
||||
if (calcVariance) {
|
||||
res = new double[2];
|
||||
double var = 0;
|
||||
for (int i=0; i<distances.size(); i++) {
|
||||
var += Math.pow(distances.get(i)-avg, 2);
|
||||
}
|
||||
res[1]=var;
|
||||
}
|
||||
else res = new double[1];
|
||||
res[0] = avg;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire an event every n function calls, the event sends the public String funCallIntervalReached.
|
||||
* Be aware that if this interval is smaller than the population size, it may happen that a notification
|
||||
|
@ -17,7 +17,7 @@ import eva2.tools.EVAERROR;
|
||||
public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDouble implements Interface2DBorderProblem, InterfaceMultimodalProblemKnown {
|
||||
protected static InterfaceDistanceMetric m_Metric = new PhenotypeMetric();
|
||||
private double m_GlobalOpt = 0;
|
||||
private Population m_Optima;
|
||||
protected Population m_Optima;
|
||||
protected double m_Epsilon = 0.05;
|
||||
// protected double[][] m_Range;
|
||||
// protected double[] m_Extrema;
|
||||
@ -87,9 +87,11 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
|
||||
// population init must be last
|
||||
// it set's fitcalls and generation to zero
|
||||
population.init();
|
||||
this.m_GlobalOpt = Double.NEGATIVE_INFINITY;
|
||||
m_Optima = new Population();
|
||||
this.initListOfOptima();
|
||||
if (m_Optima == null) {
|
||||
this.m_GlobalOpt = Double.NEGATIVE_INFINITY;
|
||||
m_Optima = new Population();
|
||||
this.initListOfOptima();
|
||||
}
|
||||
}
|
||||
|
||||
public void initProblem() {
|
||||
@ -122,7 +124,7 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
|
||||
* @return String
|
||||
*/
|
||||
public String getAdditionalFileStringHeader(PopulationInterface pop) {
|
||||
return "Solution \t Number of Optima found \t Maximum Peak Ratio";
|
||||
return "#Optima found \t Maximum Peak Ratio";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,7 +134,7 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
|
||||
*/
|
||||
public String getAdditionalFileStringValue(PopulationInterface pop) {
|
||||
String result = "";
|
||||
result += AbstractEAIndividual.getDefaultDataString(pop.getBestIndividual()) +"\t";
|
||||
// result += AbstractEAIndividual.getDefaultDataString(pop.getBestIndividual()) +"\t";
|
||||
result += this.getNumberOfFoundOptima((Population)pop)+"\t";
|
||||
result += this.getMaximumPeakRatio((Population)pop);
|
||||
return result;
|
||||
@ -242,7 +244,7 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
|
||||
public static double getMaximumPeakRatio(InterfaceMultimodalProblemKnown mmProb, Population pop, double epsilon) {
|
||||
double foundInvertedSum = 0, sumRealMaxima = 0;
|
||||
Population realOpts = mmProb.getRealOptima();
|
||||
double maxOpt = realOpts.getEAIndividual(0).getFitness(0);
|
||||
double tmp, maxOpt = realOpts.getEAIndividual(0).getFitness(0);
|
||||
sumRealMaxima = maxOpt;
|
||||
for (int i=1; i<realOpts.size(); i++) {
|
||||
// search for the maximum fitness (for the maximization problem)
|
||||
@ -255,7 +257,10 @@ public abstract class AbstractMultiModalProblemKnown extends AbstractProblemDoub
|
||||
for (int i=0; i<realOpts.size(); i++) {
|
||||
// sum up the found optimal fitness values
|
||||
if (optsFound[i] != null) {
|
||||
foundInvertedSum += (maxOpt - optsFound[i].getFitness(0));
|
||||
tmp = (maxOpt - optsFound[i].getFitness(0));
|
||||
if (tmp < 0) EVAERROR.errorMsgOnce("warning: for the MPR calculation, negative fitness values may disturb the allover result (AbstractMultiModalProblemKnown)");
|
||||
foundInvertedSum += Math.max(0., tmp);
|
||||
// System.out.println("foundInvertedSum = " + foundInvertedSum);
|
||||
}
|
||||
}
|
||||
// System.out.println("foundSum: " + foundInvertedSum + " realsum: " + sumRealMaxima + " ratio: " + foundInvertedSum/sumRealMaxima);
|
||||
|
@ -7,16 +7,23 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
|
||||
import eva2.server.go.InterfaceTerminator;
|
||||
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.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.terminators.CombinedTerminator;
|
||||
import eva2.server.go.operators.terminators.EvaluationTerminator;
|
||||
import eva2.server.go.operators.terminators.PhenotypeConvergenceTerminator;
|
||||
import eva2.server.go.populations.Population;
|
||||
import eva2.server.go.strategies.InterfaceOptimizer;
|
||||
import eva2.tools.Mathematics;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
@ -111,6 +118,7 @@ public abstract class AbstractOptimizationProblem implements InterfaceOptimizati
|
||||
*/
|
||||
public String getAdditionalFileStringHeader(PopulationInterface pop) {
|
||||
return "Solution";
|
||||
// return "";
|
||||
}
|
||||
|
||||
/** This method returns the additional data that is to be written into a file
|
||||
@ -118,6 +126,7 @@ public abstract class AbstractOptimizationProblem implements InterfaceOptimizati
|
||||
* @return String
|
||||
*/
|
||||
public String getAdditionalFileStringValue(PopulationInterface pop) {
|
||||
// return "";
|
||||
return AbstractEAIndividual.getDefaultDataString(pop.getBestIndividual());
|
||||
}
|
||||
|
||||
@ -196,22 +205,27 @@ public abstract class AbstractOptimizationProblem implements InterfaceOptimizati
|
||||
|
||||
/**
|
||||
* This method extracts the individuals from a given population that are assumed to correspond to local or global optima.
|
||||
* Similar inidviduals are clustered together with a density based clustering method
|
||||
* Similar individuals are clustered together with a density based clustering method
|
||||
* @param pop
|
||||
* @param epsilon maximal allowed improvement of an individual before considered premature (given as distance in the search space)
|
||||
* @param epsilonPhenoSpace maximal allowed improvement of an individual before considered premature (given as distance in the search space)
|
||||
* @param epsilonFitConv if positive: additional absolute convergence criterion (fitness space) as termination criterion of the local search
|
||||
* @param clusterSigma minimum cluster distance
|
||||
* @param numOfFailures
|
||||
* @see #isPotentialOptimumNMS(AbstractEAIndividual, double, double, int)
|
||||
* @return
|
||||
*/
|
||||
public Population extractPotentialOptima(Population pop, double epsilon, double clusterSigma) {
|
||||
public Population extractPotentialOptima(Population pop, double epsilonPhenoSpace, double epsilonFitConv, double clusterSigma, int numOfFailures) {
|
||||
Population potOptima = new Population();
|
||||
for (int i = 0; i < pop.size(); ++i){
|
||||
AbstractEAIndividual indy = pop.getEAIndividual(i);
|
||||
if (isPotentialOptimum(indy, epsilon,-1,-1)){
|
||||
// System.out.println("bef: " + indy.toString());
|
||||
if (isPotentialOptimumNMS(indy, epsilonPhenoSpace, epsilonFitConv, numOfFailures)){
|
||||
// if (isPotentialOptimum(indy, epsilon,-1,-1)){
|
||||
potOptima.addIndividual(indy);
|
||||
}
|
||||
}
|
||||
Population clusteredPop = (Population)PostProcess.clusterBest(potOptima, clusterSigma, 0, PostProcess.KEEP_LONERS, PostProcess.BEST_ONLY).clone();
|
||||
return clusteredPop;
|
||||
if (clusterSigma > 0) return (Population)PostProcess.clusterBest(potOptima, clusterSigma, 0, PostProcess.KEEP_LONERS, PostProcess.BEST_ONLY).clone();
|
||||
else return potOptima;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -273,6 +287,50 @@ public abstract class AbstractOptimizationProblem implements InterfaceOptimizati
|
||||
else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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
|
||||
* function.
|
||||
*
|
||||
* @param orig
|
||||
* @param epsilonPhenoSpace
|
||||
* @param epsilonFitConv
|
||||
* @param numOfFailures
|
||||
* @return
|
||||
*/
|
||||
public boolean isPotentialOptimumNMS(AbstractEAIndividual orig, double epsilonPhenoSpace, double epsilonFitConv, int numOfFailures){
|
||||
|
||||
AbstractEAIndividual indy = (AbstractEAIndividual)orig.clone();
|
||||
this.evaluate(indy); // indy may be evaluated in a normalised way...
|
||||
|
||||
InterfaceDistanceMetric metric = new PhenotypeMetric();
|
||||
double overallDist = 0;
|
||||
double initPerturb = -1;
|
||||
int dim = -1;
|
||||
if (orig instanceof InterfaceDataTypeDouble) {
|
||||
initPerturb = epsilonPhenoSpace/(2*(Mathematics.getAvgRange(((InterfaceDataTypeDouble)orig).getDoubleRange())));
|
||||
dim=((InterfaceDataTypeDouble)orig).getDoubleRange().length;
|
||||
if (numOfFailures<0) numOfFailures = 100*AbstractEAIndividual.getDoublePosition(this.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;
|
||||
}
|
||||
|
||||
Population pop = new Population(1);
|
||||
pop.add(orig);
|
||||
InterfaceTerminator term = new EvaluationTerminator(numOfFailures);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************
|
||||
* These are for GUI
|
||||
*/
|
||||
|
@ -17,6 +17,10 @@ public class F13Problem extends F1Problem implements InterfaceMultimodalProblem
|
||||
public F13Problem(F13Problem b) {
|
||||
super(b);
|
||||
}
|
||||
public F13Problem(int dim) {
|
||||
super();
|
||||
setProblemDimension(dim);
|
||||
}
|
||||
|
||||
/** This method returns a deep clone of the problem.
|
||||
* @return the clone
|
||||
|
@ -38,7 +38,17 @@ public class F1Problem extends AbstractProblemDouble implements Interface2DBorde
|
||||
this.m_YOffSet = b.m_YOffSet;
|
||||
this.m_UseTestConstraint = b.m_UseTestConstraint;
|
||||
}
|
||||
|
||||
|
||||
public F1Problem(int dim) {
|
||||
this();
|
||||
setProblemDimension(dim);
|
||||
}
|
||||
|
||||
public F1Problem(int dim, double defRange) {
|
||||
this(dim);
|
||||
setDefaultRange(defRange);
|
||||
}
|
||||
|
||||
/** This method returns a deep clone of the problem.
|
||||
* @return the clone
|
||||
*/
|
||||
|
@ -190,7 +190,8 @@ public class PSymbolicRegression extends AbstractOptimizationProblem implements
|
||||
evaluatePopulationEnd(population);
|
||||
}
|
||||
|
||||
/** This method evaluate a single individual and sets the fitness values
|
||||
/**
|
||||
* This method evaluates a single individual and sets the fitness values
|
||||
* @param individual The individual that is to be evalutated
|
||||
*/
|
||||
public void evaluate(AbstractEAIndividual individual) {
|
||||
@ -203,13 +204,14 @@ public class PSymbolicRegression extends AbstractOptimizationProblem implements
|
||||
if ((tmpIndy instanceof GAPIndividualProgramData) && (this.m_UseInnerConst))
|
||||
this.m_C = ((GAPIndividualProgramData)tmpIndy).getDoubleData();
|
||||
fitness = 0;
|
||||
for (double i = 0; i < this.m_NumberOfCheckPoints; i++) {
|
||||
for (int j = 0; j < this.m_X.length; j++)
|
||||
this.m_X[j] = this.m_LowerBound +(i*(this.m_UpperBound-this.m_LowerBound)/this.m_NumberOfCheckPoints);
|
||||
tmpValue = ((Double)program.evaluate(this)).doubleValue();
|
||||
fitness += Math.pow((this.m_TargetFunction.evaulateFunction(this.m_X) - ((Double)program.evaluate(this)).doubleValue()), 2);
|
||||
}
|
||||
|
||||
for (int j = 0; j < this.m_NumberOfCheckPoints; j++)
|
||||
for (int i = 0; i < this.m_X.length; i++) {
|
||||
this.m_X[i] = this.m_LowerBound +(j*(this.m_UpperBound-this.m_LowerBound)/this.m_NumberOfCheckPoints);
|
||||
tmpValue = ((Double)program.evaluate(this)).doubleValue();
|
||||
fitness += Math.pow((this.m_TargetFunction.evaluateFunction(this.m_X) - ((Double)program.evaluate(this)).doubleValue()), 2);
|
||||
}
|
||||
|
||||
fitness = fitness / (double)this.m_NumberOfCheckPoints;
|
||||
// add noise to the fitness
|
||||
fitness += RNG.gaussianDouble(this.m_Noise);
|
||||
@ -225,7 +227,7 @@ public class PSymbolicRegression extends AbstractOptimizationProblem implements
|
||||
for (int j = 0; j < this.m_X.length; j++) this.m_X[j] = i ;
|
||||
tmpValue = ((Double)program.evaluate(this)).doubleValue();
|
||||
this.m_Plot.setConnectedPoint(this.m_X[0], tmpValue, 0);
|
||||
tmpValue = this.m_TargetFunction.evaulateFunction(this.m_X);
|
||||
tmpValue = this.m_TargetFunction.evaluateFunction(this.m_X);
|
||||
this.m_Plot.setConnectedPoint(this.m_X[0], tmpValue, 1);
|
||||
this.m_Plot.setInfoString(1, program.getStringRepresentation(), 1.0f);
|
||||
}
|
||||
@ -233,7 +235,7 @@ public class PSymbolicRegression extends AbstractOptimizationProblem implements
|
||||
}
|
||||
}
|
||||
|
||||
/** This method returns a string describing the optimization problem.
|
||||
/** This method returns a string describing the optimization problem.
|
||||
* @param opt The Optimizer that is used or had been used.
|
||||
* @return The description.
|
||||
*/
|
||||
|
@ -18,5 +18,5 @@ public interface InterfaceRegressionFunction {
|
||||
* @param x Input vector.
|
||||
* @return y the function result.
|
||||
*/
|
||||
public double evaulateFunction(double[] x);
|
||||
public double evaluateFunction(double[] x);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class RFKoza_GPI_10_1 implements InterfaceRegressionFunction, java.io.Ser
|
||||
* @param x Input vector.
|
||||
* @return y the function result.
|
||||
*/
|
||||
public double evaulateFunction(double[] x) {
|
||||
public double evaluateFunction(double[] x) {
|
||||
double result = 0;
|
||||
for (int i = 0; i < x.length; i++) result += Math.cos(2*x[i]);
|
||||
return result;
|
||||
|
@ -25,7 +25,7 @@ public class RFKoza_GPI_10_2 implements InterfaceRegressionFunction, java.io.Ser
|
||||
* @param x Input vector.
|
||||
* @return y the function result.
|
||||
*/
|
||||
public double evaulateFunction(double[] x) {
|
||||
public double evaluateFunction(double[] x) {
|
||||
double result = 0;
|
||||
for (int i = 0; i < x.length; i++) result += 3.1416*x[i] + 2.718 * Math.pow(x[i], 2);
|
||||
return result;
|
||||
|
@ -25,7 +25,7 @@ public class RFKoza_GPI_7_3 implements InterfaceRegressionFunction, java.io.Seri
|
||||
* @param x Input vector.
|
||||
* @return y the function result.
|
||||
*/
|
||||
public double evaulateFunction(double[] x) {
|
||||
public double evaluateFunction(double[] x) {
|
||||
double result = 0;
|
||||
for (int i = 0; i < x.length; i++) result += Math.pow(x[i], 4) + Math.pow(x[i], 3) + Math.pow(x[i], 2) + Math.pow(x[i], 1);
|
||||
return result;
|
||||
|
@ -25,7 +25,7 @@ public class RFKoza_GPI_7_3_extended implements InterfaceRegressionFunction, jav
|
||||
* @param x Input vector.
|
||||
* @return y the function result.
|
||||
*/
|
||||
public double evaulateFunction(double[] x) {
|
||||
public double evaluateFunction(double[] x) {
|
||||
double result = 0;
|
||||
for (int i = 0; i < x.length; i++) result += 0.12345*Math.pow(x[i], 4) + (Math.PI/4)*Math.pow(x[i], 3) + (Math.E/2)*Math.pow(x[i], 2) + 1.23456*Math.pow(x[i], 1);
|
||||
return result;
|
||||
|
@ -25,7 +25,7 @@ public class RFRaidl_F1 implements InterfaceRegressionFunction, java.io.Serializ
|
||||
* @param x Input vector.
|
||||
* @return y the function result.
|
||||
*/
|
||||
public double evaulateFunction(double[] x) {
|
||||
public double evaluateFunction(double[] x) {
|
||||
double result = 0;
|
||||
for (int i = 0; i < x.length; i++) result += Math.sin(x[i]);
|
||||
return result;
|
||||
|
@ -25,7 +25,7 @@ public class RFRaidl_F2 implements InterfaceRegressionFunction, java.io.Serializ
|
||||
* @param x Input vector.
|
||||
* @return y the function result.
|
||||
*/
|
||||
public double evaulateFunction(double[] x) {
|
||||
public double evaluateFunction(double[] x) {
|
||||
double result = 0;
|
||||
for (int i = 0; i < x.length; i++) result += Math.exp(x[i]/3)*Math.cos(3*x[i])/2;
|
||||
return result;
|
||||
|
@ -25,7 +25,7 @@ public class RFRaidl_F3 implements InterfaceRegressionFunction, java.io.Serializ
|
||||
* @param x Input vector.
|
||||
* @return y the function result.
|
||||
*/
|
||||
public double evaulateFunction(double[] x) {
|
||||
public double evaluateFunction(double[] x) {
|
||||
double result = 0;
|
||||
for (int i = 0; i < x.length; i++) result += Math.log(4+2*Math.sin(x[i]*Math.sin(8*x[i])))*Math.exp(Math.cos(3*x[i]));
|
||||
return result;
|
||||
|
@ -4,6 +4,7 @@ import java.io.Serializable;
|
||||
|
||||
import eva2.gui.GenericObjectEditor;
|
||||
import eva2.server.go.InterfacePopulationChangedEventListener;
|
||||
import eva2.server.go.enums.PostProcessMethod;
|
||||
import eva2.server.go.operators.mutation.MutateESFixedStepSize;
|
||||
import eva2.server.go.operators.postprocess.PostProcess;
|
||||
import eva2.server.go.populations.InterfaceSolutionSet;
|
||||
@ -50,6 +51,7 @@ public class ClusteringHillClimbing implements InterfacePopulationChangedEventLi
|
||||
// reduce the step size when there is hardy improvement.
|
||||
private double reduceFactor = 0.2;
|
||||
private MutateESFixedStepSize mutator = new MutateESFixedStepSize(0.1);
|
||||
private PostProcessMethod localSearchMethod = PostProcessMethod.nelderMead;
|
||||
|
||||
public ClusteringHillClimbing() {
|
||||
hideHideable();
|
||||
@ -143,18 +145,25 @@ public class ClusteringHillClimbing implements InterfacePopulationChangedEventLi
|
||||
loopCnt++;
|
||||
m_Population.addPopulationChangedEventListener(this);
|
||||
m_Population.setNotifyEvalInterval(notifyGuiEvery);
|
||||
Pair<Population, Double> popD = PostProcess.clusterHC(m_Population, (AbstractOptimizationProblem)m_Problem, sigmaClust, hcEvalCycle - (m_Population.getFunctionCalls() % hcEvalCycle), 0.5, mutator);
|
||||
Pair<Population, Double> popD;
|
||||
if (TRACE) System.out.println("evalCycle: " + hcEvalCycle + ", evals now: " + (2*hcEvalCycle - (m_Population.getFunctionCalls() % hcEvalCycle)));
|
||||
popD = PostProcess.clusterLocalSearch(localSearchMethod, m_Population, (AbstractOptimizationProblem)m_Problem, sigmaClust, 2*hcEvalCycle - (m_Population.getFunctionCalls() % hcEvalCycle), 0.5, mutator);
|
||||
// (m_Population, (AbstractOptimizationProblem)m_Problem, sigmaClust, hcEvalCycle - (m_Population.getFunctionCalls() % hcEvalCycle), 0.5);
|
||||
improvement = popD.tail();
|
||||
m_Population = popD.head();
|
||||
if (TRACE) System.out.println("num inds after clusterLS: " + m_Population.size());
|
||||
|
||||
popD.head().setGenerationTo(m_Population.getGeneration()+1);
|
||||
|
||||
if (improvement < minImprovement) {
|
||||
if (TRACE) System.out.println("improvement below " + minImprovement);
|
||||
if (mutator.getSigma() < stepSizeThreshold) { // reinit!
|
||||
if ((localSearchMethod != PostProcessMethod.hillClimber) || (mutator.getSigma() < stepSizeThreshold)) { // reinit!
|
||||
// is performed for nm and cma, and if hc has too low sigma
|
||||
if (TRACE) System.out.println("REINIT!!");
|
||||
// store results
|
||||
mutator.setSigma(initialStepSize);
|
||||
|
||||
if (localSearchMethod == PostProcessMethod.hillClimber) mutator.setSigma(initialStepSize);
|
||||
|
||||
// store results
|
||||
archive.SetFunctionCalls(m_Population.getFunctionCalls());
|
||||
archive.addPopulation(m_Population);
|
||||
|
||||
@ -171,7 +180,8 @@ public class ClusteringHillClimbing implements InterfacePopulationChangedEventLi
|
||||
m_Population.addPopulation(tmpPop);
|
||||
m_Population.incrFunctionCallsBy(tmpPop.size());
|
||||
|
||||
} else { // decrease step size
|
||||
} else { // decrease step size for hc
|
||||
if (localSearchMethod != PostProcessMethod.hillClimber) System.err.println("Invalid case in ClusteringHillClimbing!");
|
||||
mutator.setSigma(mutator.getSigma()*reduceFactor);
|
||||
if (TRACE) System.out.println("mutation stepsize reduced to " + mutator.getSigma());
|
||||
}
|
||||
@ -249,18 +259,18 @@ public class ClusteringHillClimbing implements InterfacePopulationChangedEventLi
|
||||
/**
|
||||
* @return the hcEvalCycle
|
||||
*/
|
||||
public int getHcEvalCycle() {
|
||||
public int getEvalCycle() {
|
||||
return hcEvalCycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hcEvalCycle the hcEvalCycle to set
|
||||
*/
|
||||
public void setHcEvalCycle(int hcEvalCycle) {
|
||||
public void setEvalCycle(int hcEvalCycle) {
|
||||
this.hcEvalCycle = hcEvalCycle;
|
||||
}
|
||||
|
||||
public String hcEvalCycleTipText() {
|
||||
public String evalCycleTipText() {
|
||||
return "The number of evaluations between two clustering/adaption steps.";
|
||||
}
|
||||
|
||||
@ -369,7 +379,19 @@ public class ClusteringHillClimbing implements InterfacePopulationChangedEventLi
|
||||
}
|
||||
|
||||
public String stepSizeInitialTipText() {
|
||||
return "Initial mutation step size, relative to the problem range.";
|
||||
return "Initial mutation step size for hill climbing, relative to the problem range.";
|
||||
}
|
||||
|
||||
public PostProcessMethod getLocalSearchMethod() {
|
||||
return localSearchMethod;
|
||||
}
|
||||
|
||||
public void setLocalSearchMethod(PostProcessMethod localSearchMethod) {
|
||||
this.localSearchMethod = localSearchMethod;
|
||||
}
|
||||
|
||||
public String localSearchMethodTipText() {
|
||||
return "Set the method to be used for local search";
|
||||
}
|
||||
|
||||
// /**
|
||||
|
@ -114,8 +114,8 @@ public class EvolutionStrategyIPOP extends EvolutionStrategies implements Interf
|
||||
* Reinitialize population with increased mu,lambda
|
||||
**/
|
||||
private void boostPopSize() {
|
||||
// increase by at least one
|
||||
int newLambda = Math.max((int)(getLambda()*incPopSizeFact), getLambda() + 1);
|
||||
// potentially increase pop size, increase by at least one if the factor is > 1.
|
||||
int newLambda = Math.max((int)(getLambda()*incPopSizeFact), getLambda() + ((incPopSizeFact > 1.) ? 1 : 0));
|
||||
setLambda(newLambda);
|
||||
checkPopulationConstraints();
|
||||
// update the stagnation time in the terminator
|
||||
|
@ -3,6 +3,8 @@ package eva2.server.go.strategies;
|
||||
import java.io.Serializable;
|
||||
import java.util.Vector;
|
||||
|
||||
import com.sun.org.apache.bcel.internal.generic.CHECKCAST;
|
||||
|
||||
import eva2.OptimizerFactory;
|
||||
import eva2.OptimizerRunnable;
|
||||
import eva2.gui.BeanInspector;
|
||||
@ -17,10 +19,12 @@ import eva2.server.go.problems.AbstractOptimizationProblem;
|
||||
import eva2.server.go.problems.AbstractProblemDouble;
|
||||
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
||||
import eva2.server.stat.StatsParameter;
|
||||
import eva2.tools.Mathematics;
|
||||
|
||||
/**
|
||||
* Nelder-Mead-Simplex does not guarantee an equal number of evaluations within each optimize call
|
||||
* because of the different step types.
|
||||
* Range check is now available by projection at the bounds.
|
||||
*
|
||||
* @author mkron
|
||||
*
|
||||
@ -35,6 +39,7 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
private AbstractOptimizationProblem m_Problem;
|
||||
private transient Vector<InterfacePopulationChangedEventListener> m_Listener;
|
||||
private String m_Identifier = "NelderMeadSimplex";
|
||||
private boolean checkConstraints = true;
|
||||
|
||||
public NelderMeadSimplex() {
|
||||
setPopulation(new Population(populationSize));
|
||||
@ -52,10 +57,8 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
return new NelderMeadSimplex(this);
|
||||
}
|
||||
|
||||
|
||||
public void SetIdentifier(String name) {
|
||||
m_Identifier = name;
|
||||
|
||||
}
|
||||
|
||||
public void SetProblem(InterfaceOptimizationProblem problem) {
|
||||
@ -85,31 +88,44 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
|
||||
public void freeWilly() {}
|
||||
|
||||
protected double[] calcChallengeVect(double[] centroid, double[] refX) {
|
||||
double[] r = new double[centroid.length];
|
||||
for (int i=0; i<r.length; i++) r[i] = 2*centroid[i] - refX[i];
|
||||
// double alpha = 1.3;
|
||||
// for (int i=0; i<r.length; i++) r[i] = centroid[i] + alpha*(centroid[i] - refX[i]);
|
||||
return r;
|
||||
}
|
||||
|
||||
public AbstractEAIndividual simplexStep(Population subpop) {
|
||||
// parameter
|
||||
|
||||
|
||||
// hole die n-1 besten individuen
|
||||
Population bestpop = subpop.getBestNIndividuals(subpop.size()-1);
|
||||
// und das schlechteste
|
||||
AbstractEAIndividual worst = subpop.getWorstEAIndividual();
|
||||
AbstractEAIndividual best=subpop.getBestEAIndividual();
|
||||
double[] u_q = ((InterfaceDataTypeDouble) worst).getDoubleData();
|
||||
int dim = u_q.length;
|
||||
|
||||
double[][] range = ((InterfaceDataTypeDouble) worst).getDoubleRange();
|
||||
double[] x_worst = ((InterfaceDataTypeDouble) worst).getDoubleData();
|
||||
int dim = x_worst.length;
|
||||
|
||||
// Centroid berechnen
|
||||
double[] g = new double[dim];
|
||||
double[] centroid = new double[dim];
|
||||
for (int i=0; i<bestpop.size(); i++) {
|
||||
for (int j=0; j<dim; j++) {
|
||||
AbstractEAIndividual bestIndi= (AbstractEAIndividual) bestpop.getIndividual(i);
|
||||
g[j] +=((InterfaceDataTypeDouble)bestIndi).getDoubleData()[j]/bestpop.size(); // bug?
|
||||
centroid[j] +=((InterfaceDataTypeDouble)bestIndi).getDoubleData()[j]/bestpop.size(); // bug?
|
||||
}
|
||||
}
|
||||
|
||||
// Reflection
|
||||
double[] r = new double[dim];
|
||||
for (int i=0; i<dim; i++)
|
||||
r[i] = 2*g[i] - u_q[i];
|
||||
double[] r = calcChallengeVect(centroid, x_worst);
|
||||
|
||||
if (checkConstraints) {
|
||||
if (!Mathematics.isInRange(r, range)) {
|
||||
Mathematics.reflectBounds(r, range);
|
||||
}
|
||||
}
|
||||
AbstractEAIndividual r_ind = (AbstractEAIndividual)((AbstractEAIndividual)bestpop.getIndividual(1)).clone();
|
||||
((InterfaceDataTypeDouble)r_ind).SetDoubleGenotype(r);
|
||||
|
||||
@ -122,7 +138,9 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
} else if (best.getFitness(0)>r_ind.getFitness(0)){ //neues besser als bisher bestes => Expansion
|
||||
|
||||
double[] e = new double[dim];
|
||||
for (int i=0; i<dim; i++) e[i] = 3*g[i] - 2*u_q[i];
|
||||
for (int i=0; i<dim; i++) e[i] = 3*centroid[i] - 2*x_worst[i];
|
||||
if (checkConstraints && !Mathematics.isInRange(e, range)) Mathematics.projectToRange(e, range);
|
||||
|
||||
AbstractEAIndividual e_ind = (AbstractEAIndividual)((AbstractEAIndividual)bestpop.getIndividual(1)).clone();
|
||||
((InterfaceDataTypeDouble)e_ind).SetDoubleGenotype(e);
|
||||
m_Problem.evaluate(e_ind);
|
||||
@ -135,7 +153,9 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
|
||||
} else if(r_ind.getFitness(0) >= bestpop.getWorstEAIndividual().getFitness(0)){//kontrahiere da neues indi keine verbesserung brachte
|
||||
double[] c = new double[dim];
|
||||
for (int i=0; i<dim; i++) c[i] = 0.5*g[i] + 0.5*u_q[i];
|
||||
for (int i=0; i<dim; i++) c[i] = 0.5*centroid[i] + 0.5*x_worst[i];
|
||||
if (checkConstraints && !Mathematics.isInRange(c, range)) Mathematics.projectToRange(c, range);
|
||||
|
||||
AbstractEAIndividual c_ind = (AbstractEAIndividual)((AbstractEAIndividual)bestpop.getIndividual(1)).clone();
|
||||
((InterfaceDataTypeDouble)c_ind).SetDoubleGenotype(c);
|
||||
m_Problem.evaluate(c_ind);
|
||||
@ -152,11 +172,11 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "NelderMeadSimplex";
|
||||
return m_Identifier;
|
||||
}
|
||||
|
||||
public String globalInfo() {
|
||||
return m_Identifier;
|
||||
return "The Nelder-Mead simplex search algorithm for local search. Reflection is used as constra";
|
||||
}
|
||||
|
||||
public Population getPopulation() {
|
||||
@ -182,6 +202,7 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
|
||||
public void initByPopulation(Population pop, boolean reset) {
|
||||
setPopulation(pop);
|
||||
pop.addPopulationChangedEventListener(this);
|
||||
if (reset) {
|
||||
m_Problem.initPopulation(m_Population);
|
||||
m_Problem.evaluate(m_Population);
|
||||
@ -205,6 +226,15 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
do {
|
||||
AbstractEAIndividual ind = simplexStep(m_Population);
|
||||
if(ind!=null){ //Verbesserung gefunden
|
||||
double[] x=((InterfaceDataTypeDouble)ind).getDoubleData();
|
||||
double[][] range = ((InterfaceDataTypeDouble)ind).getDoubleRange();
|
||||
if (!Mathematics.isInRange(x, range)) {
|
||||
System.err.println("WARNING: nelder mead step produced indy out of range!");
|
||||
// Mathematics.projectToRange(x, range);
|
||||
// ((InterfaceDataTypeDouble)ind).SetDoubleGenotype(x);
|
||||
// m_Problem.evaluate(ind);
|
||||
// this.m_Population.incrFunctionCalls();
|
||||
}
|
||||
m_Population.set(m_Population.getIndexOfWorstIndividual(), ind);
|
||||
}else{//keine Verbesserung gefunden shrink!!
|
||||
|
||||
@ -342,6 +372,9 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
public static Population createNMSPopulation(AbstractEAIndividual candidate, double perturbRatio, double[][] range, boolean includeCand) {
|
||||
Population initPop = new Population();
|
||||
if (includeCand) initPop.add(candidate);
|
||||
if (perturbRatio >= 1. || (perturbRatio <= 0.)) {
|
||||
System.err.println("Warning: perturbation ratio should lie between 0 and 1! (NelderMeadSimplex:createNMSPopulation)");
|
||||
}
|
||||
addPerturbedPopulation(perturbRatio, initPop, range, candidate);
|
||||
return initPop;
|
||||
}
|
||||
@ -362,45 +395,6 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
}
|
||||
initialPop.setPopulationSize(initialPop.size());
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Search for a local optimizer using nelder mead and return the solution found and the number of steps
|
||||
// * (evaluations) actually performed.
|
||||
// *
|
||||
// * @param candidate
|
||||
// * @param problem
|
||||
// * @param term
|
||||
// * @param perturbationRatio
|
||||
// * @return
|
||||
// */
|
||||
// public static int processWithNMS(Population candidates, AbstractOptimizationProblem problem, InterfaceTerminator term, double perturbationRatio) {
|
||||
// NelderMeadSimplex nms = new NelderMeadSimplex();
|
||||
// nms.setProblemAndPopSize(problem);
|
||||
// nms.setGenerationCycle(5);
|
||||
// nms.initByPopulation(candidates, false);
|
||||
// int funCallsBefore = candidates.getFunctionCalls();
|
||||
// candidates.SetFunctionCalls(0);
|
||||
//
|
||||
// OptimizerRunnable hcRunnable = new OptimizerRunnable(OptimizerFactory.makeParams(nms, candidates, problem, 0, term), true);
|
||||
// // as nms creates a new population and has already evaluated them, send a signal to stats
|
||||
// hcRunnable.getStats().createNextGenerationPerformed(nms.getPopulation(), null);
|
||||
// hcRunnable.getGOParams().setDoPostProcessing(false);
|
||||
// hcRunnable.setVerbosityLevel(StatsParameter.VERBOSITY_NONE);
|
||||
// hcRunnable.run();
|
||||
// hcRunnable.getGOParams().setDoPostProcessing(true);
|
||||
// hcRunnable = null;
|
||||
// int funCallsDone = candidates.getFunctionCalls();
|
||||
// candidates.SetFunctionCalls(funCallsBefore+funCallsDone);
|
||||
//
|
||||
// return funCallsDone;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @return the generationCycle
|
||||
// */
|
||||
// public int getGenerationCycle() {
|
||||
// return generationCycle;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @param generationCycle the generationCycle to set
|
||||
@ -408,13 +402,17 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
public void setGenerationCycle(int generationCycle) {
|
||||
this.generationCycle = generationCycle;
|
||||
}
|
||||
|
||||
public boolean isCheckRange() {
|
||||
return checkConstraints;
|
||||
}
|
||||
|
||||
public void setCheckRange(boolean checkRange) {
|
||||
this.checkConstraints = checkRange;
|
||||
}
|
||||
|
||||
//
|
||||
// public static final GOParameters standardNMS(AbstractOptimizationProblem problem) {
|
||||
// NelderMeadSimplex nms = NelderMeadSimplex.createNelderMeadSimplex(problem, null);
|
||||
// Population pop = new Population();
|
||||
// pop.setPopulationSize(nms.getPopulationSize());
|
||||
//
|
||||
// return makeParams(nms, pop, problem, randSeed, defaultTerminator());
|
||||
// }
|
||||
public String checkRangeTipText() {
|
||||
return "Mark to check range constraints by reflection/projection";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
if (a.algType != null)
|
||||
this.algType = (SelectedTag)a.algType.clone();
|
||||
this.m_Population = (Population)a.m_Population.clone();
|
||||
this.m_Problem = (InterfaceOptimizationProblem)a.m_Problem.clone();
|
||||
this.m_Problem = a.m_Problem;
|
||||
this.m_Identifier = a.m_Identifier;
|
||||
this.m_InitialVelocity = a.m_InitialVelocity;
|
||||
this.m_SpeedLimit = a.m_SpeedLimit;
|
||||
@ -169,8 +169,9 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
* Set the initial random velocity vector.
|
||||
*
|
||||
* @param indy the individual to work on
|
||||
* @param initialV initial velocity relative to the range
|
||||
*/
|
||||
protected void initIndividualDefaults(AbstractEAIndividual indy) {
|
||||
public static void initIndividualDefaults(AbstractEAIndividual indy, double initialV) {
|
||||
double[] writeData;
|
||||
// init velocity
|
||||
writeData = new double[((InterfaceDataTypeDouble)indy).getDoubleData().length];
|
||||
@ -181,7 +182,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
//sum = Math.sqrt(sum);
|
||||
double relSpeed = getRelativeSpeed(writeData, ((InterfaceDataTypeDouble)indy).getDoubleRange());
|
||||
for (int j = 0; j < writeData.length; j++) {
|
||||
writeData[j] = (writeData[j]/relSpeed)*this.m_InitialVelocity;
|
||||
writeData[j] = (writeData[j]/relSpeed)*initialV;
|
||||
}
|
||||
indy.putData(partTypeKey, defaultType);
|
||||
indy.putData(partVelKey, writeData);
|
||||
@ -192,7 +193,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
*
|
||||
* @param indy the individual to work on
|
||||
*/
|
||||
protected void initIndividualMemory(AbstractEAIndividual indy) {
|
||||
protected static void initIndividualMemory(AbstractEAIndividual indy) {
|
||||
// init best fitness
|
||||
double[] tmpD = indy.getFitness();
|
||||
double[] writeData = new double[tmpD.length];
|
||||
@ -338,6 +339,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
public double[] getPopulationVelocity(Population pop) {
|
||||
return getPopulationVelSpeed(pop, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the norm of the velocity vector relative to the problem range.
|
||||
*
|
||||
@ -345,7 +347,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
* @param range the problem range in each dimension
|
||||
* @return measure of the speed relative to the problem range
|
||||
*/
|
||||
public double getRelativeSpeed(double[] curSpeed, double[][] range) {
|
||||
public static double getRelativeSpeed(double[] curSpeed, double[][] range) {
|
||||
double sumV = 0;
|
||||
double sumR = 0;
|
||||
for (int i = 0; i < range.length; i++) {
|
||||
@ -403,7 +405,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
for (int i = 0; i < pop.size(); i++) {
|
||||
indy = (AbstractEAIndividual) pop.get(i);
|
||||
if (indy instanceof InterfaceDataTypeDouble) {
|
||||
initIndividualDefaults(indy);
|
||||
initIndividualDefaults(indy, m_InitialVelocity);
|
||||
}
|
||||
indy.putData(indexKey, i);
|
||||
indy.SetIndividualIndex(i);
|
||||
@ -470,13 +472,17 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
}
|
||||
|
||||
protected void resetIndividual(AbstractEAIndividual indy) {
|
||||
resetIndividual(indy, m_InitialVelocity);
|
||||
plotIndy(((InterfaceDataTypeDouble)indy).getDoubleData(), null, (Integer)indy.getData(indexKey));
|
||||
}
|
||||
|
||||
public static void resetIndividual(AbstractEAIndividual indy, double initialV) {
|
||||
if (indy instanceof InterfaceDataTypeDouble) {
|
||||
indy.setParents(null);
|
||||
indy.defaultInit();
|
||||
indy.putData(partTypeKey, defaultType); // turn into default type
|
||||
initIndividualDefaults(indy);
|
||||
initIndividualDefaults(indy, initialV);
|
||||
initIndividualMemory(indy);
|
||||
plotIndy(((InterfaceDataTypeDouble)indy).getDoubleData(), null, (Integer)indy.getData(indexKey));
|
||||
} else System.err.println("error, double valued individuals required for PSO");
|
||||
}
|
||||
|
||||
@ -1432,7 +1438,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
if (indy==null) {
|
||||
System.err.println("Error in PSO.setPopulation!");
|
||||
} else if (!indy.hasData(partTypeKey)) {
|
||||
initIndividualDefaults(indy);
|
||||
initIndividualDefaults(indy, m_InitialVelocity);
|
||||
initIndividualMemory(indy);
|
||||
indy.putData(indexKey, i);
|
||||
indy.SetIndividualIndex(i);
|
||||
@ -1596,7 +1602,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
public void setGOEShowProperties(Class<?> cls) {
|
||||
GenericObjectEditor.setShowProperty(cls, "topologyRange", (m_Topology.getSelectedTag().getID() < 2) || (m_Topology.getSelectedTag().getID() == 6));
|
||||
GenericObjectEditor.setShowProperty(cls, "subSwarmRadius", (m_Topology.getSelectedTag().getID() == 3));
|
||||
GenericObjectEditor.setShowProperty(cls, "subSwarmSize", (m_Topology.getSelectedTag().getID() == 3));
|
||||
GenericObjectEditor.setShowProperty(cls, "maxSubSwarmSize", (m_Topology.getSelectedTag().getID() == 3));
|
||||
GenericObjectEditor.setShowProperty(cls, "treeStruct", (m_Topology.getSelectedTag().getID() == 4));
|
||||
GenericObjectEditor.setShowProperty(cls, "treeBranchDegree", (m_Topology.getSelectedTag().getID() == 4) || (m_Topology.getSelectedTag().getID() == 5));
|
||||
GenericObjectEditor.setShowProperty(cls, "wrapTopology", (m_Topology.getSelectedTag().getID() == 0));
|
||||
@ -1718,15 +1724,15 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
return "Define the maximum distance to a swarm leader in the multi-swarm variant";
|
||||
}
|
||||
|
||||
public int getSubSwarmSize() {
|
||||
public int getMaxSubSwarmSize() {
|
||||
return maxSubSwarmSize;
|
||||
}
|
||||
|
||||
public void setSubSwarmSize(int subSize) {
|
||||
public void setMaxSubSwarmSize(int subSize) {
|
||||
maxSubSwarmSize = subSize;
|
||||
}
|
||||
|
||||
public String subSwarmSizeTipText() {
|
||||
public String maxSubSwarmSizeTipText() {
|
||||
return "Maximum size of a sub swarm. Violating particles will be reinitialized. 0 means no limit to the sub swarm size.";
|
||||
}
|
||||
|
||||
|
@ -220,14 +220,14 @@ public class PSOParameters extends AbstractGOParameters implements InterfaceGOPa
|
||||
return ((ParticleSwarmOptimization)this.m_Optimizer).subSwarmRadiusTipText();
|
||||
}
|
||||
|
||||
public int getSubSwarmSize() {
|
||||
return ((ParticleSwarmOptimization)this.m_Optimizer).getSubSwarmSize();
|
||||
public int getMaxSubSwarmSize() {
|
||||
return ((ParticleSwarmOptimization)this.m_Optimizer).getMaxSubSwarmSize();
|
||||
}
|
||||
public void setSubSwarmSize(int subSize) {
|
||||
((ParticleSwarmOptimization)this.m_Optimizer).setSubSwarmSize(subSize);
|
||||
public void setMaxSubSwarmSize(int subSize) {
|
||||
((ParticleSwarmOptimization)this.m_Optimizer).setMaxSubSwarmSize(subSize);
|
||||
}
|
||||
public String subSwarmSizeTipText() {
|
||||
return ((ParticleSwarmOptimization)this.m_Optimizer).subSwarmSizeTipText();
|
||||
public String maxSubSwarmSizeTipText() {
|
||||
return ((ParticleSwarmOptimization)this.m_Optimizer).maxSubSwarmSizeTipText();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,9 @@
|
||||
package eva2.server.modules;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import wsi.ra.jproxy.RemoteStateListener;
|
||||
import wsi.ra.math.RNG;
|
||||
import eva2.gui.BeanInspector;
|
||||
import eva2.server.go.InterfaceGOParameters;
|
||||
import eva2.server.go.InterfacePopulationChangedEventListener;
|
||||
@ -11,13 +15,12 @@ import eva2.server.go.operators.terminators.EvaluationTerminator;
|
||||
import eva2.server.go.operators.terminators.GenerationTerminator;
|
||||
import eva2.server.go.populations.Population;
|
||||
import eva2.server.go.problems.AbstractOptimizationProblem;
|
||||
import wsi.ra.math.RNG;
|
||||
import eva2.server.go.problems.InterfaceAdditionalPopulationInformer;
|
||||
import eva2.server.stat.InterfaceStatistics;
|
||||
import eva2.server.stat.InterfaceTextListener;
|
||||
import eva2.server.stat.StatisticsWithGUI;
|
||||
import eva2.tools.EVAERROR;
|
||||
import eva2.tools.EVAHELP;
|
||||
import wsi.ra.jproxy.RemoteStateListener;
|
||||
|
||||
/**
|
||||
* The Processor may run as a thread permanently (GenericModuleAdapter) and is then stopped and started
|
||||
@ -64,7 +67,7 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo
|
||||
m_Statistics = Stat;
|
||||
}
|
||||
|
||||
protected boolean isOptRunning() {
|
||||
public boolean isOptRunning() {
|
||||
return m_optRunning;
|
||||
}
|
||||
|
||||
@ -213,6 +216,9 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo
|
||||
//////////////// PP or set results without further PP
|
||||
if (isOptRunning()) {
|
||||
resultPop = performPostProcessing();
|
||||
if (resultPop==null) { // post processing disabled, so use opt. solutions
|
||||
resultPop = goParams.getOptimizer().getAllSolutions().getSolutions();
|
||||
}
|
||||
} else resultPop = goParams.getOptimizer().getAllSolutions().getSolutions();
|
||||
|
||||
}
|
||||
@ -252,9 +258,13 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo
|
||||
*/
|
||||
public void registerPopulationStateChanged(Object source, String name) {
|
||||
if (name.equals(Population.nextGenerationPerformed)) {
|
||||
// System.out.println(getGOParams().getOptimizer().getPopulation().getFunctionCalls() + " " + getGOParams().getOptimizer().getPopulation().getBestFitness()[0]);
|
||||
Vector informerList = new Vector<InterfaceAdditionalPopulationInformer>(2);
|
||||
informerList.add(this.goParams.getProblem());
|
||||
if (this.goParams.getOptimizer() instanceof InterfaceAdditionalPopulationInformer) informerList.add(this.goParams.getOptimizer());
|
||||
m_Statistics.createNextGenerationPerformed(
|
||||
(PopulationInterface)this.goParams.getOptimizer().getPopulation(),
|
||||
this.goParams.getProblem());
|
||||
informerList);
|
||||
if (m_ListenerModule != null) {
|
||||
m_ListenerModule.updateProgress(
|
||||
getStatusPercent(
|
||||
|
@ -236,14 +236,20 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
return (resultOut != null) || (textListeners.size()>0);
|
||||
}
|
||||
|
||||
protected String getOutputHeader(InterfaceAdditionalPopulationInformer informer, PopulationInterface pop) {
|
||||
protected String getOutputHeader(List<InterfaceAdditionalPopulationInformer> informerList, PopulationInterface pop) {
|
||||
|
||||
String headline = "Fit.-calls \t Best \t Mean \t Worst ";
|
||||
if ((informer == null) || !m_StatsParams.isOutputAdditionalInfo()) {
|
||||
if ((informerList == null) || !m_StatsParams.isOutputAdditionalInfo()) {
|
||||
return headline;
|
||||
} else return headline + "\t " + informer.getAdditionalFileStringHeader(pop);
|
||||
} else {
|
||||
for (InterfaceAdditionalPopulationInformer informer : informerList) {
|
||||
headline = headline + "\t " + informer.getAdditionalFileStringHeader(pop);
|
||||
}
|
||||
return headline;
|
||||
}
|
||||
}
|
||||
|
||||
protected String getOutputLine(InterfaceAdditionalPopulationInformer informer, PopulationInterface pop) {
|
||||
protected String getOutputLine(List<InterfaceAdditionalPopulationInformer> informerList, PopulationInterface pop) {
|
||||
StringBuffer sbuf = new StringBuffer(Integer.toString(functionCalls));
|
||||
sbuf.append(" \t ");
|
||||
sbuf.append(BeanInspector.toString(currentBestFit));
|
||||
@ -255,9 +261,11 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
sbuf.append(" \t ");
|
||||
sbuf.append(BeanInspector.toString(currentWorstFit));
|
||||
} else sbuf.append(" # \t");
|
||||
if (informer != null && m_StatsParams.isOutputAdditionalInfo()) {
|
||||
sbuf.append(" \t ");
|
||||
sbuf.append(informer.getAdditionalFileStringValue(pop));
|
||||
if (informerList != null && m_StatsParams.isOutputAdditionalInfo()) {
|
||||
for (InterfaceAdditionalPopulationInformer informer : informerList) {
|
||||
sbuf.append(" \t ");
|
||||
sbuf.append(informer.getAdditionalFileStringValue(pop));
|
||||
}
|
||||
}
|
||||
return sbuf.toString();
|
||||
}
|
||||
@ -289,7 +297,7 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
* @param pop
|
||||
* @param informer
|
||||
*/
|
||||
public abstract void plotSpecificData(PopulationInterface pop, InterfaceAdditionalPopulationInformer informer);
|
||||
public abstract void plotSpecificData(PopulationInterface pop, List<InterfaceAdditionalPopulationInformer> informerList);
|
||||
|
||||
protected abstract void plotCurrentResults();
|
||||
|
||||
@ -303,16 +311,16 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
*
|
||||
*/
|
||||
public synchronized void createNextGenerationPerformed(PopulationInterface
|
||||
pop, InterfaceAdditionalPopulationInformer informer) {
|
||||
pop, List<InterfaceAdditionalPopulationInformer> informerList) {
|
||||
if (firstPlot) {
|
||||
initPlots(m_StatsParams.getPlotDescriptions());
|
||||
// if (doTextOutput()) printToTextListener(getOutputHeader(informer, pop)+'\n');
|
||||
firstPlot = false;
|
||||
}
|
||||
if ((runIterCnt==0) && printHeaderByVerbosity()) printToTextListener(getOutputHeader(informer, pop)+'\n');
|
||||
if ((runIterCnt==0) && printHeaderByVerbosity()) printToTextListener(getOutputHeader(informerList, pop)+'\n');
|
||||
|
||||
if (pop.getSpecificData() != null) {
|
||||
plotSpecificData(pop, informer);
|
||||
plotSpecificData(pop, informerList);
|
||||
return;
|
||||
}
|
||||
// by default plotting only the best
|
||||
@ -361,7 +369,7 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
}
|
||||
// meanCollection.set(pop.getGenerations()-1, means);
|
||||
|
||||
if (doTextOutput() && printLineByVerbosity(runIterCnt)) printToTextListener(getOutputLine(informer, pop)+'\n');
|
||||
if (doTextOutput() && printLineByVerbosity(runIterCnt)) printToTextListener(getOutputLine(informerList, pop)+'\n');
|
||||
plotCurrentResults();
|
||||
|
||||
runIterCnt++;
|
||||
|
@ -12,8 +12,9 @@ package eva2.server.stat;
|
||||
/*==========================================================================*
|
||||
* IMPORTS
|
||||
*==========================================================================*/
|
||||
import java.util.List;
|
||||
|
||||
import eva2.server.go.IndividualInterface;
|
||||
import eva2.server.go.InterfaceGOParameters;
|
||||
import eva2.server.go.PopulationInterface;
|
||||
import eva2.server.go.problems.InterfaceAdditionalPopulationInformer;
|
||||
/*==========================================================================*
|
||||
@ -34,7 +35,7 @@ public interface InterfaceStatistics {
|
||||
public void addTextListener(InterfaceTextListener listener);
|
||||
public boolean removeTextListener(InterfaceTextListener listener);
|
||||
public void printToTextListener(String s);
|
||||
public void createNextGenerationPerformed(PopulationInterface Pop, InterfaceAdditionalPopulationInformer informer);
|
||||
public void createNextGenerationPerformed(PopulationInterface Pop, List<InterfaceAdditionalPopulationInformer> informerList);
|
||||
public void createNextGenerationPerformed(double[] bestfit,double[] worstfit,int calls);
|
||||
public InterfaceStatisticsParameter getStatisticsParameter(); // called from moduleadapter
|
||||
public IndividualInterface getBestSolution(); // returns the best overall solution
|
||||
|
@ -1,5 +1,7 @@
|
||||
package eva2.server.stat;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import eva2.server.go.IndividualInterface;
|
||||
import eva2.server.go.PopulationInterface;
|
||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
@ -35,7 +37,7 @@ public class StatisticsDummy implements InterfaceStatistics, InterfaceTextListen
|
||||
}
|
||||
|
||||
public void createNextGenerationPerformed(PopulationInterface pop,
|
||||
InterfaceAdditionalPopulationInformer informer) {
|
||||
List<InterfaceAdditionalPopulationInformer> informerList) {
|
||||
bestCurrentIndividual = (AbstractEAIndividual)pop.getBestIndividual();
|
||||
if ((bestIndividualAllover == null) || (AbstractStatistics.secondIsBetter(bestIndividualAllover, bestCurrentIndividual))) {
|
||||
bestIndividualAllover = bestCurrentIndividual;
|
||||
|
@ -90,7 +90,7 @@ public class StatisticsStandalone extends AbstractStatistics implements Interfac
|
||||
((ArrayList<double[]>[]) m_Result.get(0))[optRunsPerformed].add(new double[] {functionCalls, currentBestFit[0]});
|
||||
}
|
||||
|
||||
public void plotSpecificData(PopulationInterface pop, InterfaceAdditionalPopulationInformer informer) {
|
||||
public void plotSpecificData(PopulationInterface pop, List<InterfaceAdditionalPopulationInformer> informerList) {
|
||||
if (TRACE) System.out.println(" m_SpecificData !!");
|
||||
double[] specificData = pop.getSpecificData();
|
||||
if (specificData != null) {
|
||||
|
@ -241,7 +241,7 @@ public class StatisticsWithGUI extends AbstractStatistics implements Serializabl
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void plotSpecificData(PopulationInterface pop, InterfaceAdditionalPopulationInformer informer) {
|
||||
public void plotSpecificData(PopulationInterface pop, List<InterfaceAdditionalPopulationInformer> informer) {
|
||||
double[] specificData = pop.getSpecificData();
|
||||
int calls = pop.getFunctionCalls();
|
||||
ArrayList<String[]> description = new ArrayList<String[]>();
|
||||
|
@ -727,4 +727,66 @@ public class Mathematics {
|
||||
}
|
||||
return viols;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the average length of the range intervals over all dimensions.
|
||||
*
|
||||
* @param range
|
||||
* @return the average length of the range intervals
|
||||
*/
|
||||
public static double getAvgRange(double[][] range) {
|
||||
double sum = 0.;
|
||||
for (int i=0; i<range.length; i++) sum+=(range[i][1]-range[i][0]);
|
||||
return sum/range.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reflect the entries of x which violate the bounds to within the range.
|
||||
* Return the number of violating dimensions.
|
||||
*
|
||||
* @param x
|
||||
* @param range
|
||||
* @return the number of violating dimensions
|
||||
*/
|
||||
public static int reflectBounds(double[] x, double[][] range) {
|
||||
int viols=0;
|
||||
double d = 0.;
|
||||
for (int i=0; i<x.length; i++) {
|
||||
double dimLen = range[i][1]-range[i][0];
|
||||
if (dimLen <= 0.) System.err.println("Error in reflectBounds: empty range!");
|
||||
if (x[i]<range[i][0]) {
|
||||
viols++;
|
||||
d = range[i][0]-x[i];
|
||||
while (d > dimLen) d -= dimLen; // avoid violating the other bound immediately
|
||||
x[i]=range[i][0]+d;
|
||||
} else if (x[i]>range[i][1]) {
|
||||
viols++;
|
||||
d = x[i]-range[i][1];
|
||||
while (d>dimLen) d -= dimLen; // avoid violating the other bound immediately
|
||||
x[i]=range[i][1]-d;
|
||||
}
|
||||
}
|
||||
return viols;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple version of reflection of a value moving by a step and bouncing
|
||||
* of min and max values like a pool ball. Precondition is min <= val <= max,
|
||||
* post condition is min <= retVal <= max.
|
||||
*
|
||||
* @param val
|
||||
* @param step
|
||||
* @param min
|
||||
* @param max
|
||||
* @return
|
||||
*/
|
||||
public static double reflectValue(double val, double step, double min, double max) {
|
||||
while (step > (max-min)) step -= (max-min);
|
||||
if ((val + step) > max)
|
||||
return (2 * max - val - step);
|
||||
if ((val + step) < min)
|
||||
return (2 * min - val - step);
|
||||
return (val += step);
|
||||
}
|
||||
}
|
||||
|
@ -73,8 +73,9 @@ public class SelectedTag implements java.io.Serializable {
|
||||
*
|
||||
* @param i The new selected tag index
|
||||
*/
|
||||
public void setSelectedTag(int i) {
|
||||
public SelectedTag setSelectedTag(int i) {
|
||||
if ((i >= 0) && (i < this.m_Tags.length)) this.m_Selected = i;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,14 +85,15 @@ public class SelectedTag implements java.io.Serializable {
|
||||
*
|
||||
* @param str The new selected tag name
|
||||
*/
|
||||
public void setSelectedTag(String str) {
|
||||
public SelectedTag setSelectedTag(String str) {
|
||||
for (int i=0; i<m_Tags.length; i++) {
|
||||
if (m_Tags[i].m_String.compareTo(str) == 0) {
|
||||
m_Selected = i;
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
System.err.println("Warning, trying to select unknown string (SelectedTag::setSelectedTag(String)");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user