Updating two metrics

This commit is contained in:
Marcel Kronfeld 2011-05-03 12:33:22 +00:00
parent ae46d9a3d7
commit 0438ee5055
2 changed files with 67 additions and 20 deletions

View File

@ -3,6 +3,7 @@ package eva2.server.go.operators.distancemetric;
import java.io.Serializable; import java.io.Serializable;
import eva2.server.go.individuals.AbstractEAIndividual; import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeDouble;
/** /**
* The Euclidean metric just measures the Euclidean distance based on the default double representation * The Euclidean metric just measures the Euclidean distance based on the default double representation
@ -13,28 +14,38 @@ import eva2.server.go.individuals.AbstractEAIndividual;
* *
*/ */
public class EuclideanMetric implements InterfaceDistanceMetric, Serializable { public class EuclideanMetric implements InterfaceDistanceMetric, Serializable {
private boolean normedByDblRange = false;
public Object clone() { public Object clone() {
return (Object) new EuclideanMetric(this); return (Object) new EuclideanMetric(this);
} }
public EuclideanMetric(EuclideanMetric a) { public EuclideanMetric(EuclideanMetric a) {
this.setNormedByDblRange(a.isNormedByDblRange());
} }
public EuclideanMetric() { public EuclideanMetric() {
} }
public EuclideanMetric(boolean normed) {
setNormedByDblRange(normed);
}
public double distance(AbstractEAIndividual indy1, AbstractEAIndividual indy2) { public double distance(AbstractEAIndividual indy1, AbstractEAIndividual indy2) {
double[] dIndy1, dIndy2; double[] dIndy1, dIndy2;
double result = 0; double result = 0;
dIndy1 = AbstractEAIndividual.getDoublePositionShallow(indy1); dIndy1 = AbstractEAIndividual.getDoublePositionShallow(indy1);
dIndy2 = AbstractEAIndividual.getDoublePositionShallow(indy2); dIndy2 = AbstractEAIndividual.getDoublePositionShallow(indy2);
if (isNormedByDblRange()) {
for (int i = 0; (i < dIndy1.length) && (i < dIndy2.length); i++) { double[][] range1 = ((InterfaceDataTypeDouble)indy1).getDoubleRange();
result += Math.pow((dIndy1[i] - dIndy2[i]), 2); double[][] range2 = ((InterfaceDataTypeDouble)indy2).getDoubleRange();
return normedEuclideanDistance(dIndy1, range1, dIndy2, range2);
} else {
for (int i = 0; (i < dIndy1.length) && (i < dIndy2.length); i++) {
result += Math.pow((dIndy1[i] - dIndy2[i]), 2);
}
return Math.sqrt(result);
} }
return Math.sqrt(result);
} }
/** /**
@ -87,5 +98,15 @@ public class EuclideanMetric implements InterfaceDistanceMetric, Serializable {
public String getName() { public String getName() {
return "Euclidean Metric"; return "Euclidean Metric";
} }
public void setNormedByDblRange(boolean normedByDblRange) {
this.normedByDblRange = normedByDblRange;
}
public boolean isNormedByDblRange() {
return normedByDblRange;
}
public String normedByDblRangeTipText() {
return "Set to true to norm the distance by the double range - only possible with InterfaceDataTypeDouble individuals.";
}
} }

View File

@ -9,13 +9,16 @@ import eva2.tools.EVAERROR;
/** /**
* Define a metric on data stored within individuals, such as the personal best position * Define a metric on data stored within individuals, such as the personal best position
* in PSO. * in PSO. The metric tries to set the stored data as double position to an indy clone.
* On these clones, the base metric is applied.
*
* @author mkron * @author mkron
* *
*/ */
public class IndividualDataMetric implements InterfaceDistanceMetric, Serializable { public class IndividualDataMetric implements InterfaceDistanceMetric, Serializable {
private String dataKey = ParticleSwarmOptimization.partBestPosKey; private String dataKey = ParticleSwarmOptimization.partBestPosKey;
private boolean normedDistance = true; // flag whether to use normed distances (for InterfaceDataTypeDouble) // private boolean normedDistance = true; // flag whether to use normed distances (for InterfaceDataTypeDouble)
private InterfaceDistanceMetric baseMetric = new EuclideanMetric(true);
public IndividualDataMetric() {} public IndividualDataMetric() {}
@ -23,7 +26,15 @@ public class IndividualDataMetric implements InterfaceDistanceMetric, Serializab
dataKey = key; dataKey = key;
} }
public IndividualDataMetric(IndividualDataMetric pBestMetric) { public IndividualDataMetric(String key, InterfaceDistanceMetric bMetric) {
dataKey = key;
setBaseMetric(bMetric);
}
public IndividualDataMetric(IndividualDataMetric o) {
this.dataKey = o.dataKey;
// this.normedDistance = o.normedDistance;
this.setBaseMetric(o.getBaseMetric());
} }
/** This method allows you to make a deep clone of /** This method allows you to make a deep clone of
@ -40,11 +51,16 @@ public class IndividualDataMetric implements InterfaceDistanceMetric, Serializab
Object data1 = indy1.getData(dataKey); Object data1 = indy1.getData(dataKey);
Object data2 = indy2.getData(dataKey); Object data2 = indy2.getData(dataKey);
if (data1 instanceof double[] && (data2 instanceof double[])) { if (data1 instanceof double[] && (data2 instanceof double[])) {
if (normedDistance) { AbstractEAIndividual dataIndy1 = (AbstractEAIndividual) indy1.clone();
double[][] range1 = ((InterfaceDataTypeDouble)indy1).getDoubleRange(); AbstractEAIndividual.setDoublePosition(dataIndy1, (double[]) data1);
double[][] range2 = ((InterfaceDataTypeDouble)indy2).getDoubleRange(); AbstractEAIndividual dataIndy2 = (AbstractEAIndividual) indy2.clone();
return EuclideanMetric.normedEuclideanDistance((double[])data1, range1, (double[])data2, range2); AbstractEAIndividual.setDoublePosition(dataIndy2, (double[]) data2);
} else return EuclideanMetric.euclideanDistance((double[])data1, (double[])data2); return getBaseMetric().distance(dataIndy1, dataIndy2);
// if (normedDistance) {
// double[][] range1 = ((InterfaceDataTypeDouble)indy1).getDoubleRange();
// double[][] range2 = ((InterfaceDataTypeDouble)indy2).getDoubleRange();
// return EuclideanMetric.normedEuclideanDistance((double[])data1, range1, (double[])data2, range2);
// } else return EuclideanMetric.euclideanDistance((double[])data1, (double[])data2);
} else { } else {
EVAERROR.errorMsgOnce("Error, invalid key data, double array required by " + this.getClass().getName()); EVAERROR.errorMsgOnce("Error, invalid key data, double array required by " + this.getClass().getName());
EVAERROR.errorMsgOnce("Using PhenotypeMetric as Backup..."); EVAERROR.errorMsgOnce("Using PhenotypeMetric as Backup...");
@ -67,14 +83,24 @@ public class IndividualDataMetric implements InterfaceDistanceMetric, Serializab
public String normedDistanceTipText() { public String normedDistanceTipText() {
return "Flag whether to use euclidean distance directly or normed by the double range."; return "Flag whether to use euclidean distance directly or normed by the double range.";
} }
public boolean isNormedDistance() { // public boolean isNormedDistance() {
return normedDistance; // return normedDistance;
} // }
public void setNormedDistance(boolean normedDistance) { // public void setNormedDistance(boolean normedDistance) {
this.normedDistance = normedDistance; // this.normedDistance = normedDistance;
} // }
public static String globalInfo() { public static String globalInfo() {
return "Uses individual object data (so far only double[]) to calculate the distance."; return "Uses individual object data (so far only double[]) to calculate the distance.";
} }
public void setBaseMetric(InterfaceDistanceMetric baseMetric) {
this.baseMetric = baseMetric;
}
public InterfaceDistanceMetric getBaseMetric() {
return baseMetric;
}
public String baseMetricTipText() {
return "The metric to be used on the stored data objects.";
}
} }