Added generated serial version identifier.
This commit is contained in:
parent
cde9129555
commit
65ce36b901
@ -24,38 +24,52 @@ import eva2.tools.math.RNG;
|
|||||||
import eva2.tools.math.Jama.Matrix;
|
import eva2.tools.math.Jama.Matrix;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For a double valued problem, there are two main methods to implement: {@link #getProblemDimension()}
|
* For a double valued problem, there are two main methods to implement:
|
||||||
* must return the problem dimension, while {@link #eval(double[])} is to evaluate a single double
|
* {@link #getProblemDimension()} must return the problem dimension, while
|
||||||
* vector into the result fitness vector.
|
* {@link #eval(double[])} is to evaluate a single double vector into the result
|
||||||
|
* fitness vector.
|
||||||
*
|
*
|
||||||
* To define the problem range, you may use the default range parameter resulting in a symmetric
|
* To define the problem range, you may use the default range parameter
|
||||||
* double range [-defaultRange,defaulRange] in all dimensions.
|
* resulting in a symmetric double range [-defaultRange,defaulRange] in all
|
||||||
* Or you may implement {@link #getRangeLowerBound(int)} and {@link #getRangeUpperBound(int)}
|
* dimensions. Or you may implement {@link #getRangeLowerBound(int)} and
|
||||||
* to define an arbitrary problem range. In that case, the default range parameter is not used.
|
* {@link #getRangeUpperBound(int)} to define an arbitrary problem range. In
|
||||||
|
* that case, the default range parameter is not used.
|
||||||
*
|
*
|
||||||
* Anything you want to do before any optimization is started on the problem should go into
|
* Anything you want to do before any optimization is started on the problem
|
||||||
* {@link #initProblem()}, but remember to call the super-method in your implementation. The
|
* should go into {@link #initProblem()}, but remember to call the super-method
|
||||||
* individual template will be initialized to an ESIndividualDoubleData by then.
|
* in your implementation. The individual template will be initialized to an
|
||||||
|
* ESIndividualDoubleData by then.
|
||||||
*
|
*
|
||||||
* For the GUI, it is also convenient to implement the {@link #globalInfo()} and {@link #getName()}
|
* For the GUI, it is also convenient to implement the {@link #globalInfo()} and
|
||||||
* methods to provide some distinctive information for the user.
|
* {@link #getName()} methods to provide some distinctive information for the
|
||||||
|
* user.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author mkron
|
* @author mkron
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractProblemDouble extends AbstractOptimizationProblem implements InterfaceProblemDouble, Interface2DBorderProblem/*, InterfaceParamControllable */{
|
public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
|
||||||
|
implements InterfaceProblemDouble, Interface2DBorderProblem/*
|
||||||
|
* ,
|
||||||
|
* InterfaceParamControllable
|
||||||
|
*/{
|
||||||
|
/**
|
||||||
|
* Generated serial version identifier.
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -3904130243174390134L;
|
||||||
private double m_DefaultRange = 10;
|
private double m_DefaultRange = 10;
|
||||||
private double m_Noise = 0;
|
private double m_Noise = 0;
|
||||||
private boolean doRotation = false; // should really be false by default
|
private boolean doRotation = false; // should really be false by default
|
||||||
private Matrix rotation;
|
private Matrix rotation;
|
||||||
|
|
||||||
// PropertySelectableList<AbstractConstraint> constraintList = new PropertySelectableList<AbstractConstraint>(new AbstractConstraint[]{new GenericConstraint()});
|
// PropertySelectableList<AbstractConstraint> constraintList = new
|
||||||
private AbstractConstraint[] constraintArray = new AbstractConstraint[]{new GenericConstraint()};
|
// PropertySelectableList<AbstractConstraint>(new AbstractConstraint[]{new
|
||||||
private boolean withConstraints = false;
|
// GenericConstraint()});
|
||||||
|
private AbstractConstraint[] constraintArray = new AbstractConstraint[] { new GenericConstraint() };
|
||||||
|
private boolean withConstraints = false;
|
||||||
private transient boolean isShowing = false;
|
private transient boolean isShowing = false;
|
||||||
private double rotAngle = 22.5; // for default rotation along every axis
|
private double rotAngle = 22.5; // for default rotation along every axis
|
||||||
public static String rawFitKey="UnconstrainedFitnessValue";
|
public static String rawFitKey = "UnconstrainedFitnessValue";
|
||||||
|
|
||||||
public AbstractProblemDouble() {
|
public AbstractProblemDouble() {
|
||||||
initTemplate();
|
initTemplate();
|
||||||
@ -66,10 +80,14 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void initTemplate() {
|
protected void initTemplate() {
|
||||||
if (m_Template == null) m_Template = new ESIndividualDoubleData();
|
if (m_Template == null)
|
||||||
if (getProblemDimension() > 0) { // avoid evil case setting dim to 0 during object init
|
m_Template = new ESIndividualDoubleData();
|
||||||
((InterfaceDataTypeDouble)this.m_Template).setDoubleDataLength(getProblemDimension());
|
if (getProblemDimension() > 0) { // avoid evil case setting dim to 0
|
||||||
((InterfaceDataTypeDouble)this.m_Template).SetDoubleRange(makeRange());
|
// during object init
|
||||||
|
((InterfaceDataTypeDouble) this.m_Template)
|
||||||
|
.setDoubleDataLength(getProblemDimension());
|
||||||
|
((InterfaceDataTypeDouble) this.m_Template)
|
||||||
|
.SetDoubleRange(makeRange());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,104 +99,123 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
|
|||||||
this.m_DefaultRange = o.m_DefaultRange;
|
this.m_DefaultRange = o.m_DefaultRange;
|
||||||
this.m_Noise = o.m_Noise;
|
this.m_Noise = o.m_Noise;
|
||||||
this.SetDefaultAccuracy(o.getDefaultAccuracy());
|
this.SetDefaultAccuracy(o.getDefaultAccuracy());
|
||||||
if (o.m_Template != null) this.m_Template = (AbstractEAIndividual)o.m_Template.clone();
|
if (o.m_Template != null)
|
||||||
if (o.constraintArray!=null) {
|
this.m_Template = (AbstractEAIndividual) o.m_Template.clone();
|
||||||
this.constraintArray=o.constraintArray.clone();
|
if (o.constraintArray != null) {
|
||||||
for (int i=0; i<constraintArray.length; i++) constraintArray[i]=(AbstractConstraint)o.constraintArray[i].clone();
|
this.constraintArray = o.constraintArray.clone();
|
||||||
|
for (int i = 0; i < constraintArray.length; i++)
|
||||||
|
constraintArray[i] = (AbstractConstraint) o.constraintArray[i]
|
||||||
|
.clone();
|
||||||
}
|
}
|
||||||
this.withConstraints=o.withConstraints;
|
this.withConstraints = o.withConstraints;
|
||||||
this.doRotation = o.doRotation;
|
this.doRotation = o.doRotation;
|
||||||
this.rotation = (o.rotation==null) ? null : (Matrix)o.rotation.clone();
|
this.rotation = (o.rotation == null) ? null : (Matrix) o.rotation
|
||||||
|
.clone();
|
||||||
this.rotAngle = o.rotAngle;
|
this.rotAngle = o.rotAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve and copy the double solution representation from an individual. This
|
* Retrieve and copy the double solution representation from an individual.
|
||||||
* may also perform a coding adaption. The result is stored as phenotype within
|
* This may also perform a coding adaption. The result is stored as
|
||||||
* the evaluate method.
|
* phenotype within the evaluate method.
|
||||||
*
|
*
|
||||||
* @param individual
|
* @param individual
|
||||||
* @return the double solution representation
|
* @return the double solution representation
|
||||||
*/
|
*/
|
||||||
protected double[] getEvalArray(AbstractEAIndividual individual){
|
protected double[] getEvalArray(AbstractEAIndividual individual) {
|
||||||
double[] x = new double[((InterfaceDataTypeDouble) individual).getDoubleData().length];
|
double[] x = new double[((InterfaceDataTypeDouble) individual)
|
||||||
System.arraycopy(((InterfaceDataTypeDouble) individual).getDoubleData(), 0, x, 0, x.length);
|
.getDoubleData().length];
|
||||||
return x;
|
System.arraycopy(
|
||||||
|
((InterfaceDataTypeDouble) individual).getDoubleData(), 0, x,
|
||||||
|
0, x.length);
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When implementing a double problem, inheriting classes should not override this method (or only
|
* When implementing a double problem, inheriting classes should not
|
||||||
* extend it) and do the fitness calculations in the method eval(double[]).
|
* override this method (or only extend it) and do the fitness calculations
|
||||||
|
* in the method eval(double[]).
|
||||||
*
|
*
|
||||||
* @see eval(double[] x)
|
* @see eval(double[] x)
|
||||||
*/
|
*/
|
||||||
public void evaluate(AbstractEAIndividual individual) {
|
public void evaluate(AbstractEAIndividual individual) {
|
||||||
double[] x;
|
double[] x;
|
||||||
double[] fitness;
|
double[] fitness;
|
||||||
|
|
||||||
x = getEvalArray(individual);
|
x = getEvalArray(individual);
|
||||||
((InterfaceDataTypeDouble)individual).SetDoublePhenotype(x);
|
((InterfaceDataTypeDouble) individual).SetDoublePhenotype(x);
|
||||||
// evaluate the vector
|
// evaluate the vector
|
||||||
fitness = this.eval(x);
|
fitness = this.eval(x);
|
||||||
// if indicated, add Gaussian noise
|
// if indicated, add Gaussian noise
|
||||||
if (m_Noise != 0) RNG.addNoise(fitness, m_Noise);
|
if (m_Noise != 0)
|
||||||
// set the fitness
|
RNG.addNoise(fitness, m_Noise);
|
||||||
setEvalFitness(individual, x, fitness);
|
// set the fitness
|
||||||
if (isWithConstraints()) {
|
setEvalFitness(individual, x, fitness);
|
||||||
individual.putData(rawFitKey, individual.getFitness().clone());
|
if (isWithConstraints()) {
|
||||||
addConstraints(individual, x);
|
individual.putData(rawFitKey, individual.getFitness().clone());
|
||||||
}
|
addConstraints(individual, x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected double[] rotateMaybe(double[] x) {
|
protected double[] rotateMaybe(double[] x) {
|
||||||
if (isDoRotation()) {
|
if (isDoRotation()) {
|
||||||
if (rotation==null) initProblem();
|
if (rotation == null)
|
||||||
x = Mathematics.rotate(x, rotation);
|
initProblem();
|
||||||
}
|
x = Mathematics.rotate(x, rotation);
|
||||||
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected double[] inverseRotateMaybe(double[] x) {
|
protected double[] inverseRotateMaybe(double[] x) {
|
||||||
if (isDoRotation()) {
|
if (isDoRotation()) {
|
||||||
if (rotation==null) initProblem();
|
if (rotation == null)
|
||||||
x = Mathematics.rotate(x, rotation.inverse());
|
initProblem();
|
||||||
}
|
x = Mathematics.rotate(x, rotation.inverse());
|
||||||
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add all constraint violations to the individual. Expect that the fitness has already been set.
|
* Add all constraint violations to the individual. Expect that the fitness
|
||||||
|
* has already been set.
|
||||||
*
|
*
|
||||||
* @param individual
|
* @param individual
|
||||||
* @param indyPos may contain the decoded individual position
|
* @param indyPos
|
||||||
|
* may contain the decoded individual position
|
||||||
*/
|
*/
|
||||||
protected void addConstraints(AbstractEAIndividual individual, double[] indyPos) {
|
protected void addConstraints(AbstractEAIndividual individual,
|
||||||
|
double[] indyPos) {
|
||||||
AbstractConstraint[] cnstr = getConstraints();
|
AbstractConstraint[] cnstr = getConstraints();
|
||||||
for (int i=0; i<cnstr.length; i++) {
|
for (int i = 0; i < cnstr.length; i++) {
|
||||||
// String name= (String)BeanInspector.callIfAvailable(cnstr[i], "getName", new Object[]{});
|
// String name= (String)BeanInspector.callIfAvailable(cnstr[i],
|
||||||
// System.out.println("checking constraint " + (name==null ? cnstr[i].getClass().getSimpleName() : name));
|
// "getName", new Object[]{});
|
||||||
((AbstractConstraint)cnstr[i]).addViolation(individual, indyPos);
|
// System.out.println("checking constraint " + (name==null ?
|
||||||
|
// cnstr[i].getClass().getSimpleName() : name));
|
||||||
|
((AbstractConstraint) cnstr[i]).addViolation(individual, indyPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a fitness value back to an individual. May be overridden to add constraints.
|
* Write a fitness value back to an individual. May be overridden to add
|
||||||
|
* constraints.
|
||||||
*
|
*
|
||||||
* @param individual
|
* @param individual
|
||||||
* @param x
|
* @param x
|
||||||
* @param fit
|
* @param fit
|
||||||
*/
|
*/
|
||||||
protected void setEvalFitness(AbstractEAIndividual individual, double[] x, double[] fit) {
|
protected void setEvalFitness(AbstractEAIndividual individual, double[] x,
|
||||||
|
double[] fit) {
|
||||||
individual.SetFitness(fit);
|
individual.SetFitness(fit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluate a double vector, representing the target function.
|
* Evaluate a double vector, representing the target function. If you
|
||||||
* If you implement this, you should take care of the offsets and rotation,
|
* implement this, you should take care of the offsets and rotation, e.g. by
|
||||||
* e.g. by using x=rotateMaybe(x) before further evaluation.
|
* using x=rotateMaybe(x) before further evaluation.
|
||||||
*
|
*
|
||||||
* @param x the vector to evaluate
|
* @param x
|
||||||
* @return the target function value
|
* the vector to evaluate
|
||||||
|
* @return the target function value
|
||||||
*/
|
*/
|
||||||
public abstract double[] eval(double[] x);
|
public abstract double[] eval(double[] x);
|
||||||
|
|
||||||
@ -191,119 +228,135 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initPopulation(Population population) {
|
public void initPopulation(Population population) {
|
||||||
initTemplate();
|
initTemplate();
|
||||||
AbstractOptimizationProblem.defaultInitPopulation(population, m_Template, this);
|
AbstractOptimizationProblem.defaultInitPopulation(population,
|
||||||
|
m_Template, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new range array by using the getRangeLowerBound and getRangeUpperBound methods.
|
* Create a new range array by using the getRangeLowerBound and
|
||||||
|
* getRangeUpperBound methods.
|
||||||
*
|
*
|
||||||
* @return a range array
|
* @return a range array
|
||||||
*/
|
*/
|
||||||
public double[][] makeRange() {
|
public double[][] makeRange() {
|
||||||
double[][] range = new double[this.getProblemDimension()][2];
|
double[][] range = new double[this.getProblemDimension()][2];
|
||||||
for (int i = 0; i < range.length; i++) {
|
for (int i = 0; i < range.length; i++) {
|
||||||
range[i][0] = getRangeLowerBound(i);
|
range[i][0] = getRangeLowerBound(i);
|
||||||
range[i][1] = getRangeUpperBound(i);
|
range[i][1] = getRangeUpperBound(i);
|
||||||
}
|
}
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the lower bound of the double range in the given dimension. Override
|
* Get the lower bound of the double range in the given dimension. Override
|
||||||
* this to implement non-symmetric ranges. Use setDefaultRange for symmetric ranges.
|
* this to implement non-symmetric ranges. Use setDefaultRange for symmetric
|
||||||
*
|
* ranges.
|
||||||
* @see makeRange()
|
*
|
||||||
* @see getRangeUpperBound(int dim)
|
* @see makeRange()
|
||||||
* @param dim
|
* @see getRangeUpperBound(int dim)
|
||||||
* @return the lower bound of the double range in the given dimension
|
* @param dim
|
||||||
*/
|
* @return the lower bound of the double range in the given dimension
|
||||||
public double getRangeLowerBound(int dim) {
|
*/
|
||||||
return -getDefaultRange();
|
public double getRangeLowerBound(int dim) {
|
||||||
}
|
return -getDefaultRange();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the upper bound of the double range in the given dimension. Override
|
* Get the upper bound of the double range in the given dimension. Override
|
||||||
* this to implement non-symmetric ranges. User setDefaultRange for symmetric ranges.
|
* this to implement non-symmetric ranges. User setDefaultRange for
|
||||||
*
|
* symmetric ranges.
|
||||||
* @see makeRange()
|
*
|
||||||
* @see getRangeLowerBound(int dim)
|
* @see makeRange()
|
||||||
* @param dim
|
* @see getRangeLowerBound(int dim)
|
||||||
* @return the upper bound of the double range in the given dimension
|
* @param dim
|
||||||
*/
|
* @return the upper bound of the double range in the given dimension
|
||||||
public double getRangeUpperBound(int dim) {
|
*/
|
||||||
return getDefaultRange();
|
public double getRangeUpperBound(int dim) {
|
||||||
}
|
return getDefaultRange();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initProblem() {
|
public void initProblem() {
|
||||||
initTemplate();
|
initTemplate();
|
||||||
if (isDoRotation()) {
|
if (isDoRotation()) {
|
||||||
rotation = initDefaultRotationMatrix(rotAngle , getProblemDimension());
|
rotation = initDefaultRotationMatrix(rotAngle,
|
||||||
} else rotation = null;
|
getProblemDimension());
|
||||||
|
} else
|
||||||
|
rotation = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize rotation matrix which rotates around the given angle in every axis.
|
* Initialize rotation matrix which rotates around the given angle in every
|
||||||
|
* axis.
|
||||||
*
|
*
|
||||||
* @param rotAngle
|
* @param rotAngle
|
||||||
* @param dim
|
* @param dim
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static Matrix initDefaultRotationMatrix(double rotAngle, int dim) {
|
public static Matrix initDefaultRotationMatrix(double rotAngle, int dim) {
|
||||||
Matrix rotation=null;
|
Matrix rotation = null;
|
||||||
// Matrix vec = new Matrix(dim, 1);
|
// Matrix vec = new Matrix(dim, 1);
|
||||||
// for (int i=0; i<dim; i++) vec.set(i,0, i+1);
|
// for (int i=0; i<dim; i++) vec.set(i,0, i+1);
|
||||||
// System.out.println(BeanInspector.toString(eval(vec.getColumnPackedCopy())));
|
// System.out.println(BeanInspector.toString(eval(vec.getColumnPackedCopy())));
|
||||||
// rotation = new Matrix(dim, dim);
|
// rotation = new Matrix(dim, dim);
|
||||||
// rotation = Mathematics.getRotationMatrix(vec).transpose();
|
// rotation = Mathematics.getRotationMatrix(vec).transpose();
|
||||||
rotation = Mathematics.getRotationMatrix((rotAngle*Math.PI/180.), dim).transpose();
|
rotation = Mathematics.getRotationMatrix((rotAngle * Math.PI / 180.),
|
||||||
//double[] t= new double[dim]; Arrays.fill(t, 1.);
|
dim).transpose();
|
||||||
//System.out.println(BeanInspector.toString(rotation.times(t)));
|
// double[] t= new double[dim]; Arrays.fill(t, 1.);
|
||||||
|
// System.out.println(BeanInspector.toString(rotation.times(t)));
|
||||||
return rotation;
|
return rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method allows you to choose how much noise is to be added to the
|
* This method allows you to choose how much noise is to be added to the
|
||||||
* fitness. This can be used to make the optimization problem more difficult.
|
* fitness. This can be used to make the optimization problem more
|
||||||
* @param noise The sigma for a gaussian random number.
|
* difficult.
|
||||||
*/
|
*
|
||||||
public void setNoise(double noise) {
|
* @param noise
|
||||||
if (noise < 0) noise = 0;
|
* The sigma for a gaussian random number.
|
||||||
this.m_Noise = noise;
|
*/
|
||||||
}
|
public void setNoise(double noise) {
|
||||||
/**
|
if (noise < 0)
|
||||||
* Get the current noise level.
|
noise = 0;
|
||||||
* @return the current noise level
|
this.m_Noise = noise;
|
||||||
*/
|
}
|
||||||
public double getNoise() {
|
|
||||||
return this.m_Noise;
|
|
||||||
}
|
|
||||||
public String noiseTipText() {
|
|
||||||
return "Gaussian noise level on the fitness value.";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method allows you to choose the EA individual used by the problem.
|
* Get the current noise level.
|
||||||
*
|
*
|
||||||
* @param indy The EAIndividual type
|
* @return the current noise level
|
||||||
*/
|
*/
|
||||||
public void setEAIndividual(InterfaceDataTypeDouble indy) {
|
public double getNoise() {
|
||||||
this.m_Template = (AbstractEAIndividual)indy;
|
return this.m_Noise;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String noiseTipText() {
|
||||||
* Get the EA individual template currently used by the problem.
|
return "Gaussian noise level on the fitness value.";
|
||||||
*
|
}
|
||||||
* @return the EA individual template currently used
|
|
||||||
*/
|
|
||||||
public InterfaceDataTypeDouble getEAIndividual() {
|
|
||||||
return (InterfaceDataTypeDouble)this.m_Template;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String EAIndividualTipText() {
|
/**
|
||||||
return "Set the base individual type defining the data representation and mutation/crossover operators";
|
* This method allows you to choose the EA individual used by the problem.
|
||||||
}
|
*
|
||||||
|
* @param indy
|
||||||
|
* The EAIndividual type
|
||||||
|
*/
|
||||||
|
public void setEAIndividual(InterfaceDataTypeDouble indy) {
|
||||||
|
this.m_Template = (AbstractEAIndividual) indy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the EA individual template currently used by the problem.
|
||||||
|
*
|
||||||
|
* @return the EA individual template currently used
|
||||||
|
*/
|
||||||
|
public InterfaceDataTypeDouble getEAIndividual() {
|
||||||
|
return (InterfaceDataTypeDouble) this.m_Template;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String EAIndividualTipText() {
|
||||||
|
return "Set the base individual type defining the data representation and mutation/crossover operators";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A (symmetric) absolute range limit.
|
* A (symmetric) absolute range limit.
|
||||||
@ -313,6 +366,7 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
|
|||||||
public double getDefaultRange() {
|
public double getDefaultRange() {
|
||||||
return m_DefaultRange;
|
return m_DefaultRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a (symmetric) absolute range limit.
|
* Set a (symmetric) absolute range limit.
|
||||||
*
|
*
|
||||||
@ -322,64 +376,73 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
|
|||||||
this.m_DefaultRange = defaultRange;
|
this.m_DefaultRange = defaultRange;
|
||||||
initTemplate();
|
initTemplate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String defaultRangeTipText() {
|
public String defaultRangeTipText() {
|
||||||
return "Absolute limit for the symmetric range in any dimension";
|
return "Absolute limit for the symmetric range in any dimension";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDoRotation(boolean doRotation) {
|
public void setDoRotation(boolean doRotation) {
|
||||||
this.doRotation = doRotation;
|
this.doRotation = doRotation;
|
||||||
if (!doRotation) rotation=null;
|
if (!doRotation)
|
||||||
|
rotation = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDoRotation() {
|
public boolean isDoRotation() {
|
||||||
return doRotation;
|
return doRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String doRotationTipText() {
|
public String doRotationTipText() {
|
||||||
return "If marked, the function is rotated by 22.5 degrees along every axis.";
|
return "If marked, the function is rotated by 22.5 degrees along every axis.";
|
||||||
}
|
}
|
||||||
/**********************************************************************************************************************
|
|
||||||
* These are for InterfaceParamControllable
|
/**********************************************************************************************************************
|
||||||
*/
|
* These are for InterfaceParamControllable
|
||||||
|
*/
|
||||||
public Object[] getParamControl() {
|
public Object[] getParamControl() {
|
||||||
if (isWithConstraints()) {
|
if (isWithConstraints()) {
|
||||||
return constraintArray;
|
return constraintArray;
|
||||||
// return constraintList.getObjects();
|
// return constraintList.getObjects();
|
||||||
} else return null;
|
} else
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
/**********************************************************************************************************************
|
|
||||||
* These are for Interface2DBorderProblem
|
|
||||||
*/
|
|
||||||
public double[][] get2DBorder() {
|
|
||||||
return makeRange();
|
|
||||||
}
|
|
||||||
|
|
||||||
public double[] project2DPoint(double[] point) {
|
/**********************************************************************************************************************
|
||||||
return Mathematics.expandVector(point, getProblemDimension(), 0.);
|
* These are for Interface2DBorderProblem
|
||||||
}
|
*/
|
||||||
|
public double[][] get2DBorder() {
|
||||||
|
return makeRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double[] project2DPoint(double[] point) {
|
||||||
|
return Mathematics.expandVector(point, getProblemDimension(), 0.);
|
||||||
|
}
|
||||||
|
|
||||||
public double functionValue(double[] point) {
|
public double functionValue(double[] point) {
|
||||||
double[] x=project2DPoint(point);
|
double[] x = project2DPoint(point);
|
||||||
double v = eval(x)[0];
|
double v = eval(x)[0];
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a position as a known optimum to a list of optima. This method evaluates the fitness
|
* Add a position as a known optimum to a list of optima. This method
|
||||||
* and applies inverse rotation if necessary.
|
* evaluates the fitness and applies inverse rotation if necessary.
|
||||||
*
|
*
|
||||||
* @param optimas
|
* @param optimas
|
||||||
* @param prob
|
* @param prob
|
||||||
* @param pos
|
* @param pos
|
||||||
*/
|
*/
|
||||||
public static void addUnrotatedOptimum(Population optimas, AbstractProblemDouble prob, double[] pos) {
|
public static void addUnrotatedOptimum(Population optimas,
|
||||||
|
AbstractProblemDouble prob, double[] pos) {
|
||||||
InterfaceDataTypeDouble tmpIndy;
|
InterfaceDataTypeDouble tmpIndy;
|
||||||
tmpIndy = (InterfaceDataTypeDouble)prob.getIndividualTemplate().clone();
|
tmpIndy = (InterfaceDataTypeDouble) prob.getIndividualTemplate()
|
||||||
|
.clone();
|
||||||
tmpIndy.SetDoubleGenotype(pos);
|
tmpIndy.SetDoubleGenotype(pos);
|
||||||
if (prob.isDoRotation()) {
|
if (prob.isDoRotation()) {
|
||||||
pos = prob.inverseRotateMaybe(pos); // theres an inverse rotation required
|
pos = prob.inverseRotateMaybe(pos); // theres an inverse rotation
|
||||||
|
// required
|
||||||
tmpIndy.SetDoubleGenotype(pos);
|
tmpIndy.SetDoubleGenotype(pos);
|
||||||
}
|
}
|
||||||
((AbstractEAIndividual)tmpIndy).SetFitness(prob.eval(pos));
|
((AbstractEAIndividual) tmpIndy).SetFitness(prob.eval(pos));
|
||||||
if (!Mathematics.isInRange(pos, prob.makeRange())) {
|
if (!Mathematics.isInRange(pos, prob.makeRange())) {
|
||||||
System.err.println("Warning, add optimum which is out of range!");
|
System.err.println("Warning, add optimum which is out of range!");
|
||||||
}
|
}
|
||||||
@ -388,36 +451,43 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Refine a potential solution using Nelder-Mead-Simplex.
|
* Refine a potential solution using Nelder-Mead-Simplex.
|
||||||
|
*
|
||||||
* @param prob
|
* @param prob
|
||||||
* @param pos
|
* @param pos
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static double[] refineSolutionNMS(AbstractProblemDouble prob, double[] pos) {
|
public static double[] refineSolutionNMS(AbstractProblemDouble prob,
|
||||||
|
double[] pos) {
|
||||||
Population pop = new Population();
|
Population pop = new Population();
|
||||||
InterfaceDataTypeDouble tmpIndy;
|
InterfaceDataTypeDouble tmpIndy;
|
||||||
tmpIndy = (InterfaceDataTypeDouble)prob.getIndividualTemplate().clone();
|
tmpIndy = (InterfaceDataTypeDouble) prob.getIndividualTemplate()
|
||||||
|
.clone();
|
||||||
tmpIndy.SetDoubleGenotype(pos);
|
tmpIndy.SetDoubleGenotype(pos);
|
||||||
((AbstractEAIndividual)tmpIndy).SetFitness(prob.eval(pos));
|
((AbstractEAIndividual) tmpIndy).SetFitness(prob.eval(pos));
|
||||||
pop.add(tmpIndy);
|
pop.add(tmpIndy);
|
||||||
FitnessConvergenceTerminator convTerm = new FitnessConvergenceTerminator(1e-25, 10, StagnationTypeEnum.generationBased, ChangeTypeEnum.absoluteChange, DirectionTypeEnum.decrease);
|
FitnessConvergenceTerminator convTerm = new FitnessConvergenceTerminator(
|
||||||
int calls = PostProcess.processSingleCandidatesNMCMA(PostProcessMethod.nelderMead, pop, convTerm, 0.001, prob);
|
1e-25, 10, StagnationTypeEnum.generationBased,
|
||||||
return ((InterfaceDataTypeDouble)pop.getBestEAIndividual()).getDoubleData();
|
ChangeTypeEnum.absoluteChange, DirectionTypeEnum.decrease);
|
||||||
|
int calls = PostProcess.processSingleCandidatesNMCMA(
|
||||||
|
PostProcessMethod.nelderMead, pop, convTerm, 0.001, prob);
|
||||||
|
return ((InterfaceDataTypeDouble) pop.getBestEAIndividual())
|
||||||
|
.getDoubleData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refine a candidate solution vector regarding rotations. Saves the
|
* Refine a candidate solution vector regarding rotations. Saves the new
|
||||||
* new solution vector in pos and returns the number of dimensions
|
* solution vector in pos and returns the number of dimensions that had to
|
||||||
* that had to be modified after rotation due to range restrictions.
|
* be modified after rotation due to range restrictions.
|
||||||
*
|
*
|
||||||
* The given position is expected to be unrotated! The returned solution
|
* The given position is expected to be unrotated! The returned solution is
|
||||||
* is unrotated as well.
|
* unrotated as well.
|
||||||
*
|
*
|
||||||
* @param pos
|
* @param pos
|
||||||
* @param prob
|
* @param prob
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static int refineWithRotation(double[] pos, AbstractProblemDouble prob) {
|
public static int refineWithRotation(double[] pos,
|
||||||
|
AbstractProblemDouble prob) {
|
||||||
double[] res = prob.inverseRotateMaybe(pos);
|
double[] res = prob.inverseRotateMaybe(pos);
|
||||||
int modifiedInPrjct = Mathematics.projectToRange(res, prob.makeRange());
|
int modifiedInPrjct = Mathematics.projectToRange(res, prob.makeRange());
|
||||||
res = AbstractProblemDouble.refineSolutionNMS(prob, res);
|
res = AbstractProblemDouble.refineSolutionNMS(prob, res);
|
||||||
@ -426,51 +496,56 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
|
|||||||
return modifiedInPrjct;
|
return modifiedInPrjct;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************
|
/**********************************************************************************************************************
|
||||||
* These are for GUI
|
* These are for GUI
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method allows the GUI to read the
|
* This method allows the GUI to read the name to the current object.
|
||||||
* name to the current object.
|
*
|
||||||
* @return the name of the object
|
* @return the name of the object
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "AbstractProblemDouble";
|
return "AbstractProblemDouble";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns a global info string.
|
* This method returns a global info string.
|
||||||
* @return description
|
*
|
||||||
*/
|
* @return description
|
||||||
public static String globalInfo() {
|
*/
|
||||||
return "The programmer did not give further details.";
|
public static String globalInfo() {
|
||||||
}
|
return "The programmer did not give further details.";
|
||||||
|
}
|
||||||
|
|
||||||
/** This method returns a string describing the optimization problem.
|
/**
|
||||||
* @param opt The Optimizer that is used or had been used.
|
* This method returns a string describing the optimization problem.
|
||||||
* @return The description.
|
*
|
||||||
*/
|
* @param opt
|
||||||
public String getStringRepresentationForProblem(InterfaceOptimizer opt) {
|
* The Optimizer that is used or had been used.
|
||||||
StringBuffer sb = new StringBuffer(200);
|
* @return The description.
|
||||||
sb.append("A double valued problem: ");
|
*/
|
||||||
sb.append(this.getName());
|
public String getStringRepresentationForProblem(InterfaceOptimizer opt) {
|
||||||
sb.append("\n");
|
StringBuffer sb = new StringBuffer(200);
|
||||||
sb.append(globalInfo());
|
sb.append("A double valued problem: ");
|
||||||
sb.append("Dimension : ");
|
sb.append(this.getName());
|
||||||
sb.append(this.getProblemDimension());
|
sb.append("\n");
|
||||||
sb.append("\nNoise level : ");
|
sb.append(globalInfo());
|
||||||
sb.append(this.m_Noise);
|
sb.append("Dimension : ");
|
||||||
return sb.toString();
|
sb.append(this.getProblemDimension());
|
||||||
}
|
sb.append("\nNoise level : ");
|
||||||
|
sb.append(this.m_Noise);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
// public PropertySelectableList<AbstractConstraint> getConstraints() {
|
// public PropertySelectableList<AbstractConstraint> getConstraints() {
|
||||||
// return constraintList;
|
// return constraintList;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// public void setConstraints(PropertySelectableList<AbstractConstraint> constraintArray) {
|
// public void setConstraints(PropertySelectableList<AbstractConstraint>
|
||||||
// this.constraintList = constraintArray;
|
// constraintArray) {
|
||||||
// }
|
// this.constraintList = constraintArray;
|
||||||
|
// }
|
||||||
|
|
||||||
public AbstractConstraint[] getConstraints() {
|
public AbstractConstraint[] getConstraints() {
|
||||||
return constraintArray;
|
return constraintArray;
|
||||||
@ -490,7 +565,8 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
|
|||||||
|
|
||||||
public void setWithConstraints(boolean withConstraints) {
|
public void setWithConstraints(boolean withConstraints) {
|
||||||
this.withConstraints = withConstraints;
|
this.withConstraints = withConstraints;
|
||||||
GenericObjectEditor.setShowProperty(this.getClass(), "constraints", withConstraints);
|
GenericObjectEditor.setShowProperty(this.getClass(), "constraints",
|
||||||
|
withConstraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String withConstraintsTipText() {
|
public String withConstraintsTipText() {
|
||||||
@ -500,59 +576,79 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
|
|||||||
@Override
|
@Override
|
||||||
public String[] getAdditionalFileStringHeader(PopulationInterface pop) {
|
public String[] getAdditionalFileStringHeader(PopulationInterface pop) {
|
||||||
String[] superHeader = super.getAdditionalFileStringHeader(pop);
|
String[] superHeader = super.getAdditionalFileStringHeader(pop);
|
||||||
if (isWithConstraints()) return ToolBox.appendArrays(superHeader, new String[]{"rawFit","numViol","sumViol"});
|
if (isWithConstraints())
|
||||||
else return superHeader;
|
return ToolBox.appendArrays(superHeader, new String[] { "rawFit",
|
||||||
|
"numViol", "sumViol" });
|
||||||
|
else
|
||||||
|
return superHeader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getAdditionalFileStringInfo(PopulationInterface pop) {
|
public String[] getAdditionalFileStringInfo(PopulationInterface pop) {
|
||||||
String[] superInfo = super.getAdditionalFileStringInfo(pop);
|
String[] superInfo = super.getAdditionalFileStringInfo(pop);
|
||||||
if (isWithConstraints())
|
if (isWithConstraints())
|
||||||
return ToolBox.appendArrays(superInfo, new String[]{"Raw fitness (unpenalized) of the current best individual",
|
return ToolBox
|
||||||
"The number of constraints violated by the current best individual",
|
.appendArrays(
|
||||||
"The sum of constraint violations of the current best individual"});
|
superInfo,
|
||||||
else return superInfo;
|
new String[] {
|
||||||
|
"Raw fitness (unpenalized) of the current best individual",
|
||||||
|
"The number of constraints violated by the current best individual",
|
||||||
|
"The sum of constraint violations of the current best individual" });
|
||||||
|
else
|
||||||
|
return superInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] getAdditionalFileStringValue(PopulationInterface pop) {
|
public Object[] getAdditionalFileStringValue(PopulationInterface pop) {
|
||||||
Object[] superVal = super.getAdditionalFileStringValue(pop);
|
Object[] superVal = super.getAdditionalFileStringValue(pop);
|
||||||
if (isWithConstraints()) {
|
if (isWithConstraints()) {
|
||||||
AbstractEAIndividual indy = (AbstractEAIndividual)pop.getBestIndividual();
|
AbstractEAIndividual indy = (AbstractEAIndividual) pop
|
||||||
Pair<Integer,Double> violation= getConstraintViolation(indy);
|
.getBestIndividual();
|
||||||
return ToolBox.appendArrays(superVal, new Object[]{indy.getData(rawFitKey),
|
Pair<Integer, Double> violation = getConstraintViolation(indy);
|
||||||
violation.head(),
|
return ToolBox.appendArrays(superVal,
|
||||||
violation.tail()});
|
new Object[] { indy.getData(rawFitKey), violation.head(),
|
||||||
// return superVal + " \t" + BeanInspector.toString(indy.getData(rawFitKey)) + " \t" + violation.head() + " \t" + violation.tail();
|
violation.tail() });
|
||||||
} else return superVal;
|
// return superVal + " \t" +
|
||||||
|
// BeanInspector.toString(indy.getData(rawFitKey)) + " \t" +
|
||||||
|
// violation.head() + " \t" + violation.tail();
|
||||||
|
} else
|
||||||
|
return superVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Pair<Integer,Double> getConstraintViolation(AbstractEAIndividual indy) {
|
protected Pair<Integer, Double> getConstraintViolation(
|
||||||
double sum=0;
|
AbstractEAIndividual indy) {
|
||||||
int numViol=0;
|
double sum = 0;
|
||||||
|
int numViol = 0;
|
||||||
for (AbstractConstraint constr : constraintArray) {
|
for (AbstractConstraint constr : constraintArray) {
|
||||||
double v= constr.getViolation(getEvalArray(indy));
|
double v = constr.getViolation(getEvalArray(indy));
|
||||||
if (v>0) numViol++;
|
if (v > 0)
|
||||||
|
numViol++;
|
||||||
sum += v;
|
sum += v;
|
||||||
}
|
}
|
||||||
return new Pair<Integer,Double>(numViol, sum);
|
return new Pair<Integer, Double>(numViol, sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isShowPlot() {
|
public boolean isShowPlot() {
|
||||||
return isShowing ;
|
return isShowing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setShowPlot(boolean showP) {
|
public void setShowPlot(boolean showP) {
|
||||||
if (!isShowing && showP) {
|
if (!isShowing && showP) {
|
||||||
TopoPlot plot = new TopoPlot(getName(), "x1", "x2");
|
TopoPlot plot = new TopoPlot(getName(), "x1", "x2");
|
||||||
plot.setParams(60,60, ColorBarCalculator.BLUE_TO_RED);
|
plot.setParams(60, 60, ColorBarCalculator.BLUE_TO_RED);
|
||||||
this.initProblem();
|
this.initProblem();
|
||||||
plot.setTopology(this, makeRange(), true);
|
plot.setTopology(this, makeRange(), true);
|
||||||
if (this instanceof InterfaceMultimodalProblemKnown && ((InterfaceMultimodalProblemKnown)this).fullListAvailable()) {
|
if (this instanceof InterfaceMultimodalProblemKnown
|
||||||
plot.drawPopulation("Opt", ((InterfaceMultimodalProblemKnown)this).getRealOptima());
|
&& ((InterfaceMultimodalProblemKnown) this)
|
||||||
|
.fullListAvailable()) {
|
||||||
|
plot.drawPopulation("Opt",
|
||||||
|
((InterfaceMultimodalProblemKnown) this)
|
||||||
|
.getRealOptima());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isShowing = showP;
|
isShowing = showP;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String showPlotTipText() {
|
public String showPlotTipText() {
|
||||||
return "Produce an exemplary 2D plot of the function (dimensional cut at x_i=0 for n>1).";
|
return "Produce an exemplary 2D plot of the function (dimensional cut at x_i=0 for n>1).";
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user