Merging MK rev. 227 - several minor changes.

This commit is contained in:
Marcel Kronfeld 2008-12-10 09:56:15 +00:00
parent 245d8892ef
commit 302ca1e02b
37 changed files with 1325 additions and 639 deletions

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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

View File

@ -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) {}
}
}

View File

@ -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();

View File

@ -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() {

View File

@ -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) {

View File

@ -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.;

View File

@ -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);
}
}

View File

@ -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() {

View File

@ -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

View File

@ -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);

View File

@ -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
*/

View File

@ -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

View File

@ -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
*/

View File

@ -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.
*/

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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";
}
// /**

View File

@ -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

View File

@ -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";
}
}

View File

@ -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.";
}

View File

@ -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();
}
/**

View File

@ -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(

View File

@ -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++;

View File

@ -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

View File

@ -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;

View File

@ -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) {

View File

@ -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[]>();

View File

@ -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);
}
}

View File

@ -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;
}
/**