Added generated serial version identifier.

This commit is contained in:
Andreas Dräger 2010-08-24 14:57:52 +00:00
parent cde9129555
commit 65ce36b901

View File

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