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,33 +24,47 @@ 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
// PropertySelectableList<AbstractConstraint>(new AbstractConstraint[]{new
// GenericConstraint()});
private AbstractConstraint[] constraintArray = new AbstractConstraint[] { new GenericConstraint() }; private AbstractConstraint[] constraintArray = new AbstractConstraint[] { new GenericConstraint() };
private boolean withConstraints = false; private boolean withConstraints = false;
private transient boolean isShowing = false; private transient boolean isShowing = false;
@ -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,34 +99,42 @@ 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)
this.m_Template = (AbstractEAIndividual) o.m_Template.clone();
if (o.constraintArray != null) { if (o.constraintArray != null) {
this.constraintArray = o.constraintArray.clone(); this.constraintArray = o.constraintArray.clone();
for (int i=0; i<constraintArray.length; i++) constraintArray[i]=(AbstractConstraint)o.constraintArray[i].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];
System.arraycopy(
((InterfaceDataTypeDouble) individual).getDoubleData(), 0, x,
0, x.length);
return x; 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)
*/ */
@ -121,7 +147,8 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
// 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)
RNG.addNoise(fitness, m_Noise);
// set the fitness // set the fitness
setEvalFitness(individual, x, fitness); setEvalFitness(individual, x, fitness);
if (isWithConstraints()) { if (isWithConstraints()) {
@ -132,7 +159,8 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
protected double[] rotateMaybe(double[] x) { protected double[] rotateMaybe(double[] x) {
if (isDoRotation()) { if (isDoRotation()) {
if (rotation==null) initProblem(); if (rotation == null)
initProblem();
x = Mathematics.rotate(x, rotation); x = Mathematics.rotate(x, rotation);
} }
return x; return x;
@ -140,44 +168,53 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
protected double[] inverseRotateMaybe(double[] x) { protected double[] inverseRotateMaybe(double[] x) {
if (isDoRotation()) { if (isDoRotation()) {
if (rotation==null) initProblem(); if (rotation == null)
initProblem();
x = Mathematics.rotate(x, rotation.inverse()); 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[]{});
// System.out.println("checking constraint " + (name==null ?
// cnstr[i].getClass().getSimpleName() : name));
((AbstractConstraint) cnstr[i]).addViolation(individual, indyPos); ((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
* the vector to evaluate
* @return the target function value * @return the target function value
*/ */
public abstract double[] eval(double[] x); public abstract double[] eval(double[] x);
@ -192,11 +229,13 @@ 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
*/ */
@ -211,7 +250,8 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
/** /**
* 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 makeRange()
* @see getRangeUpperBound(int dim) * @see getRangeUpperBound(int dim)
@ -224,7 +264,8 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
/** /**
* 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 makeRange()
* @see getRangeLowerBound(int dim) * @see getRangeLowerBound(int dim)
@ -239,12 +280,15 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
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
@ -257,7 +301,8 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
// 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.),
dim).transpose();
// double[] t= new double[dim]; Arrays.fill(t, 1.); // double[] t= new double[dim]; Arrays.fill(t, 1.);
// System.out.println(BeanInspector.toString(rotation.times(t))); // System.out.println(BeanInspector.toString(rotation.times(t)));
return rotation; return rotation;
@ -265,20 +310,27 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
/** /**
* 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.
*
* @param noise
* The sigma for a gaussian random number.
*/ */
public void setNoise(double noise) { public void setNoise(double noise) {
if (noise < 0) noise = 0; if (noise < 0)
noise = 0;
this.m_Noise = noise; this.m_Noise = noise;
} }
/** /**
* Get the current noise level. * Get the current noise level.
*
* @return the current noise level * @return the current noise level
*/ */
public double getNoise() { public double getNoise() {
return this.m_Noise; return this.m_Noise;
} }
public String noiseTipText() { public String noiseTipText() {
return "Gaussian noise level on the fitness value."; return "Gaussian noise level on the fitness value.";
} }
@ -286,7 +338,8 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
/** /**
* This method allows you to choose the EA individual used by the problem. * This method allows you to choose the EA individual used by the problem.
* *
* @param indy The EAIndividual type * @param indy
* The EAIndividual type
*/ */
public void setEAIndividual(InterfaceDataTypeDouble indy) { public void setEAIndividual(InterfaceDataTypeDouble indy) {
this.m_Template = (AbstractEAIndividual) indy; this.m_Template = (AbstractEAIndividual) indy;
@ -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,21 +376,25 @@ 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
*/ */
@ -344,8 +402,10 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
if (isWithConstraints()) { if (isWithConstraints()) {
return constraintArray; return constraintArray;
// return constraintList.getObjects(); // return constraintList.getObjects();
} else return null; } else
return null;
} }
/********************************************************************************************************************** /**********************************************************************************************************************
* These are for Interface2DBorderProblem * These are for Interface2DBorderProblem
*/ */
@ -364,19 +424,22 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
} }
/** /**
* 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));
@ -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);
@ -431,8 +501,8 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
*/ */
/** /**
* 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() {
@ -441,14 +511,18 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
/** /**
* This method returns a global info string. * This method returns a global info string.
*
* @return description * @return description
*/ */
public static String globalInfo() { public static String globalInfo() {
return "The programmer did not give further details."; 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.
*
* @param opt
* The Optimizer that is used or had been used.
* @return The description. * @return The description.
*/ */
public String getStringRepresentationForProblem(InterfaceOptimizer opt) { public String getStringRepresentationForProblem(InterfaceOptimizer opt) {
@ -468,7 +542,8 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
// return constraintList; // return constraintList;
// } // }
// //
// public void setConstraints(PropertySelectableList<AbstractConstraint> constraintArray) { // public void setConstraints(PropertySelectableList<AbstractConstraint>
// constraintArray) {
// this.constraintList = constraintArray; // this.constraintList = 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,39 +576,53 @@ 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
.appendArrays(
superInfo,
new String[] {
"Raw fitness (unpenalized) of the current best individual",
"The number of constraints violated by the current best individual", "The number of constraints violated by the current best individual",
"The sum of constraint violations of the current best individual" }); "The sum of constraint violations of the current best individual" });
else return superInfo; 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
.getBestIndividual();
Pair<Integer, Double> violation = getConstraintViolation(indy); Pair<Integer, Double> violation = getConstraintViolation(indy);
return ToolBox.appendArrays(superVal, new Object[]{indy.getData(rawFitKey), return ToolBox.appendArrays(superVal,
violation.head(), new Object[] { indy.getData(rawFitKey), violation.head(),
violation.tail() }); violation.tail() });
// return superVal + " \t" + BeanInspector.toString(indy.getData(rawFitKey)) + " \t" + violation.head() + " \t" + violation.tail(); // return superVal + " \t" +
} else return superVal; // 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(
AbstractEAIndividual indy) {
double sum = 0; double sum = 0;
int numViol = 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);
@ -541,18 +631,24 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem
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).";
} }