aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEduardo Pedroni <ep625@york.ac.uk>2014-04-07 10:04:05 +0100
committerEduardo Pedroni <ep625@york.ac.uk>2014-04-07 10:04:05 +0100
commit67ace66f66ffaa00e1bd1495c0d406c801e59c5c (patch)
tree337da2ab9bbd5eb41a0a6eafbf783340240bcffe /src
parentefee474689b37f43897b8572cec4e3669874b0d4 (diff)
Refactored problem types
Diffstat (limited to 'src')
-rw-r--r--src/jcgp/JCGP.java55
-rw-r--r--src/jcgp/backend/modules/fitness/DigitalCircuit.java17
-rw-r--r--src/jcgp/backend/modules/fitness/FitnessFunction.java11
-rw-r--r--src/jcgp/backend/modules/fitness/Problem.java20
-rw-r--r--src/jcgp/backend/modules/fitness/SymbolicRegression.java17
-rw-r--r--src/jcgp/backend/modules/fitness/TestCaseProblem.java (renamed from src/jcgp/backend/modules/fitness/testcase/TestCaseEvaluator.java)45
-rw-r--r--src/jcgp/backend/resources/ModifiableResources.java5
-rw-r--r--src/jcgp/backend/resources/Resources.java20
-rw-r--r--src/jcgp/gui/settings/SettingsPane.java45
9 files changed, 148 insertions, 87 deletions
diff --git a/src/jcgp/JCGP.java b/src/jcgp/JCGP.java
index 70b01a8..a19e085 100644
--- a/src/jcgp/JCGP.java
+++ b/src/jcgp/JCGP.java
@@ -1,10 +1,14 @@
package jcgp;
+import java.util.ArrayList;
+
import jcgp.backend.modules.ea.EvolutionaryAlgorithm;
import jcgp.backend.modules.ea.MuPlusLambda;
import jcgp.backend.modules.ea.TournamentSelection;
-import jcgp.backend.modules.fitness.FitnessFunction;
-import jcgp.backend.modules.fitness.testcase.TestCaseEvaluator.TestCase;
+import jcgp.backend.modules.fitness.DigitalCircuit;
+import jcgp.backend.modules.fitness.Problem;
+import jcgp.backend.modules.fitness.SymbolicRegression;
+import jcgp.backend.modules.fitness.TestCaseProblem.TestCase;
import jcgp.backend.modules.mutator.Mutator;
import jcgp.backend.modules.mutator.PointMutator;
import jcgp.backend.population.Population;
@@ -50,30 +54,34 @@ public class JCGP {
new TournamentSelection()};
private EvolutionaryAlgorithm evolutionaryAlgorithm;
- // fitness evaluators
- private FitnessFunction[] fitnessFunctions = new FitnessFunction[] {
- /*new TestCaseEvaluator()*/ };
- private FitnessFunction fitnessFunction;
+ // problem types
+ private Problem[] problems = new Problem[] {
+ new SymbolicRegression(),
+ new DigitalCircuit() };
+ private Problem problem;
/*
* the population of chromosomes
*/
private Population population;
-
private boolean finished = false;
public JCGP() {
+ setEvolutionaryAlgorithm(0);
+ setMutator(0);
+ setProblem(0);
population = new Population(resources);
-
- evolutionaryAlgorithm = evolutionaryAlgorithms[0];
- mutator = mutators[0];
+ ArrayList<TestCase<Integer>> tc = new ArrayList<TestCase<Integer>>();
+ tc.add(new TestCase<Integer>(new Integer[]{1, 2, 3}, new Integer[]{-4, 5, 6}));
- //fitnessFunction = fitnessFunctions[0];
+ ((SymbolicRegression) problem).setTestCases(tc);
- //resources.setTestCases(new TestCase(new Integer[]{1, 2, 3}, new Integer[]{-4, 5, 6}));
-
+ ArrayList<TestCase<Integer>> tcdc = new ArrayList<TestCase<Integer>>();
+ tcdc.add(new TestCase<Integer>(new Integer[]{1, 2, 3}, new Integer[]{-4, 5, 6}));
+
+ ((DigitalCircuit) problems[1]).setTestCases(tc);
}
public ModifiableResources getResources() {
@@ -119,16 +127,16 @@ public class JCGP {
/**
* @return the fitnessFunctions
*/
- public FitnessFunction[] getFitnessFunctions() {
- return fitnessFunctions;
+ public Problem[] getProblems() {
+ return problems;
}
/**
* @return the fitnessFunction
*/
- public FitnessFunction getFitnessFunction() {
- return fitnessFunction;
+ public Problem getProblem() {
+ return problem;
}
@@ -149,21 +157,21 @@ public class JCGP {
/**
- * @param fitnessFunction the fitnessFunction to set
+ * @param problem the fitnessFunction to set
*/
- public void setFitnessFunction(int index) {
- this.fitnessFunction = fitnessFunctions[index];
+ public void setProblem(int index) {
+ this.problem = problems[index];
+ resources.setFunctionSet(problem.getFunctionSet());
}
public void nextGeneration() {
if (!finished) {
- fitnessFunction.evaluate(population, (Resources) resources);
-
+ problem.evaluate(population, (Resources) resources);
report();
if (resources.getInt("currentGen") < resources.getInt("generations")) {
// we still have generations left to go
- if (population.getChromosome(evolutionaryAlgorithm.getFittestChromosome()).getFitness() >= resources.getInt("maxFitness")) {
+ if (problem.isPerfectSolution(population.getChromosome(evolutionaryAlgorithm.getFittestChromosome()))) {
// solution has been found, start next run
resources.println("Solution found on generation " + resources.getInt("currentGen") + ", chromosome: " + evolutionaryAlgorithm.getFittestChromosome());
@@ -181,7 +189,6 @@ public class JCGP {
} else {
resources.set("currentGen", resources.getInt("currentGen") + 1);
}
-
} else {
// the run has ended, check if any more runs must be done
resources.println("Solution not found, highest fitness achieved was "
diff --git a/src/jcgp/backend/modules/fitness/DigitalCircuit.java b/src/jcgp/backend/modules/fitness/DigitalCircuit.java
new file mode 100644
index 0000000..b01bdc5
--- /dev/null
+++ b/src/jcgp/backend/modules/fitness/DigitalCircuit.java
@@ -0,0 +1,17 @@
+package jcgp.backend.modules.fitness;
+
+import jcgp.backend.function.BitwiseLogic;
+
+public class DigitalCircuit extends TestCaseProblem<Integer> {
+
+ public DigitalCircuit() {
+ super();
+ functionSet = new BitwiseLogic();
+ }
+
+ @Override
+ public String toString() {
+ return "Digital circuit";
+ }
+
+}
diff --git a/src/jcgp/backend/modules/fitness/FitnessFunction.java b/src/jcgp/backend/modules/fitness/FitnessFunction.java
deleted file mode 100644
index d3b76cb..0000000
--- a/src/jcgp/backend/modules/fitness/FitnessFunction.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package jcgp.backend.modules.fitness;
-
-import jcgp.backend.modules.Module;
-import jcgp.backend.population.Population;
-import jcgp.backend.resources.Resources;
-
-public interface FitnessFunction extends Module {
-
- public void evaluate(Population population, Resources resources);
-
-}
diff --git a/src/jcgp/backend/modules/fitness/Problem.java b/src/jcgp/backend/modules/fitness/Problem.java
new file mode 100644
index 0000000..1e70c13
--- /dev/null
+++ b/src/jcgp/backend/modules/fitness/Problem.java
@@ -0,0 +1,20 @@
+package jcgp.backend.modules.fitness;
+
+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/fitness/SymbolicRegression.java b/src/jcgp/backend/modules/fitness/SymbolicRegression.java
new file mode 100644
index 0000000..da2e69e
--- /dev/null
+++ b/src/jcgp/backend/modules/fitness/SymbolicRegression.java
@@ -0,0 +1,17 @@
+package jcgp.backend.modules.fitness;
+
+import jcgp.backend.function.IntegerArithmetic;
+
+public class SymbolicRegression extends TestCaseProblem<Integer> {
+
+ public SymbolicRegression() {
+ super();
+ functionSet = new IntegerArithmetic();
+ }
+
+ @Override
+ public String toString() {
+ return "Symbolic regression";
+ }
+
+}
diff --git a/src/jcgp/backend/modules/fitness/testcase/TestCaseEvaluator.java b/src/jcgp/backend/modules/fitness/TestCaseProblem.java
index 4b0654c..7753e26 100644
--- a/src/jcgp/backend/modules/fitness/testcase/TestCaseEvaluator.java
+++ b/src/jcgp/backend/modules/fitness/TestCaseProblem.java
@@ -1,11 +1,13 @@
-package jcgp.backend.modules.fitness.testcase;
+package jcgp.backend.modules.fitness;
import java.util.ArrayList;
-import java.util.Collections;
+import java.util.List;
-import jcgp.backend.modules.fitness.FitnessFunction;
+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;
/**
*
@@ -17,7 +19,7 @@ import jcgp.backend.resources.Resources;
* @author Eduardo Pedroni
*
*/
-public abstract class TestCaseEvaluator implements FitnessFunction {
+public abstract class TestCaseProblem<U> extends Problem {
public static class TestCase<T> {
@@ -46,7 +48,19 @@ public abstract class TestCaseEvaluator implements FitnessFunction {
}
}
- protected ArrayList<TestCase<?>> testCases;
+ private ArrayList<TestCase<U>> testCases;
+ private IntegerParameter maxFitness;
+
+ public TestCaseProblem() {
+ maxFitness = new IntegerParameter(0, "Max fitness", true, false) {
+ @Override
+ public void validate(int newValue) {
+ // blank
+ }
+ };
+ testCases = new ArrayList<TestCase<U>>();
+ }
+
@Override
public void evaluate(Population population, Resources resources) {
@@ -69,19 +83,30 @@ public abstract class TestCaseEvaluator implements FitnessFunction {
}
}
- public int getMaxFitness() {
+ @Override
+ public Parameter[] getLocalParameters() {
+ return new Parameter[]{maxFitness};
+ }
+
+ private int getMaxFitness() {
int fitness = 0;
- for (TestCase<?> tc : testCases) {
+ for (TestCase<U> tc : testCases) {
fitness += tc.getOutputs().length;
}
return fitness;
}
- public void setTestCases(TestCase<?>... testCases) {
- this.testCases = new ArrayList<TestCase<?>>();
- Collections.addAll(this.testCases, testCases);
+ public void setTestCases(List<TestCase<U>> testCases) {
+ this.testCases.clear();
+ this.testCases.addAll(testCases);
+ maxFitness.set(getMaxFitness());
+ }
+
+ @Override
+ public boolean isPerfectSolution(Chromosome fittest) {
+ return fittest.getFitness() >= maxFitness.get();
}
}
diff --git a/src/jcgp/backend/resources/ModifiableResources.java b/src/jcgp/backend/resources/ModifiableResources.java
index 3e6b55e..90c2f03 100644
--- a/src/jcgp/backend/resources/ModifiableResources.java
+++ b/src/jcgp/backend/resources/ModifiableResources.java
@@ -1,5 +1,6 @@
package jcgp.backend.resources;
+import jcgp.backend.function.FunctionSet;
import jcgp.backend.resources.parameters.BooleanParameter;
import jcgp.backend.resources.parameters.DoubleParameter;
import jcgp.backend.resources.parameters.IntegerParameter;
@@ -30,8 +31,8 @@ public class ModifiableResources extends Resources {
}
}
- public void setFunctionSet(int index) {
- functionSet = functionSets[index];
+ public void setFunctionSet(FunctionSet functionSet) {
+ this.functionSet = functionSet;
set("arity", functionSet.getMaxArity());
}
diff --git a/src/jcgp/backend/resources/Resources.java b/src/jcgp/backend/resources/Resources.java
index c1c3e4c..d1f396a 100644
--- a/src/jcgp/backend/resources/Resources.java
+++ b/src/jcgp/backend/resources/Resources.java
@@ -5,11 +5,8 @@ import java.util.Random;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
-import jcgp.backend.function.BitwiseLogic;
-import jcgp.backend.function.BooleanLogic;
import jcgp.backend.function.Function;
import jcgp.backend.function.FunctionSet;
-import jcgp.backend.function.IntegerArithmetic;
import jcgp.backend.resources.parameters.BooleanParameter;
import jcgp.backend.resources.parameters.DoubleParameter;
import jcgp.backend.resources.parameters.IntegerParameter;
@@ -30,12 +27,7 @@ public class Resources {
protected Random numberGenerator = new Random();
- // function sets
- protected FunctionSet[] functionSets = new FunctionSet[] {
- new IntegerArithmetic(),
- new BitwiseLogic(),
- new BooleanLogic() };
- protected FunctionSet functionSet = functionSets[0];
+ protected FunctionSet functionSet;
// GUI console
protected Console console;
@@ -202,7 +194,8 @@ public class Resources {
}
});
- parameters.put("arity", new IntegerParameter(functionSet.getMaxArity(), "Max arity", true, false) {
+ //parameters.put("arity", new IntegerParameter(functionSet.getMaxArity(), "Max arity", true, false) {
+ parameters.put("arity", new IntegerParameter(0, "Max arity", true, false) {
@Override
public void validate(int newValue) {
// blank
@@ -267,13 +260,6 @@ public class Resources {
}
/**
- * @return the functionSets
- */
- public FunctionSet[] getFunctionSets() {
- return functionSets;
- }
-
- /**
* @return the functionSet
*/
public FunctionSet getFunctionSet() {
diff --git a/src/jcgp/gui/settings/SettingsPane.java b/src/jcgp/gui/settings/SettingsPane.java
index 8c707d3..5b23bdd 100644
--- a/src/jcgp/gui/settings/SettingsPane.java
+++ b/src/jcgp/gui/settings/SettingsPane.java
@@ -14,12 +14,11 @@ import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
-import javafx.scene.text.FontSmoothingType;
import javafx.scene.text.Text;
import jcgp.JCGP;
import jcgp.backend.function.FunctionSet;
import jcgp.backend.modules.ea.EvolutionaryAlgorithm;
-import jcgp.backend.modules.fitness.FitnessFunction;
+import jcgp.backend.modules.fitness.Problem;
import jcgp.backend.modules.mutator.Mutator;
import jcgp.backend.resources.parameters.Parameter;
import jcgp.gui.GUI;
@@ -28,7 +27,7 @@ import jcgp.gui.settings.parameters.GUIParameter;
public class SettingsPane extends AnchorPane {
private VBox mainContainer;
- private VBox baseParameterPane, eaPane, mutatorPane, ffPane, nfPane;
+ private VBox baseParameterPane, eaPane, mutatorPane, problemPane;
private Button runPause = new Button("Run"), step = new Button("Step"), reset = new Button("Reset");
@@ -95,7 +94,7 @@ public class SettingsPane extends AnchorPane {
parameters.add(GUIParameter.create(cgp.getResources().getParameter("seed"), this));
parameters.add(GUIParameter.create(cgp.getResources().getParameter("report"), this));
- parameters.add(GUIParameter.create(cgp.getResources().getParameter("maxFitness"), this));
+ //parameters.add(GUIParameter.create(cgp.getResources().getParameter("maxFitness"), this));
baseParameterPane.getChildren().addAll(parameters);
mainContainer.getChildren().add(baseParameterPane);
@@ -138,7 +137,6 @@ public class SettingsPane extends AnchorPane {
mutatorPane = new VBox(2);
Text header = new Text("Mutator");
- header.setFontSmoothingType(FontSmoothingType.LCD);
header.setFont(Font.font("Arial", 14));
header.setUnderline(true);
@@ -156,7 +154,7 @@ public class SettingsPane extends AnchorPane {
mutatorCBox.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
- cgp.setEvolutionaryAlgorithm(mutatorCBox.getSelectionModel().getSelectedIndex());
+ cgp.setMutator(mutatorCBox.getSelectionModel().getSelectedIndex());
if (mutatorCBox.getSelectionModel().getSelectedItem().getLocalParameters() != null) {
refreshParameters(mutatorCBox.getSelectionModel().getSelectedItem().getLocalParameters(), mutatorParameters);
}
@@ -168,39 +166,41 @@ public class SettingsPane extends AnchorPane {
}
private void initialiseProblemTypeParameters(final JCGP cgp, final GUI gui) {
- ffPane= new VBox(2);
+ problemPane= new VBox(2);
Text header = new Text("Problem type");
header.setFont(Font.font("Arial", 14));
header.setUnderline(true);
- final ComboBox<FitnessFunction> ffCBox = new ComboBox<FitnessFunction>();
- ffCBox.getItems().addAll(cgp.getFitnessFunctions());
- ffCBox.getSelectionModel().select(cgp.getFitnessFunction());
+ final ComboBox<Problem> ffCBox = new ComboBox<Problem>();
+ ffCBox.getItems().addAll(cgp.getProblems());
+ ffCBox.getSelectionModel().select(cgp.getProblem());
ffCBox.prefWidthProperty().bind(mainContainer.widthProperty());
final VBox ffParameters = new VBox();
ffParameters.setSpacing(2);
- if (cgp.getFitnessFunction().getLocalParameters() != null) {
- refreshParameters(cgp.getFitnessFunction().getLocalParameters(), ffParameters);
+ if (cgp.getProblem().getLocalParameters() != null) {
+ refreshParameters(cgp.getProblem().getLocalParameters(), ffParameters);
}
+ final VBox nodeFunctions = new VBox();
+ nodeFunctions.setSpacing(2);
+ refreshFunctions(cgp.getResources().getFunctionSet(), nodeFunctions, gui);
+
ffCBox.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
- cgp.setEvolutionaryAlgorithm(ffCBox.getSelectionModel().getSelectedIndex());
+ cgp.setProblem(ffCBox.getSelectionModel().getSelectedIndex());
if (ffCBox.getSelectionModel().getSelectedItem().getLocalParameters() != null) {
- refreshParameters(ffCBox.getSelectionModel().getSelectedItem().getLocalParameters(), ffParameters);
- }
+ refreshParameters(cgp.getProblem().getLocalParameters(), ffParameters);
+ refreshFunctions(cgp.getProblem().getFunctionSet(), nodeFunctions, gui);
+ }
+ gui.reset();
}
});
- final VBox nfParameters = new VBox();
- nfParameters.setSpacing(2);
- refreshFunctions(cgp.getResources().getFunctionSet(), nfParameters, gui);
-
- ffPane.getChildren().addAll(header, ffCBox, ffParameters, nfParameters);
- mainContainer.getChildren().add(ffPane);
+ problemPane.getChildren().addAll(header, ffCBox, ffParameters, nodeFunctions);
+ mainContainer.getChildren().add(problemPane);
}
@@ -293,8 +293,7 @@ public class SettingsPane extends AnchorPane {
baseParameterPane.setDisable(value);
eaPane.setDisable(value);
mutatorPane.setDisable(value);
- ffPane.setDisable(value);
- nfPane.setDisable(value);
+ problemPane.setDisable(value);
step.setDisable(value);
reset.setDisable(value);