aboutsummaryrefslogtreecommitdiffstats
path: root/src/jcgp/backend/modules/problem/SymbolicRegressionProblem.java
diff options
context:
space:
mode:
authorEduardo Pedroni <ep625@york.ac.uk>2014-05-01 13:05:27 +0100
committerEduardo Pedroni <ep625@york.ac.uk>2014-05-01 13:05:27 +0100
commit36f4393bcc9e55afa2334baa33e603ce839741a1 (patch)
treed9a1d55d0d3553193a3fc11a92f11515762d202f /src/jcgp/backend/modules/problem/SymbolicRegressionProblem.java
parent4c8de2402f2878cde7587c7f3bbf4ffaea86efd4 (diff)
Did more commenting, implemented reflection and statistics
Diffstat (limited to 'src/jcgp/backend/modules/problem/SymbolicRegressionProblem.java')
-rw-r--r--src/jcgp/backend/modules/problem/SymbolicRegressionProblem.java72
1 files changed, 54 insertions, 18 deletions
diff --git a/src/jcgp/backend/modules/problem/SymbolicRegressionProblem.java b/src/jcgp/backend/modules/problem/SymbolicRegressionProblem.java
index 5468157..04e9fe8 100644
--- a/src/jcgp/backend/modules/problem/SymbolicRegressionProblem.java
+++ b/src/jcgp/backend/modules/problem/SymbolicRegressionProblem.java
@@ -1,24 +1,54 @@
package jcgp.backend.modules.problem;
import jcgp.backend.function.SymbolicRegressionFunctions;
+import jcgp.backend.parameters.BooleanParameter;
+import jcgp.backend.parameters.DoubleParameter;
+import jcgp.backend.parameters.ParameterStatus;
import jcgp.backend.population.Chromosome;
import jcgp.backend.population.Population;
import jcgp.backend.resources.Resources;
-import jcgp.backend.resources.parameters.BooleanParameter;
-import jcgp.backend.resources.parameters.DoubleParameter;
-import jcgp.backend.resources.parameters.Parameter;
-import jcgp.backend.resources.parameters.ParameterStatus;
+/**
+ * Symbolic regression functions
+ * <br><br>
+ * Using this problem type, regression problems can be solved.
+ * {@code parseData()} must be used to load the desired function
+ * data in the standard CGP .dat format.
+ * <br><br>
+ * This problem uses quite a few parameters:
+ * <ul>
+ * <li>Error threshold: the maximum difference allowed between an
+ * evolved output and the equivalent output from the problem data.
+ * Outputs within the error threshold will be considered correct.
+ * This is only used if HITS is enabled.</li>
+ * <li>Perfection threshold: if the fitness is calculated without
+ * using the HITS method, it is a decimal value. A solution is
+ * considered perfect when the difference between its fitness and
+ * the maximum possible fitness is within the perfection threshold.</li>
+ * <li>HITS-based fitness: increment the fitness by 1 whenever the
+ * chromosome output is within the error threshold.</li></ul>
+ *
+ *
+ * @see SymbolicRegressionFunctions
+ * @author Eduardo Pedroni
+ *
+ */
public class SymbolicRegressionProblem extends TestCaseProblem<Double> {
private DoubleParameter errorThreshold, perfectionThreshold;
private BooleanParameter hitsBasedFitness;
-
+
+ /**
+ * Creates a new instance of SymbolicRegressionProblem.
+ *
+ * @param resources a reference to the experiment's resources.
+ */
public SymbolicRegressionProblem(Resources resources) {
super(resources);
- functionSet = new SymbolicRegressionFunctions();
- setProblemName("Symbolic regression");
+ setFunctionSet(new SymbolicRegressionFunctions());
+ setName("Symbolic regression");
setFileExtension(".dat");
+
errorThreshold = new DoubleParameter(0.01, "Error threshold") {
@Override
public void validate(Number newValue) {
@@ -33,6 +63,7 @@ public class SymbolicRegressionProblem extends TestCaseProblem<Double> {
}
}
};
+
perfectionThreshold = new DoubleParameter(0.000001, "Perfection threshold") {
@Override
public void validate(Number newValue) {
@@ -47,12 +78,10 @@ public class SymbolicRegressionProblem extends TestCaseProblem<Double> {
}
}
};
- hitsBasedFitness = new BooleanParameter(true, "HITS-based fitness") {
- @Override
- public void validate(Boolean newValue) {
- // blank
- }
- };
+
+ hitsBasedFitness = new BooleanParameter(true, "HITS-based fitness");
+
+ registerParameters(errorThreshold, perfectionThreshold, hitsBasedFitness);
}
@Override
@@ -75,7 +104,6 @@ public class SymbolicRegressionProblem extends TestCaseProblem<Double> {
} else {
fitness += 1 - Math.abs(cgpValue - dataValue);
}
-
}
}
// assign the resulting fitness to the respective individual
@@ -87,7 +115,8 @@ public class SymbolicRegressionProblem extends TestCaseProblem<Double> {
}
@Override
- public void addTestCase(String[] inputs, String[] outputs) {
+ public TestCase<Double> parseTestCase(String[] inputs, String[] outputs) {
+ // cast the test case values to UnsignedInteger
Double[] inputCases = new Double[inputs.length];
Double[] outputCases = new Double[outputs.length];
for (int i = 0; i < inputCases.length; i++) {
@@ -97,16 +126,23 @@ public class SymbolicRegressionProblem extends TestCaseProblem<Double> {
outputCases[o] = Double.parseDouble(outputs[o]);
}
- addTestCase(new TestCase<Double>(inputCases, outputCases));
+ return new TestCase<Double>(inputCases, outputCases);
}
@Override
public boolean isPerfectSolution(Chromosome fittest) {
+ // higher fitness is better
return fittest.getFitness() >= maxFitness.get() - perfectionThreshold.get();
}
@Override
- public Parameter<?>[] getLocalParameters() {
- return new Parameter[]{maxFitness, errorThreshold, perfectionThreshold, hitsBasedFitness};
+ public boolean isImprovement(Chromosome fittest) {
+ // higher fitness is better
+ if (fittest.getFitness() > bestFitness.get()) {
+ bestFitness.set(fittest.getFitness());
+ return true;
+ } else {
+ return false;
+ }
}
}