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:
Marcel Kronfeld 2009-03-17 17:26:06 +00:00
parent ac92a3a119
commit abafb57679
18 changed files with 761 additions and 130 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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