Merging MK branch revs. 243-249. Population sorting by fitness index, new package operators.paramcontrol for adaptive parameters, as well as minor stuff.
This commit is contained in:
parent
ac92a3a119
commit
abafb57679
@ -4,6 +4,10 @@ package eva2;
|
||||
* Main product and version information strings.
|
||||
*
|
||||
* --- Changelog
|
||||
* 2.034: Adding a generic parameter control method for optimizers, currently used by PSO to adapt inertness depending
|
||||
* on EvaluationTerminator or GenerationTerminator instances defining the number of function evaluations.
|
||||
* The new package is eva2.server.go.operators.paramcontrol.
|
||||
* A Population may now be ordered by a specific fitness criterion, employed, e.g., by Nelder-Mead-Simplex.
|
||||
* 2.033: There was an interesting problem with the Matlab-Interface, which just hung up after extensive optimization
|
||||
* loops, yet only if Matlab was started without X-forwarding (which is necessary for qsub, e.g.).
|
||||
* Debugging was tedious, since the debugging using System.out. itself caused threading deadlocks. The
|
||||
|
@ -259,7 +259,7 @@ public class OptimizerFactory {
|
||||
ga.addPopulationChangedEventListener(listener);
|
||||
ga.init();
|
||||
|
||||
listener.registerPopulationStateChanged(ga.getPopulation(), "");
|
||||
if (listener!=null) listener.registerPopulationStateChanged(ga.getPopulation(), "");
|
||||
|
||||
return ga;
|
||||
}
|
||||
|
@ -536,7 +536,19 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
||||
this.m_Fitness[index] = fitness;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method will set the fitness of the individual to the given value in every component.
|
||||
* If the fitness was null, nothing will be done.
|
||||
*
|
||||
* @param resetVal The new fitness array
|
||||
*/
|
||||
public void resetFitness(double resetVal) {
|
||||
if (m_Fitness!=null) {
|
||||
for (int i=0; i<m_Fitness.length; i++) m_Fitness[i]=resetVal;
|
||||
}
|
||||
}
|
||||
|
||||
/** This method will check the constraints imposed by the separation schemes
|
||||
* for parallelizing MOEAs
|
||||
*/
|
||||
|
@ -0,0 +1,67 @@
|
||||
package eva2.server.go.operators.paramcontrol;
|
||||
|
||||
import eva2.gui.BeanInspector;
|
||||
|
||||
/**
|
||||
* Convenience class. Besides the init() method, two more remain to be implemented:
|
||||
* the first one to retrieve an array of strings with the canonical names of the controlled parameters,
|
||||
* and the second one to produce an object array of the same length with the values to be assigned
|
||||
* at the iteration. If there is no iteration known, iteration counts will be set to -1.
|
||||
*
|
||||
* @author mkron
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractParameterControl implements InterfaceParameterControl {
|
||||
public Object[] initialValues = null;
|
||||
protected static boolean TRACE=true;
|
||||
|
||||
public void init(Object obj) {
|
||||
String[] params = getControlledParameters();
|
||||
if (params != null) {
|
||||
initialValues=new Object[params.length];
|
||||
for (int i=0; i<params.length; i++) initialValues[i]=BeanInspector.getMem(obj, params[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void finish(Object obj) {
|
||||
String[] params = getControlledParameters();
|
||||
if (params != null) {
|
||||
for (int i=0; i<params.length; i++) BeanInspector.setMem(obj, params[i], initialValues[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateParameters(Object obj, int iteration, int maxIteration) {
|
||||
String[] params = getControlledParameters();
|
||||
Object[] vals = getValues(obj, iteration, maxIteration);
|
||||
for (int i=0; i<params.length; i++) {
|
||||
if (!BeanInspector.setMem(obj, params[i], vals[i])) {
|
||||
System.err.println("Error: failed to set parameter from parameter control " + this.getClass().getName());;
|
||||
System.err.println(" Tried to set name/val: " + params[i] + " / " + BeanInspector.toString(vals[i]));
|
||||
} else {
|
||||
if (TRACE) System.out.println("Successfully set " + params[i] + " / " + BeanInspector.toString(vals[i]) + " at " + iteration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateParameters(Object obj) {
|
||||
updateParameters(obj, -1, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a String array of canonical names of the parameters to be adapted.
|
||||
*
|
||||
* @return a String array of canonical names of the parameters to be adapted
|
||||
*/
|
||||
public abstract String[] getControlledParameters();
|
||||
|
||||
/**
|
||||
* Retrieve the values of the adaptable parameters at a given iteration.
|
||||
* If the maximum iteration is not known, both iteration and maxIteration will be set to -1.
|
||||
*
|
||||
* @param obj The instance which is controlled
|
||||
* @param iteration current iteration (or -1 if unknown)
|
||||
* @param maxIteration maximum iteration count (or -1 if unknown)
|
||||
* @return
|
||||
*/
|
||||
public abstract Object[] getValues(Object obj, int iteration, int maxIteration);
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
package eva2.server.go.operators.paramcontrol;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import eva2.server.go.strategies.ParticleSwarmOptimization;
|
||||
import eva2.tools.Mathematics;
|
||||
|
||||
/**
|
||||
* After the ANTS 08 paper by Yasuda et al., this implements an activity feedback control mechanism.
|
||||
* The inertia of the PSO is made dependent on time and the target activity of the swarm, where activity
|
||||
* here is simply the average relative velocity of the particles.
|
||||
* The target activity decreases with time, and if the current activity is too low (high), the
|
||||
* inertia is increased (decreased) so that the activity approximates the target activity.
|
||||
*
|
||||
* The original authors used an absolute velocity measure and FIPS which is not implemented in EvA2 so far.
|
||||
* However, after some initial tests, this version seems
|
||||
* to work ok, although it depends on the defined target activity. I am not convinced that in general it is
|
||||
* easier to define than a constant constriction factor for the standard constricted PSO.
|
||||
* Still, the possibility to control the convergence behaviour based on time is nice, and it works quite good on F6, for example.
|
||||
*
|
||||
* @author mkron
|
||||
*
|
||||
*/
|
||||
public class ActivityFeedbackControl extends AbstractParameterControl implements Serializable {
|
||||
private double minInert=0.5;
|
||||
private double maxInert=1;
|
||||
private double startAct=0.17;
|
||||
private double endAct=0;
|
||||
private double deltaInertness = 0.1;
|
||||
|
||||
private static String[] params = new String[]{"inertnessOrChi"};
|
||||
|
||||
@Override
|
||||
public String[] getControlledParameters() {
|
||||
return params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getValues(Object obj, int iteration, int maxIteration) {
|
||||
if (obj instanceof ParticleSwarmOptimization) {
|
||||
ParticleSwarmOptimization pso = (ParticleSwarmOptimization)obj;
|
||||
Object[] vals = new Double[1];
|
||||
double currentAct = calculateActivity(pso);
|
||||
double currentInertness = pso.getInertnessOrChi();
|
||||
vals[0] = calcNewInertness(currentInertness, currentAct, desiredActivity(iteration, maxIteration));
|
||||
return vals;
|
||||
} else {
|
||||
System.err.println("Cant control this object type!!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private double calcNewInertness(double currentInertness, double currentAct,
|
||||
double desiredActivity) {
|
||||
if (TRACE) System.out.println("Activity was " + currentAct + ", desired: " + desiredActivity);
|
||||
if (currentAct < desiredActivity) { // increase inertness
|
||||
return Math.min(maxInert, currentInertness + deltaInertness);
|
||||
} else if (currentAct > desiredActivity) { // too high act, so decrease inertness
|
||||
return Math.max(minInert, currentInertness - deltaInertness);
|
||||
} else return currentInertness;
|
||||
}
|
||||
|
||||
private double desiredActivity(int iteration, int maxIteration) {
|
||||
return Mathematics.linearInterpolation(iteration, 0, maxIteration, startAct, endAct);
|
||||
}
|
||||
|
||||
private double calculateActivity(ParticleSwarmOptimization pso) {
|
||||
return pso.getPopulationAvgNormedVelocity(pso.getPopulation());
|
||||
}
|
||||
|
||||
public double getMinInertness() {
|
||||
return minInert;
|
||||
}
|
||||
public void setMinInertness(double minInert) {
|
||||
this.minInert = minInert;
|
||||
}
|
||||
public String minInertnessTipText() {
|
||||
return "The minimum inertness value to be used.";
|
||||
}
|
||||
|
||||
public double getMaxInertness() {
|
||||
return maxInert;
|
||||
}
|
||||
public void setMaxInertness(double maxInert) {
|
||||
this.maxInert = maxInert;
|
||||
}
|
||||
public String maxInertnessTipText() {
|
||||
return "The maximum inertness value to be used.";
|
||||
}
|
||||
|
||||
public double getInitActivity() {
|
||||
return startAct;
|
||||
}
|
||||
public void setInitActivity(double startAct) {
|
||||
this.startAct = startAct;
|
||||
}
|
||||
public String initActivityTipText() {
|
||||
return "The initial target activity (relative to the range).";
|
||||
}
|
||||
|
||||
public double getFinalActivity() {
|
||||
return endAct;
|
||||
}
|
||||
public void setFinalActivity(double endAct) {
|
||||
this.endAct = endAct;
|
||||
}
|
||||
public String finalActivityTipText() {
|
||||
return "The final target activity (relative to the range), should be close to zero.";
|
||||
}
|
||||
|
||||
public double getDeltaInertness() {
|
||||
return deltaInertness;
|
||||
}
|
||||
public void setDeltaInertness(double deltaInertness) {
|
||||
this.deltaInertness = deltaInertness;
|
||||
}
|
||||
public String deltaInertnessTipText() {
|
||||
return "The additive change of the inertness in each adaption step.";
|
||||
}
|
||||
|
||||
public String globalInfo() {
|
||||
return "Controls the inertness factor based on the average velocity.";
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package eva2.server.go.operators.paramcontrol;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import eva2.server.go.InterfaceTerminator;
|
||||
|
||||
/**
|
||||
* Dummy implementation. This class is ignored by the Processor. Parameters will not be changed.
|
||||
*
|
||||
* @author mkron
|
||||
*
|
||||
*/
|
||||
public class ConstantParameters extends AbstractParameterControl implements Serializable {
|
||||
|
||||
public String[] getControlledParameters() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getValues(Object obj, int iteration, int maxIteration) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updateParameters(Object obj) {
|
||||
}
|
||||
|
||||
public String globalInfo() {
|
||||
return "Parameters will not be changed.";
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package eva2.server.go.operators.paramcontrol;
|
||||
|
||||
import eva2.server.go.populations.Population;
|
||||
|
||||
/**
|
||||
* Interface for dynamic changes to object parameters.
|
||||
* When an optimizer has the getter method getParamControl retrieving an instance of this interface,
|
||||
* an update is triggered after every optimize call. This allows parameters of the object to be
|
||||
* adapted dynamically, such as linearly decreasing weights or control parameters. In case of PSO,
|
||||
* this may be the linearly decreasing inertia weight or the activation feedback control mechanism.
|
||||
*
|
||||
* @author mkron
|
||||
*
|
||||
*/
|
||||
public interface InterfaceParameterControl {
|
||||
/**
|
||||
* Initialize the parameter control instance before a run.
|
||||
*
|
||||
* @param obj The controlled object.
|
||||
*/
|
||||
public void init(Object obj);
|
||||
|
||||
/**
|
||||
* After an optimization run, finalizing stuff may be done.
|
||||
*
|
||||
* @param obj The controlled object.
|
||||
*/
|
||||
public void finish(Object obj);
|
||||
|
||||
/**
|
||||
* For a given runtime (maxIteration) and current iteration, update the parameters of the object.
|
||||
*
|
||||
* @param obj
|
||||
* @param iteration
|
||||
* @param maxIteration
|
||||
*/
|
||||
public void updateParameters(Object obj, int iteration, int maxIteration);
|
||||
|
||||
/**
|
||||
* If no runtime in terms of iterations can be specified, the parameter control may try to infer
|
||||
* the state from the object itself.
|
||||
*
|
||||
* @param obj
|
||||
*/
|
||||
public void updateParameters(Object obj);
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package eva2.server.go.operators.paramcontrol;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import eva2.tools.Mathematics;
|
||||
|
||||
/**
|
||||
* Adapt PSO inertness linearly by time, from given start to end value.
|
||||
* This only works if iterations are known.
|
||||
*
|
||||
* @author mkron
|
||||
*
|
||||
*/
|
||||
public class LinearInertnessAdaption extends AbstractParameterControl implements Serializable {
|
||||
String[] params = {"inertnessOrChi"};
|
||||
private double startV=0.7;
|
||||
private double endV=0.2;
|
||||
|
||||
public LinearInertnessAdaption() {
|
||||
startV=0.7;
|
||||
endV=0.2;
|
||||
}
|
||||
|
||||
public LinearInertnessAdaption(double startValue, double endValue, int functionCalls) {
|
||||
startV=startValue;
|
||||
endV=endValue;
|
||||
}
|
||||
|
||||
public String[] getControlledParameters() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public Object[] getValues(Object obj, int iteration, int maxIteration) {
|
||||
if (maxIteration < 0) { // there is no maxIteration known
|
||||
System.err.println("Not changing inertness - missing iteration information!");
|
||||
return null;
|
||||
} else {
|
||||
Object[] vals=new Object[1];
|
||||
vals[0] = new Double(calcInertness(iteration, maxIteration));
|
||||
return vals;
|
||||
}
|
||||
}
|
||||
|
||||
private double calcInertness(int iteration, int max) {
|
||||
return Mathematics.linearInterpolation(iteration, 0, max, startV, endV);
|
||||
// return startV+((endV-startV)*(iteration/(double)max));
|
||||
}
|
||||
|
||||
public double getStartVal() {
|
||||
return startV;
|
||||
}
|
||||
|
||||
public void setStartVal(double startV) {
|
||||
this.startV = startV;
|
||||
}
|
||||
|
||||
public String startValTipText() {
|
||||
return "Start value for the inertness";
|
||||
}
|
||||
|
||||
public double getEndVal() {
|
||||
return endV;
|
||||
}
|
||||
|
||||
public void setEndVal(double endV) {
|
||||
this.endV = endV;
|
||||
}
|
||||
|
||||
public String endValTipText() {
|
||||
return "End value for the inertness";
|
||||
}
|
||||
|
||||
public String globalInfo() {
|
||||
return "Linearly adapt the inertnessOrChi value of PSO";
|
||||
}
|
||||
}
|
@ -57,10 +57,12 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
private int lastQModCount = -1;
|
||||
// a sorted queue (for efficiency)
|
||||
transient private ArrayList<AbstractEAIndividual> sortedArr = null;
|
||||
private int lastFitCrit = -1;
|
||||
|
||||
// remember when the last evaluation was performed
|
||||
private Pair<Integer,Integer> evaluationTimeHashes = null;
|
||||
// private Pair<Integer,Integer> evaluationTimeHashes = null;
|
||||
// remember when the last evaluation was performed
|
||||
private int evaluationTimeModCount = -1;
|
||||
// private int evaluationTimeModCount = -1;
|
||||
|
||||
public Population() {
|
||||
}
|
||||
@ -154,8 +156,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
this.m_History = new ArrayList();
|
||||
this.m_Generation = 0;
|
||||
this.m_FunctionCalls = 0;
|
||||
evaluationTimeHashes = null;
|
||||
evaluationTimeModCount = -1;
|
||||
// evaluationTimeHashes = null;
|
||||
// evaluationTimeModCount = -1;
|
||||
if (this.m_Archive != null) {
|
||||
this.m_Archive.clear();
|
||||
this.m_Archive.init();
|
||||
@ -373,9 +375,26 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
return domSet;
|
||||
}
|
||||
|
||||
private boolean compareFit(boolean bChooseBetter, double[] fit1, double[] fit2) {
|
||||
if (bChooseBetter) return AbstractEAIndividual.isDominatingFitness(fit1, fit2);
|
||||
else return AbstractEAIndividual.isDominatingFitness(fit2, fit1);
|
||||
|
||||
/**
|
||||
* Compare two fitness vectors. If bChooseBetter is true, the function delivers the predicate
|
||||
* "first is better than second" using the fitness component indicated by fitIndex or a dominance
|
||||
* criterion if fitIndex < 0.
|
||||
*
|
||||
* @param bChooseBetter
|
||||
* @param fit1
|
||||
* @param fit2
|
||||
* @param fitIndex
|
||||
* @return
|
||||
*/
|
||||
private boolean compareFit(boolean bChooseBetter, double[] fit1, double[] fit2, int fitIndex) {
|
||||
if (fitIndex < 0) { // multiobjective case
|
||||
if (bChooseBetter) return AbstractEAIndividual.isDominatingFitness(fit1, fit2);
|
||||
else return AbstractEAIndividual.isDominatingFitness(fit2, fit1);
|
||||
} else {
|
||||
if (bChooseBetter) return fit1[fitIndex]<fit2[fitIndex];
|
||||
else return fit1[fitIndex]>fit2[fitIndex];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -387,7 +406,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
*/
|
||||
public int getIndexOfBestIndividual() {
|
||||
if (size()<1) return -1;
|
||||
return getIndexOfBestOrWorstIndividual(true, true);
|
||||
return getIndexOfBestOrWorstIndividual(true, true, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -398,7 +417,31 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
* @return The index of the best individual.
|
||||
*/
|
||||
public int getIndexOfWorstIndividual() {
|
||||
return getIndexOfBestOrWorstIndividual(false, false);
|
||||
return getIndexOfBestOrWorstIndividual(false, false, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return the index of the current best individual from the
|
||||
* population in the given fitness component (or using dominance when fitIndex < 0).
|
||||
* If the population is empty, -1 is returned.
|
||||
*
|
||||
* @see getIndexOfBestOrWorstIndividual()
|
||||
* @return The index of the best individual.
|
||||
*/
|
||||
public int getIndexOfBestIndividual(int fitIndex) {
|
||||
if (size()<1) return -1;
|
||||
return getIndexOfBestOrWorstIndividual(true, true, fitIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return the index of the current best individual from the
|
||||
* population in the given fitness component (or using dominance when fitIndex < 0).
|
||||
*
|
||||
* @see getIndexOfBestOrWorstIndividual()
|
||||
* @return The index of the best individual.
|
||||
*/
|
||||
public int getIndexOfWorstIndividual(int fitIndex) {
|
||||
return getIndexOfBestOrWorstIndividual(false, false, fitIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -412,7 +455,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
* @param indicate whether constraints should be regarded
|
||||
* @return The index of the best (worst) individual.
|
||||
*/
|
||||
public int getIndexOfBestOrWorstIndividual(boolean bBest, boolean checkConstraints) {
|
||||
public int getIndexOfBestOrWorstIndividual(boolean bBest, boolean checkConstraints, int fitIndex) {
|
||||
int result = -1;
|
||||
double[] curSelFitness = null;
|
||||
boolean allViolate = true;
|
||||
@ -420,7 +463,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
for (int i = 0; i < super.size(); i++) {
|
||||
if (!checkConstraints || !(getEAIndividual(i).violatesConstraint())) {
|
||||
allViolate = false;
|
||||
if ((result<0) || (compareFit(bBest, getEAIndividual(i).getFitness(), curSelFitness))) {
|
||||
if ((result<0) || (compareFit(bBest, getEAIndividual(i).getFitness(), curSelFitness, fitIndex))) {
|
||||
// fit i is better than remembered
|
||||
result = i;
|
||||
curSelFitness = getEAIndividual(i).getFitness(); // remember fit i
|
||||
@ -460,16 +503,28 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
* @return The best individual
|
||||
*/
|
||||
public AbstractEAIndividual getBestEAIndividual() {
|
||||
return getBestEAIndividual(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the current best individual from the population
|
||||
* by a given fitness component.
|
||||
* If the population is empty, null is returned.
|
||||
*
|
||||
* @param fitIndex the fitness criterion index or -1
|
||||
* @return The best individual
|
||||
*/
|
||||
public AbstractEAIndividual getBestEAIndividual(int fitIndex) {
|
||||
if (size()<1) return null;
|
||||
int best = this.getIndexOfBestIndividual();
|
||||
if (best == -1) {
|
||||
System.err.println("This shouldnt happen!");
|
||||
return null;
|
||||
} else {
|
||||
AbstractEAIndividual result = (AbstractEAIndividual)this.get(best);
|
||||
if (result == null) System.err.println("Serious Problem! Population Size: " + this.size());
|
||||
return result;
|
||||
}
|
||||
int best = this.getIndexOfBestIndividual(fitIndex);
|
||||
if (best == -1) {
|
||||
System.err.println("This shouldnt happen!");
|
||||
return null;
|
||||
} else {
|
||||
AbstractEAIndividual result = (AbstractEAIndividual)this.get(best);
|
||||
if (result == null) System.err.println("Serious Problem! Population Size: " + this.size());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -548,14 +603,34 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
}
|
||||
|
||||
/**
|
||||
* Avoids having to sort again in several calls without modifications in between.
|
||||
* Set a fitness criterion for sorting procedures. This also affects getBest
|
||||
* @param fitIndex
|
||||
*/
|
||||
public void setSortingFitnessCriterion(int fitIndex) {
|
||||
getSorted(fitIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reuses the last fitness criterion. Avoid having to sort again in several calls without modifications in between.
|
||||
* The returned array should not be modified!
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected ArrayList<AbstractEAIndividual> getSorted() {
|
||||
if (sortedArr == null || (super.modCount != lastQModCount)) {
|
||||
PriorityQueue<AbstractEAIndividual> sQueue = new PriorityQueue<AbstractEAIndividual>(super.size(), new AbstractEAIndividualComparator());
|
||||
return getSorted(lastFitCrit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Avoids having to sort again in several calls without modifications in between.
|
||||
* The returned array should not be modified!
|
||||
*
|
||||
* @param fitIndex the fitness criterion to be used or -1 for pareto dominance
|
||||
* @return
|
||||
*/
|
||||
protected ArrayList<AbstractEAIndividual> getSorted(int fitIndex) {
|
||||
if ((fitIndex != lastFitCrit) || (sortedArr == null) || (super.modCount != lastQModCount)) {
|
||||
lastFitCrit=fitIndex; // TODO check if this works right?
|
||||
PriorityQueue<AbstractEAIndividual> sQueue = new PriorityQueue<AbstractEAIndividual>(super.size(), new AbstractEAIndividualComparator(fitIndex));
|
||||
for (int i = 0; i < super.size(); i++) {
|
||||
AbstractEAIndividual indy = getEAIndividual(i);
|
||||
if (indy != null) sQueue.add(indy);
|
||||
@ -568,7 +643,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
}
|
||||
return sortedArr;
|
||||
}
|
||||
|
||||
|
||||
/** This method returns n random best individuals from the population.
|
||||
*
|
||||
* @param n number of individuals to look out for
|
||||
@ -635,7 +710,11 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
* @return The best individual
|
||||
*/
|
||||
public AbstractEAIndividual getWorstEAIndividual() {
|
||||
return getEAIndividual(getIndexOfWorstIndividual());
|
||||
return getWorstEAIndividual(-1);
|
||||
}
|
||||
|
||||
public AbstractEAIndividual getWorstEAIndividual(int fitIndex) {
|
||||
return getEAIndividual(getIndexOfWorstIndividual(fitIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1046,7 +1125,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
*/
|
||||
public double[] getCenterWeighted(AbstractSelProb selProb, int criterion, boolean obeyConst) {
|
||||
selProb.computeSelectionProbability(this, "Fitness", obeyConst);
|
||||
double[] mean = AbstractEAIndividual.getDoublePosition(getEAIndividual(0));
|
||||
double[] mean = AbstractEAIndividual.getDoublePosition(getEAIndividual(0)).clone();
|
||||
|
||||
if (mean != null) {
|
||||
Arrays.fill(mean, 0.);
|
||||
AbstractEAIndividual indy = null;
|
||||
|
@ -35,6 +35,7 @@ public class F2Problem extends F1Problem implements InterfaceMultimodalProblem,
|
||||
for (int i = 0; i < x.length-1; i++) {
|
||||
result[0] += (100*(x[i+1]-x[i]*x[i])*(x[i+1]-x[i]*x[i])+(x[i]-1)*(x[i]-1));
|
||||
}
|
||||
if (result[0]<=0) result[0]=Math.sqrt(Double.MIN_VALUE); // guard for plots in log scale
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package eva2.server.go.strategies;
|
||||
import java.util.Vector;
|
||||
|
||||
import wsi.ra.math.RNG;
|
||||
import eva2.gui.BeanInspector;
|
||||
import eva2.gui.GenericObjectEditor;
|
||||
import eva2.server.go.InterfacePopulationChangedEventListener;
|
||||
import eva2.server.go.enums.DETypeEnum;
|
||||
@ -329,6 +330,11 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial
|
||||
}
|
||||
|
||||
private AbstractEAIndividual getRandomIndy(Population pop) {
|
||||
if (pop.size()<1) {
|
||||
System.err.println("Error: invalid pop size in DE!");
|
||||
System.err.println("DE: \n"+ BeanInspector.toString(this) + "\nPop: \n" + BeanInspector.toString(pop));
|
||||
}
|
||||
|
||||
int randIndex = RNG.randomInt(0, pop.size()-1);
|
||||
return pop.getEAIndividual(randIndex);
|
||||
}
|
||||
@ -345,7 +351,7 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial
|
||||
public void optimize() {
|
||||
AbstractEAIndividual indy = null, org;
|
||||
int index;
|
||||
|
||||
|
||||
int nextDoomed = getNextDoomed(m_Population, 0);
|
||||
|
||||
// required for dynamic problems especially
|
||||
@ -354,7 +360,7 @@ public class DifferentialEvolution implements InterfaceOptimizer, java.io.Serial
|
||||
* MK: added aging mechanism to provide for dynamically changing problems. If an individual
|
||||
* reaches the age limit, it is doomed and replaced by the next challenge vector, even if its worse.
|
||||
*/
|
||||
|
||||
|
||||
for (int i = 0; i < this.m_Population.size(); i++) {
|
||||
indy = this.generateNewIndividual(this.m_Population);
|
||||
this.m_Problem.evaluate(indy);
|
||||
|
@ -122,7 +122,7 @@ public class DynamicParticleSwarmOptimization extends ParticleSwarmOptimization
|
||||
* @return the favourite speed limit.
|
||||
*/
|
||||
public double getFavTrackingSpeed(double[][] range) {
|
||||
return 2*getRelativeSpeed(getEMASpeed(), range);
|
||||
return 2*Mathematics.getRelativeLength(getEMASpeed(), range);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -180,13 +180,13 @@ public class DynamicParticleSwarmOptimization extends ParticleSwarmOptimization
|
||||
protected void plotIndy(double[] curPosition, double[] curVelocity, int index) {
|
||||
if (this.m_Show) {
|
||||
if (plotBestOnly) {
|
||||
return;
|
||||
// if (index != ((Integer)(m_Population.getBestEAIndividual().getData(indexKey)))) return;
|
||||
// else {
|
||||
if (index != ((Integer)(m_Population.getBestEAIndividual().getData(indexKey)))) return;
|
||||
else {
|
||||
// if (lastBestPlot != null) this.m_Plot.setConnectedPoint(lastBestPlot[0], lastBestPlot[1], index);
|
||||
// this.m_Plot.setConnectedPoint(curPosition[0], curPosition[1], index);
|
||||
// lastBestPlot = curPosition.clone();
|
||||
// }
|
||||
this.m_Plot.setUnconnectedPoint(curPosition[0], curPosition[1], index);
|
||||
lastBestPlot = curPosition.clone();
|
||||
}
|
||||
} else {
|
||||
if (curVelocity == null) {
|
||||
|
||||
@ -404,6 +404,9 @@ public class DynamicParticleSwarmOptimization extends ParticleSwarmOptimization
|
||||
System.err.println("Could not perform PSO update, because individual is not instance of InterfaceESIndividual!");
|
||||
}
|
||||
}
|
||||
//if (AbstractEAIndividual.getDoublePosition(indy)[0]<500000) {
|
||||
// System.err.println(indy.getStringRepresentation());
|
||||
//}
|
||||
}
|
||||
|
||||
/** This method will evaluate the current population using the
|
||||
|
@ -3,13 +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;
|
||||
import eva2.server.go.InterfacePopulationChangedEventListener;
|
||||
import eva2.server.go.InterfaceTerminator;
|
||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
import eva2.server.go.individuals.InterfaceDataTypeDouble;
|
||||
import eva2.server.go.populations.InterfaceSolutionSet;
|
||||
@ -18,7 +13,6 @@ import eva2.server.go.populations.SolutionSet;
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -35,6 +29,8 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
// simulating the generational cycle. Set rather small (eg 5) for use as local search, higher for global search (eg 50)
|
||||
private int generationCycle = 50;
|
||||
|
||||
private int fitIndex = 0; // choose criterion for multi objective functions
|
||||
|
||||
private Population m_Population;
|
||||
private AbstractOptimizationProblem m_Problem;
|
||||
private transient Vector<InterfacePopulationChangedEventListener> m_Listener;
|
||||
@ -96,14 +92,31 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
return r;
|
||||
}
|
||||
|
||||
protected boolean firstIsBetter(double[] first, double[] second) {
|
||||
return first[fitIndex]<second[fitIndex];
|
||||
}
|
||||
|
||||
protected boolean firstIsBetterEqual(double[] first, double[] second) {
|
||||
return first[fitIndex]<=second[fitIndex];
|
||||
}
|
||||
|
||||
protected boolean firstIsBetter(AbstractEAIndividual first, AbstractEAIndividual second) {
|
||||
return firstIsBetter(first.getFitness(), second.getFitness());
|
||||
}
|
||||
|
||||
protected boolean firstIsBetterEqual(AbstractEAIndividual first, AbstractEAIndividual second) {
|
||||
return firstIsBetterEqual(first.getFitness(), second.getFitness());
|
||||
}
|
||||
|
||||
public AbstractEAIndividual simplexStep(Population subpop) {
|
||||
// parameter
|
||||
|
||||
// hole die n-1 besten individuen
|
||||
// hole die n-1 besten individuen der fitness dimension fitIndex
|
||||
subpop.setSortingFitnessCriterion(fitIndex);
|
||||
Population bestpop = subpop.getBestNIndividuals(subpop.size()-1);
|
||||
// und das schlechteste
|
||||
AbstractEAIndividual worst = subpop.getWorstEAIndividual();
|
||||
AbstractEAIndividual best=subpop.getBestEAIndividual();
|
||||
AbstractEAIndividual worst = subpop.getWorstEAIndividual(fitIndex);
|
||||
AbstractEAIndividual best=subpop.getBestEAIndividual(fitIndex);
|
||||
|
||||
double[][] range = ((InterfaceDataTypeDouble) worst).getDoubleRange();
|
||||
double[] x_worst = ((InterfaceDataTypeDouble) worst).getDoubleData();
|
||||
@ -126,17 +139,15 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
Mathematics.reflectBounds(r, range);
|
||||
}
|
||||
}
|
||||
AbstractEAIndividual r_ind = (AbstractEAIndividual)((AbstractEAIndividual)bestpop.getIndividual(1)).clone();
|
||||
((InterfaceDataTypeDouble)r_ind).SetDoubleGenotype(r);
|
||||
AbstractEAIndividual reflectedInd = (AbstractEAIndividual)((AbstractEAIndividual)bestpop.getIndividual(1)).clone();
|
||||
((InterfaceDataTypeDouble)reflectedInd).SetDoubleGenotype(r);
|
||||
|
||||
m_Problem.evaluate(r_ind);
|
||||
m_Problem.evaluate(reflectedInd);
|
||||
this.m_Population.incrFunctionCalls();
|
||||
|
||||
if ((best.getFitness(0)<r_ind.getFitness(0))&(r_ind.getFitness(0) < bestpop.getWorstEAIndividual().getFitness(0))) { // Problem: Fitnesswert ist vektor
|
||||
|
||||
return r_ind;
|
||||
} else if (best.getFitness(0)>r_ind.getFitness(0)){ //neues besser als bisher bestes => Expansion
|
||||
|
||||
if (firstIsBetter(best, reflectedInd) && firstIsBetter(reflectedInd, bestpop.getWorstEAIndividual(fitIndex))) {
|
||||
return reflectedInd;
|
||||
} else if (firstIsBetter(reflectedInd, best)) { //neues besser als bisher bestes => Expansion
|
||||
double[] e = new double[dim];
|
||||
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);
|
||||
@ -145,13 +156,13 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
((InterfaceDataTypeDouble)e_ind).SetDoubleGenotype(e);
|
||||
m_Problem.evaluate(e_ind);
|
||||
this.m_Population.incrFunctionCalls();
|
||||
if(e_ind.getFitness(0)<r_ind.getFitness(0)){//expandiertes ist besser als reflektiertes
|
||||
if (firstIsBetter(e_ind, reflectedInd)) { //expandiertes ist besser als reflektiertes
|
||||
return e_ind;
|
||||
} else {
|
||||
return r_ind;
|
||||
return reflectedInd;
|
||||
}
|
||||
|
||||
} else if(r_ind.getFitness(0) >= bestpop.getWorstEAIndividual().getFitness(0)){//kontrahiere da neues indi keine verbesserung brachte
|
||||
} else if (firstIsBetterEqual(bestpop.getWorstEAIndividual(fitIndex), reflectedInd)) {
|
||||
//kontrahiere da neues indi keine verbesserung brachte
|
||||
double[] c = new double[dim];
|
||||
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);
|
||||
@ -160,7 +171,7 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
((InterfaceDataTypeDouble)c_ind).SetDoubleGenotype(c);
|
||||
m_Problem.evaluate(c_ind);
|
||||
this.m_Population.incrFunctionCalls();
|
||||
if(c_ind.getFitness(0)<=worst.getFitness(0)){
|
||||
if(firstIsBetterEqual(c_ind, worst)) {
|
||||
return c_ind;
|
||||
}
|
||||
}
|
||||
@ -176,7 +187,7 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
}
|
||||
|
||||
public String globalInfo() {
|
||||
return "The Nelder-Mead simplex search algorithm for local search. Reflection is used as constra";
|
||||
return "The Nelder-Mead simplex search algorithm for local search. Reflection on bounds may be used for constraint handling.";
|
||||
}
|
||||
|
||||
public Population getPopulation() {
|
||||
@ -235,10 +246,10 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
// m_Problem.evaluate(ind);
|
||||
// this.m_Population.incrFunctionCalls();
|
||||
}
|
||||
m_Population.set(m_Population.getIndexOfWorstIndividual(), ind);
|
||||
m_Population.set(m_Population.getIndexOfWorstIndividual(fitIndex), ind);
|
||||
}else{//keine Verbesserung gefunden shrink!!
|
||||
|
||||
double[] u_1 = ((InterfaceDataTypeDouble) m_Population.getBestEAIndividual()).getDoubleData();
|
||||
double[] u_1 = ((InterfaceDataTypeDouble) m_Population.getBestEAIndividual(fitIndex)).getDoubleData();
|
||||
|
||||
for(int j=0;j<m_Population.size();j++){
|
||||
double [] c= ((InterfaceDataTypeDouble) m_Population.getEAIndividual(j)).getDoubleData();
|
||||
@ -415,4 +426,16 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte
|
||||
return "Mark to check range constraints by reflection/projection";
|
||||
}
|
||||
|
||||
public int getCritIndex() {
|
||||
return fitIndex;
|
||||
}
|
||||
|
||||
public void setCritIndex(int fitIndex) {
|
||||
this.fitIndex = fitIndex;
|
||||
}
|
||||
|
||||
public String critIndexTipText() {
|
||||
return "For multi-criterial problems, set the index of the fitness to be used in 0..n-1. Default is 0";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,9 +15,12 @@ import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
import eva2.server.go.individuals.AbstractEAIndividualComparator;
|
||||
import eva2.server.go.individuals.InterfaceDataTypeDouble;
|
||||
import eva2.server.go.operators.distancemetric.PhenotypeMetric;
|
||||
import eva2.server.go.operators.paramcontrol.ConstantParameters;
|
||||
import eva2.server.go.operators.paramcontrol.InterfaceParameterControl;
|
||||
import eva2.server.go.populations.InterfaceSolutionSet;
|
||||
import eva2.server.go.populations.Population;
|
||||
import eva2.server.go.populations.SolutionSet;
|
||||
import eva2.server.go.problems.AbstractOptimizationProblem;
|
||||
import eva2.server.go.problems.F1Problem;
|
||||
import eva2.server.go.problems.Interface2DBorderProblem;
|
||||
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
||||
@ -71,6 +74,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
protected boolean wrapTopology = true;
|
||||
protected int treeBranchDeg = 3;
|
||||
protected int treeLevels, treeOrphans, treeLastFullLevelNodeCnt;
|
||||
protected InterfaceParameterControl paramControl = new ConstantParameters();
|
||||
|
||||
/**
|
||||
* InertnessOrChi may contain the inertness or chi parameter depending on algoType
|
||||
@ -174,13 +178,10 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
public static void initIndividualDefaults(AbstractEAIndividual indy, double initialV) {
|
||||
double[] writeData;
|
||||
// init velocity
|
||||
writeData = new double[((InterfaceDataTypeDouble)indy).getDoubleData().length];
|
||||
for (int j = 0; j < writeData.length; j++) {
|
||||
writeData[j] = RNG.gaussianDouble(1.0);
|
||||
//sum += (writeData[j])*(writeData[j]);
|
||||
}
|
||||
writeData=Mathematics.randomVector(((InterfaceDataTypeDouble)indy).getDoubleData().length, 1);
|
||||
|
||||
//sum = Math.sqrt(sum);
|
||||
double relSpeed = getRelativeSpeed(writeData, ((InterfaceDataTypeDouble)indy).getDoubleRange());
|
||||
double relSpeed = Mathematics.getRelativeLength(writeData, ((InterfaceDataTypeDouble)indy).getDoubleRange());
|
||||
for (int j = 0; j < writeData.length; j++) {
|
||||
writeData[j] = (writeData[j]/relSpeed)*initialV;
|
||||
}
|
||||
@ -216,7 +217,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
double[] curAvVelAndSpeed;
|
||||
if (population.getGeneration() == 0) return;
|
||||
|
||||
curAvVelAndSpeed = getPopulationVelSpeed(population, 3);
|
||||
curAvVelAndSpeed = getPopulationVelSpeed(population, 3, partVelKey, partTypeKey, defaultType);
|
||||
double[][] range = ((InterfaceDataTypeDouble)population.get(0)).getDoubleRange();
|
||||
if (tracedVelocity == null) {
|
||||
tracedVelocity = new double[((InterfaceDataTypeDouble)population.get(0)).getDoubleData().length];
|
||||
@ -228,7 +229,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
addMovingAverage(tracedVelocity, curAvVelAndSpeed, 2./(emaPeriods+1));
|
||||
}
|
||||
}
|
||||
if (m_Show) System.out.println(population.getGeneration() + " - abs avg " + curAvVelAndSpeed[curAvVelAndSpeed.length - 1] + ", vect " + getRelativeSpeed(curAvVelAndSpeed, range) + ", rel " + (curAvVelAndSpeed[curAvVelAndSpeed.length - 1]/getRelativeSpeed(curAvVelAndSpeed, range)));
|
||||
if (m_Show) System.out.println(population.getGeneration() + " - abs avg " + curAvVelAndSpeed[curAvVelAndSpeed.length - 1] + ", vect " + Mathematics.getRelativeLength(curAvVelAndSpeed, range) + ", rel " + (curAvVelAndSpeed[curAvVelAndSpeed.length - 1]/Mathematics.getRelativeLength(curAvVelAndSpeed, range)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,7 +245,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
}
|
||||
|
||||
public double getRelativeEMASpeed(double[][] range) {
|
||||
return getRelativeSpeed(getEMASpeed(), range);
|
||||
return Mathematics.getRelativeLength(getEMASpeed(), range);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -252,14 +253,19 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
* in the population. The mode switch may be 1 then the vectorial swarm velocity is returned; if it
|
||||
* is 2, the average speed relative to the range is returned (double array of length one); if it is 3 both
|
||||
* is returned in one array where the average absolute speed is in the last entry.
|
||||
* The velocity vector key is to be passed over. Optionally, an additional identifier is tested - they may be null.
|
||||
* @see AbstractEAIndividual.getData(String)
|
||||
*
|
||||
* @param pop the swarm population
|
||||
* @param calcModeSwitch mode switch
|
||||
* @param velocityKey String to access velocity vector within AbstractEAIndividual
|
||||
* @param typeString optional type string to access individual type
|
||||
* @param requiredType optional required type identifier of the individual.
|
||||
* @return double array containing the vectorial sum of particle velocities or an array containing the average absolute speed
|
||||
*/
|
||||
private double[] getPopulationVelSpeed(Population pop, int calcModeSwitch) {
|
||||
public static double[] getPopulationVelSpeed(Population pop, int calcModeSwitch, final String velocityKey, final String typeString, final Object requiredType) {
|
||||
AbstractEAIndividual indy = (AbstractEAIndividual)pop.get(0);
|
||||
if (!(indy instanceof InterfaceDataTypeDouble)) System.out.println("error, PSO needs individuals with double data!");
|
||||
if (!(indy instanceof InterfaceDataTypeDouble)) System.err.println("error, PSO needs individuals with double data!");
|
||||
|
||||
double[] ret;
|
||||
double[][] range = ((InterfaceDataTypeDouble)indy).getDoubleRange();
|
||||
@ -270,31 +276,36 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
boolean calcAbsSpeedAverage = ((calcModeSwitch & 2) > 0);
|
||||
if ((calcModeSwitch & 3) == 0) System.err.println("Error, switch must be 1, 2 or 3 (getPopulationVelSpeed)");
|
||||
|
||||
double[] velocity = (double[]) indy.getData(partVelKey);
|
||||
if (calcVectVelocity) retSize+=velocity.length; // entries for cumulative velocity
|
||||
if (calcAbsSpeedAverage) retSize++; // one entry for average absolute speed
|
||||
// return length of the array depends on what should be calculated
|
||||
ret = new double[retSize];
|
||||
|
||||
double[] velocity = (double[]) indy.getData(velocityKey);
|
||||
if (velocity != null) {
|
||||
if (calcVectVelocity) retSize+=velocity.length; // entries for cumulative velocity
|
||||
if (calcAbsSpeedAverage) retSize++; // one entry for average absolute speed
|
||||
// return length of the array depends on what should be calculated
|
||||
ret = new double[retSize];
|
||||
|
||||
double[] cumulVeloc = new double[velocity.length];
|
||||
double avSpeed = 0.;
|
||||
|
||||
for (int i=0; i<cumulVeloc.length; i++) cumulVeloc[i] = 0.;
|
||||
int indCnt = 0;
|
||||
|
||||
for (int i = 0; i < this.m_Population.size(); i++) {
|
||||
for (int i = 0; i < pop.size(); i++) {
|
||||
indy = (AbstractEAIndividual)pop.get(i);
|
||||
|
||||
if (particleHasSpeed(indy)) {
|
||||
indCnt++;
|
||||
velocity = (double[]) (indy.getData(partVelKey));
|
||||
if (calcVectVelocity) {
|
||||
for (int j=0; j<cumulVeloc.length; j++) cumulVeloc[j] += velocity[j];
|
||||
}
|
||||
if (calcAbsSpeedAverage) {
|
||||
avSpeed += getRelativeSpeed(velocity, range);
|
||||
}
|
||||
if (indy.hasData(velocityKey)) {
|
||||
velocity = (double[]) (indy.getData(velocityKey));
|
||||
if (velocity != null) {
|
||||
if ((typeString == null) || (indy.getData(typeString).equals(requiredType))) {
|
||||
//if (particleHasSpeed(indy)) {
|
||||
indCnt++;
|
||||
if (calcVectVelocity) {
|
||||
for (int j=0; j<cumulVeloc.length; j++) cumulVeloc[j] += velocity[j];
|
||||
}
|
||||
if (calcAbsSpeedAverage) {
|
||||
avSpeed += Mathematics.getRelativeLength(velocity, range);
|
||||
}
|
||||
}
|
||||
} else System.err.println("Error: Indy without velocity!! (getPopulationVelSpeed)");
|
||||
}
|
||||
}
|
||||
if (calcVectVelocity) {
|
||||
@ -306,7 +317,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
System.out.println("warning, no speed in particle! (DynamicParticleSwarmOptimization::getPopulationVelocity)");
|
||||
System.err.println("warning, no speed in particle! (getPopulationVelocity)");
|
||||
return null;
|
||||
}
|
||||
//for (int j=0; j<avSpeed.length; j++) avSpeed[j] /= velocity[j];
|
||||
@ -333,30 +344,21 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
/**
|
||||
* Calculates the vectorial sum of the velocities of all particles in the given population.
|
||||
*
|
||||
* @param pop vectorial sum of the particle velocities
|
||||
* @return
|
||||
* @param pop
|
||||
* @return vectorial sum of the particle velocities
|
||||
*/
|
||||
public double[] getPopulationVelocity(Population pop) {
|
||||
return getPopulationVelSpeed(pop, 1);
|
||||
return getPopulationVelSpeed(pop, 1, partVelKey, partTypeKey, defaultType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the norm of the velocity vector relative to the problem range.
|
||||
* Calculates the average of the (range-) normed velocities of all particles in the given population.
|
||||
*
|
||||
* @param curSpeed the current speed of the particle
|
||||
* @param range the problem range in each dimension
|
||||
* @return measure of the speed relative to the problem range
|
||||
* @param pop
|
||||
* @return average of the (range-) normed velocities
|
||||
*/
|
||||
public static double getRelativeSpeed(double[] curSpeed, double[][] range) {
|
||||
double sumV = 0;
|
||||
double sumR = 0;
|
||||
for (int i = 0; i < range.length; i++) {
|
||||
sumV += Math.pow(curSpeed[i], 2);
|
||||
sumR += Math.pow(range[i][1] - range[i][0], 2);
|
||||
}
|
||||
sumV = Math.sqrt(sumV);
|
||||
sumR = Math.sqrt(sumR);
|
||||
return sumV/sumR;
|
||||
public double getPopulationAvgNormedVelocity(Population pop) {
|
||||
return getPopulationVelSpeed(pop, 2, partVelKey, partTypeKey, defaultType)[0];
|
||||
}
|
||||
|
||||
/** This method will init the optimizer with a given population
|
||||
@ -620,22 +622,6 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
return (AbstractEAIndividual.isDominatingFitnessNotEqual(indy.getFitness(), bestFitness));
|
||||
}
|
||||
|
||||
protected void rotate(double[] vect, double alpha, int i, int j) {
|
||||
double xi = vect[i];
|
||||
double xj = vect[j];
|
||||
vect[i] = (xi*Math.cos(alpha))-(xj*Math.sin(alpha));
|
||||
vect[j] = (xi*Math.sin(alpha))+(xj*Math.cos(alpha));
|
||||
}
|
||||
|
||||
protected void rotateAllAxes(double[] vect, double alpha, boolean randomize) {
|
||||
for (int i=0; i<vect.length-1; i++) {
|
||||
for (int j=i+1; j<vect.length; j++) {
|
||||
if (randomize) rotate(vect, RNG.randomDouble(-alpha,alpha), i, j);
|
||||
else rotate(vect, alpha, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main velocity update step.
|
||||
*
|
||||
@ -1061,7 +1047,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
* @param speedLim the speed limit relative to the range
|
||||
*/
|
||||
protected void enforceSpeedLimit(double[] curVelocity, double[][] range, double speedLim) {
|
||||
while (getRelativeSpeed(curVelocity, range) > speedLim) {
|
||||
while (Mathematics.getRelativeLength(curVelocity, range) > speedLim) {
|
||||
for (int i = 0; i < curVelocity.length; i++) {
|
||||
curVelocity[i] *= this.m_ReduceSpeed;
|
||||
}
|
||||
@ -1145,9 +1131,9 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
|
||||
if (sleepTime > 0 ) try { Thread.sleep(sleepTime); } catch(Exception e) {}
|
||||
|
||||
maybeClearPlot();
|
||||
// maybeClearPlot();
|
||||
}
|
||||
|
||||
|
||||
protected void maybeClearPlot() {
|
||||
if (((m_Population.getGeneration() % 23) == 0) && isShow() && (m_Plot != null)) {
|
||||
m_Plot.clearAll();
|
||||
@ -1784,4 +1770,12 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se
|
||||
protected void setEmaPeriods(int emaPeriods) {
|
||||
this.emaPeriods = emaPeriods;
|
||||
}
|
||||
|
||||
public InterfaceParameterControl getParamControl() {
|
||||
return paramControl;
|
||||
}
|
||||
|
||||
public void setParamControl(InterfaceParameterControl paramControl) {
|
||||
this.paramControl = paramControl;
|
||||
}
|
||||
}
|
@ -8,7 +8,10 @@ import eva2.gui.BeanInspector;
|
||||
import eva2.server.go.InterfaceGOParameters;
|
||||
import eva2.server.go.InterfacePopulationChangedEventListener;
|
||||
import eva2.server.go.InterfaceProcessor;
|
||||
import eva2.server.go.InterfaceTerminator;
|
||||
import eva2.server.go.PopulationInterface;
|
||||
import eva2.server.go.operators.paramcontrol.ConstantParameters;
|
||||
import eva2.server.go.operators.paramcontrol.InterfaceParameterControl;
|
||||
import eva2.server.go.operators.postprocess.PostProcess;
|
||||
import eva2.server.go.operators.postprocess.PostProcessParams;
|
||||
import eva2.server.go.operators.terminators.EvaluationTerminator;
|
||||
@ -16,6 +19,7 @@ import eva2.server.go.operators.terminators.GenerationTerminator;
|
||||
import eva2.server.go.populations.Population;
|
||||
import eva2.server.go.problems.AbstractOptimizationProblem;
|
||||
import eva2.server.go.problems.InterfaceAdditionalPopulationInformer;
|
||||
import eva2.server.go.strategies.InterfaceOptimizer;
|
||||
import eva2.server.stat.InterfaceStatistics;
|
||||
import eva2.server.stat.InterfaceTextListener;
|
||||
import eva2.server.stat.StatisticsWithGUI;
|
||||
@ -202,14 +206,19 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo
|
||||
//m_Statistics.createNextGenerationPerformed((PopulationInterface)this.m_ModulParameter.getOptimizer().getPopulation());
|
||||
if (m_ListenerModule!=null) m_ListenerModule.updateProgress(getStatusPercent(goParams.getOptimizer().getPopulation(), runCounter, m_Statistics.getStatisticsParameter().getMultiRuns()), null);
|
||||
if (popLog != null) EVAHELP.clearLog(popLog);
|
||||
maybeInitParamCtrl(goParams.getOptimizer());
|
||||
|
||||
do { // main loop
|
||||
maybeUpdateParamCtrl(goParams.getOptimizer(), goParams.getTerminator());
|
||||
|
||||
this.goParams.getOptimizer().optimize();
|
||||
// registerPopulationStateChanged *SHOULD* be fired by the optimizer or resp. the population
|
||||
// as we are event listener
|
||||
if (popLog != null) EVAHELP.logString(this.goParams.getOptimizer().getPopulation().getIndyList(), popLog);
|
||||
} while (isOptRunning() && !this.goParams.getTerminator().isTerminated(this.goParams.getOptimizer().getAllSolutions()));
|
||||
runCounter++;
|
||||
|
||||
maybeFinishParamCtrl(goParams.getOptimizer());
|
||||
|
||||
//////////////// Default stats
|
||||
m_Statistics.stopOptPerformed(isOptRunning(), goParams.getTerminator().lastTerminationMessage()); // stop is "normal" if opt wasnt set false by the user (and thus still true)
|
||||
|
||||
@ -228,7 +237,42 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo
|
||||
return resultPop;
|
||||
}
|
||||
|
||||
/**
|
||||
private void maybeInitParamCtrl(InterfaceOptimizer optimizer) {
|
||||
Object paramCtrl=null;
|
||||
if (null!=(paramCtrl=BeanInspector.callIfAvailable(optimizer, "getParamControl", null))) {
|
||||
if (paramCtrl instanceof InterfaceParameterControl) {
|
||||
if (!(paramCtrl instanceof ConstantParameters)) {
|
||||
((InterfaceParameterControl)paramCtrl).init(optimizer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeFinishParamCtrl(InterfaceOptimizer optimizer) {
|
||||
Object paramCtrl=null;
|
||||
if (null!=(paramCtrl=BeanInspector.callIfAvailable(optimizer, "getParamControl", null))) {
|
||||
if (paramCtrl instanceof InterfaceParameterControl) {
|
||||
if (!(paramCtrl instanceof ConstantParameters)) {
|
||||
((InterfaceParameterControl)paramCtrl).finish(optimizer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void maybeUpdateParamCtrl(InterfaceOptimizer optimizer,
|
||||
InterfaceTerminator terminator) {
|
||||
Object paramCtrl=null;
|
||||
if (null!=(paramCtrl=BeanInspector.callIfAvailable(optimizer, "getParamControl", null))) {
|
||||
if (paramCtrl instanceof InterfaceParameterControl) {
|
||||
if (!(paramCtrl instanceof ConstantParameters)) {
|
||||
if (terminator instanceof GenerationTerminator) ((InterfaceParameterControl)paramCtrl).updateParameters(optimizer, optimizer.getPopulation().getGeneration(), ((GenerationTerminator)terminator).getGenerations());
|
||||
else if (terminator instanceof EvaluationTerminator) ((InterfaceParameterControl)paramCtrl).updateParameters(optimizer, optimizer.getPopulation().getFunctionCalls(), ((EvaluationTerminator)terminator).getFitnessCalls());
|
||||
else ((InterfaceParameterControl)paramCtrl).updateParameters(optimizer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the percentage of current (multi-)run already performed, based on evaluations/generations
|
||||
* for the EvaluationTerminator/GenerationTerminator or multi-runs only.
|
||||
*
|
||||
|
@ -190,6 +190,7 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
if (printFinalVerbosity()) printToTextListener(refineToText(meanCollection, showAvgIntervals));
|
||||
}
|
||||
}
|
||||
|
||||
if (TRACE)
|
||||
System.out.println("End of run");
|
||||
if (resultOut != null) {
|
||||
@ -257,7 +258,7 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
|
||||
protected String getOutputHeader(List<InterfaceAdditionalPopulationInformer> informerList, PopulationInterface pop) {
|
||||
|
||||
String headline = "Fun.calls \t Best \t Mean \t Worst ";
|
||||
String headline = "Fun.calls\t Best\t Mean\t Worst ";
|
||||
if ((informerList == null) || !m_StatsParams.isOutputAdditionalInfo()) {
|
||||
return headline;
|
||||
} else {
|
||||
|
@ -2,6 +2,9 @@ package eva2.tools;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import eva2.server.go.individuals.InterfaceDataTypeDouble;
|
||||
|
||||
import wsi.ra.math.RNG;
|
||||
import wsi.ra.math.Jama.Matrix;
|
||||
import wsi.ra.math.interpolation.BasicDataSet;
|
||||
import wsi.ra.math.interpolation.InterpolationException;
|
||||
@ -433,7 +436,7 @@ public class Mathematics {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Multiplies (scales) every element of the array v with s returning a new vector.
|
||||
*
|
||||
@ -491,7 +494,20 @@ public class Mathematics {
|
||||
res[i] = v[i] / s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Component wise multiplication of vectors: res[i]=u[i]*v[i]
|
||||
*
|
||||
* @param s
|
||||
* @param v
|
||||
* @return
|
||||
*/
|
||||
public static void vvMultCw(double[] u, double[] v, double[] res) {
|
||||
for (int i = 0; i < res.length; i++) {
|
||||
res[i] = u[i]*v[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a vector of given length containing zeroes.
|
||||
* @param n
|
||||
@ -615,6 +631,41 @@ public class Mathematics {
|
||||
svDiv(norm(v), v, res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the norm of the given vector relative to the problem range.
|
||||
*
|
||||
* @param vector a double vector within the range
|
||||
* @param range the range in each dimension
|
||||
* @return measure of the length relative to the problem range
|
||||
*/
|
||||
public static double getRelativeLength(double[] vector, double[][] range) {
|
||||
double sumV = 0;
|
||||
double sumR = 0;
|
||||
for (int i = 0; i < range.length; i++) {
|
||||
sumV += Math.pow(vector[i], 2);
|
||||
sumR += Math.pow(range[i][1] - range[i][0], 2);
|
||||
}
|
||||
sumV = Math.sqrt(sumV);
|
||||
sumR = Math.sqrt(sumR);
|
||||
return sumV/sumR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a random vector, the components will be set to gaussian distributed
|
||||
* values with mean zero and the given standard deviation.
|
||||
*
|
||||
* @param dim the desired dimension
|
||||
* @param stdDev the gaussian standard deviation
|
||||
* @return random vector
|
||||
*/
|
||||
public static double[] randomVector(int dim, double stdDev) {
|
||||
double[] vect = new double[dim];
|
||||
for (int j = 0; j < vect.length; j++) {
|
||||
vect[j] = RNG.gaussianDouble(stdDev);
|
||||
}
|
||||
return vect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the doubles in the array by their sum,
|
||||
* so that they add up to one.
|
||||
@ -676,6 +727,52 @@ public class Mathematics {
|
||||
return A;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate the vector by angle alpha around axis i/j
|
||||
*
|
||||
* @param vect
|
||||
* @param alpha
|
||||
* @param i
|
||||
* @param j
|
||||
*/
|
||||
public static void rotate(double[] vect, double alpha, int i, int j) {
|
||||
double xi = vect[i];
|
||||
double xj = vect[j];
|
||||
vect[i] = (xi*Math.cos(alpha))-(xj*Math.sin(alpha));
|
||||
vect[j] = (xi*Math.sin(alpha))+(xj*Math.cos(alpha));
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate the vector along all axes by angle alpha or a uniform random value
|
||||
* in [-alpha, alpha] if randomize is true.
|
||||
*
|
||||
* @param vect
|
||||
* @param alpha
|
||||
* @param randomize
|
||||
*/
|
||||
public static void rotateAllAxes(double[] vect, double alpha, boolean randomize) {
|
||||
for (int i=0; i<vect.length-1; i++) {
|
||||
for (int j=i+1; j<vect.length; j++) {
|
||||
if (randomize) rotate(vect, RNG.randomDouble(-alpha,alpha), i, j);
|
||||
else rotate(vect, alpha, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate the vector along all axes i/j by angle alphas[i][j].
|
||||
*
|
||||
* @param vect
|
||||
* @param alphas
|
||||
*/
|
||||
public static void rotateAllAxes(double[] vect, double[][] alphas) {
|
||||
for (int i=0; i<vect.length-1; i++) {
|
||||
for (int j=i+1; j<vect.length; j++) {
|
||||
rotate(vect, alphas[i][j], i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static double max(double[] vals) {
|
||||
double maxVal = vals[0];
|
||||
for (int i=1; i<vals.length; i++) maxVal = Math.max(maxVal, vals[i]);
|
||||
@ -702,6 +799,21 @@ public class Mathematics {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the vector of interval length values in any dimension.
|
||||
* ret[i]=range[i][1]-range[i][0];
|
||||
*
|
||||
* @param range
|
||||
* @return
|
||||
*/
|
||||
public static double[] shiftRange(double[][] range) {
|
||||
double[] ret = new double[range.length];
|
||||
for (int i = 0; i < ret.length; i++) {
|
||||
ret[i]=range[i][1]-range[i][0];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Project the values in x to the range given. The range must be an vector of 2d-arrays
|
||||
* each of which containing lower and upper bound in the i-th dimension.
|
||||
|
@ -75,7 +75,15 @@ public class RNG extends Random {
|
||||
* @return int
|
||||
*/
|
||||
public static int randomInt(int lo,int hi) {
|
||||
if (hi<lo) {
|
||||
System.err.println("Invalid boundary values! Returning zero.");
|
||||
return -1;
|
||||
}
|
||||
int result = (Math.abs(random.nextInt())%(hi-lo+1))+lo;
|
||||
if ((result < lo) || (result > hi)) {
|
||||
System.err.println("Error in RNG.randomInt!");
|
||||
result = Math.abs(random.nextInt()%(hi-lo+1))+lo;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user