aboutsummaryrefslogtreecommitdiffstats
path: root/src/jcgp/backend/modules/problem
diff options
context:
space:
mode:
Diffstat (limited to 'src/jcgp/backend/modules/problem')
-rw-r--r--src/jcgp/backend/modules/problem/DigitalCircuit.java25
-rw-r--r--src/jcgp/backend/modules/problem/Problem.java20
-rw-r--r--src/jcgp/backend/modules/problem/SymbolicRegression.java26
-rw-r--r--src/jcgp/backend/modules/problem/TestCaseProblem.java156
4 files changed, 227 insertions, 0 deletions
diff --git a/src/jcgp/backend/modules/problem/DigitalCircuit.java b/src/jcgp/backend/modules/problem/DigitalCircuit.java
new file mode 100644
index 0000000..d94197d
--- /dev/null
+++ b/src/jcgp/backend/modules/problem/DigitalCircuit.java
@@ -0,0 +1,25 @@
+package jcgp.backend.modules.problem;
+
+import java.util.ArrayList;
+
+import jcgp.backend.function.BitwiseLogic;
+import jcgp.backend.resources.Resources;
+
+public class DigitalCircuit extends TestCaseProblem<Integer> {
+
+ public DigitalCircuit(Resources resources) {
+ super(resources);
+ functionSet = new BitwiseLogic();
+
+ ArrayList<TestCase<Integer>> tc = new ArrayList<TestCase<Integer>>();
+ tc.add(new TestCase<Integer>(new Integer[]{1, 2, 3}, new Integer[]{-4, 5, 6}));
+
+ setTestCases(tc);
+ }
+
+ @Override
+ public String toString() {
+ return "Digital circuit";
+ }
+
+}
diff --git a/src/jcgp/backend/modules/problem/Problem.java b/src/jcgp/backend/modules/problem/Problem.java
new file mode 100644
index 0000000..d01f5b0
--- /dev/null
+++ b/src/jcgp/backend/modules/problem/Problem.java
@@ -0,0 +1,20 @@
+package jcgp.backend.modules.problem;
+
+import jcgp.backend.function.FunctionSet;
+import jcgp.backend.modules.Module;
+import jcgp.backend.population.Chromosome;
+import jcgp.backend.population.Population;
+import jcgp.backend.resources.Resources;
+
+public abstract class Problem implements Module {
+
+ protected FunctionSet functionSet;
+
+ public abstract void evaluate(Population population, Resources resources);
+
+ public FunctionSet getFunctionSet() {
+ return functionSet;
+ }
+
+ public abstract boolean isPerfectSolution(Chromosome fittest);
+}
diff --git a/src/jcgp/backend/modules/problem/SymbolicRegression.java b/src/jcgp/backend/modules/problem/SymbolicRegression.java
new file mode 100644
index 0000000..c92d183
--- /dev/null
+++ b/src/jcgp/backend/modules/problem/SymbolicRegression.java
@@ -0,0 +1,26 @@
+package jcgp.backend.modules.problem;
+
+import java.util.ArrayList;
+
+import jcgp.backend.function.IntegerArithmetic;
+import jcgp.backend.resources.Resources;
+
+public class SymbolicRegression extends TestCaseProblem<Integer> {
+
+ public SymbolicRegression(Resources resources) {
+ super(resources);
+ functionSet = new IntegerArithmetic();
+
+ ArrayList<TestCase<Integer>> tc = new ArrayList<TestCase<Integer>>();
+ tc.add(new TestCase<Integer>(new Integer[]{1, 2, 3}, new Integer[]{-4, 5, 6}));
+ tc.add(new TestCase<Integer>(new Integer[]{3, 2, 5}, new Integer[]{2, 5, 9}));
+
+ setTestCases(tc);
+ }
+
+ @Override
+ public String toString() {
+ return "Symbolic regression";
+ }
+
+}
diff --git a/src/jcgp/backend/modules/problem/TestCaseProblem.java b/src/jcgp/backend/modules/problem/TestCaseProblem.java
new file mode 100644
index 0000000..68318cf
--- /dev/null
+++ b/src/jcgp/backend/modules/problem/TestCaseProblem.java
@@ -0,0 +1,156 @@
+package jcgp.backend.modules.problem;
+
+import java.util.List;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import jcgp.backend.population.Chromosome;
+import jcgp.backend.population.Population;
+import jcgp.backend.resources.Resources;
+import jcgp.backend.resources.parameters.IntegerParameter;
+import jcgp.backend.resources.parameters.Parameter;
+
+/**
+ *
+ * This fitness function module implements a simple test case evaluator.
+ *
+ * A TestCase object is a
+ *
+ *
+ * @author Eduardo Pedroni
+ *
+ */
+public abstract class TestCaseProblem<U extends Object> extends Problem {
+
+ public static class TestCase<T> {
+ private T[] inputs;
+ private T[] outputs;
+
+ public TestCase(T[] inputs, T[] outputs) {
+ this.inputs = inputs;
+ this.outputs = outputs;
+ }
+
+ public T getInput(int index) {
+ return inputs[index];
+ }
+
+ public T getOutput(int index) {
+ return outputs[index];
+ }
+
+ public T[] getInputs() {
+ return inputs;
+ }
+
+ public T[] getOutputs() {
+ return outputs;
+ }
+ }
+
+ private ObservableList<TestCase<U>> testCases;
+ private IntegerParameter maxFitness;
+ private final int inputCount, outputCount;
+
+ private U type;
+
+ public TestCaseProblem(Resources resources) {
+ super();
+
+ inputCount = resources.inputs();
+ outputCount = resources.outputs();
+
+ maxFitness = new IntegerParameter(0, "Max fitness", true, false) {
+ @Override
+ public void validate(Number newValue) {
+ // blank
+ }
+ };
+ testCases = FXCollections.observableArrayList();
+ //testCases = new ObservableList<TestCase<U>>();
+ }
+
+
+ @Override
+ public void evaluate(Population population, Resources resources) {
+ // for every chromosome in the population
+ for (int i = 0; i < resources.populationSize(); i++) {
+ // assume an initial fitness of 0
+ int fitness = 0;
+ // for each test case
+ for (int t = 0; t < testCases.size(); t++) {
+ population.getChromosome(i).setInputs(testCases.get(t).getInputs());
+ // check each output
+ for (int o = 0; o < resources.outputs(); o++) {
+ if (population.getChromosome(i).getOutput(o).calculate() == testCases.get(t).getOutput(o)) {
+ fitness++;
+ }
+ }
+ }
+ // assign the resulting fitness to the respective individual
+ population.getChromosome(i).setFitness(fitness);
+ }
+ }
+
+ @Override
+ public Parameter<?>[] getLocalParameters() {
+ return new Parameter[]{maxFitness};
+ }
+
+ @Override
+ public boolean isPerfectSolution(Chromosome fittest) {
+ return fittest.getFitness() >= maxFitness.get();
+ }
+
+ private int getMaxFitness() {
+ int fitness = 0;
+
+ for (TestCase<U> tc : testCases) {
+ fitness += tc.getOutputs().length;
+ }
+
+ return fitness;
+ }
+
+ public void setTestCases(List<TestCase<U>> testCases) {
+ this.testCases.clear();
+ this.testCases.addAll(testCases);
+ maxFitness.set(getMaxFitness());
+ }
+
+ public ObservableList<TestCase<U>> getTestCases() {
+ return testCases;
+ }
+
+ public void addTestCase(TestCase<U> testCase) {
+ if (testCase.getInputs().length != inputCount) {
+ throw new IllegalArgumentException("Received test case with " + testCase.getInputs().length +
+ "inputs but need exactly " + inputCount);
+ } else if (testCase.getOutputs().length != outputCount) {
+ throw new IllegalArgumentException("Received test case with " + testCase.getOutputs().length +
+ "outputs but need exactly " + outputCount);
+ } else {
+ this.testCases.add(testCase);
+ maxFitness.set(getMaxFitness());
+ }
+ }
+
+ public void removeTestCase(TestCase<U> testCase) {
+ testCases.remove(testCase);
+ maxFitness.set(getMaxFitness());
+ }
+
+ public int getInputCount() {
+ return inputCount;
+ }
+
+ public int getOutputCount() {
+ return outputCount;
+ }
+
+ public Class<?> getType() {
+ return type.getClass();
+ }
+}
+
+