aboutsummaryrefslogtreecommitdiffstats
path: root/src/jcgp/backend/resources
diff options
context:
space:
mode:
Diffstat (limited to 'src/jcgp/backend/resources')
-rw-r--r--src/jcgp/backend/resources/Console.java11
-rw-r--r--src/jcgp/backend/resources/ModifiableResources.java42
-rw-r--r--src/jcgp/backend/resources/Resources.java310
-rw-r--r--src/jcgp/backend/resources/parameters/BooleanParameter.java42
-rw-r--r--src/jcgp/backend/resources/parameters/DoubleParameter.java36
-rw-r--r--src/jcgp/backend/resources/parameters/IntegerParameter.java37
-rw-r--r--src/jcgp/backend/resources/parameters/Parameter.java41
-rw-r--r--src/jcgp/backend/resources/parameters/ParameterStatus.java16
8 files changed, 535 insertions, 0 deletions
diff --git a/src/jcgp/backend/resources/Console.java b/src/jcgp/backend/resources/Console.java
new file mode 100644
index 0000000..6bbd5ba
--- /dev/null
+++ b/src/jcgp/backend/resources/Console.java
@@ -0,0 +1,11 @@
+package jcgp.backend.resources;
+
+public interface Console {
+
+ public void println(String s);
+
+ public void print(String s);
+
+ public void flush();
+
+}
diff --git a/src/jcgp/backend/resources/ModifiableResources.java b/src/jcgp/backend/resources/ModifiableResources.java
new file mode 100644
index 0000000..3e6b55e
--- /dev/null
+++ b/src/jcgp/backend/resources/ModifiableResources.java
@@ -0,0 +1,42 @@
+package jcgp.backend.resources;
+
+import jcgp.backend.resources.parameters.BooleanParameter;
+import jcgp.backend.resources.parameters.DoubleParameter;
+import jcgp.backend.resources.parameters.IntegerParameter;
+
+/**
+ *
+ * This subclass of Resources allows modifications to be made.
+ * A read-only cast of this class is passed to modules for safety,
+ * and only classes with access to a JCGP instance may modify
+ * the resources.
+ *
+ * @author eddy
+ *
+ */
+public class ModifiableResources extends Resources {
+
+ public ModifiableResources() {
+ super();
+ }
+
+ public void set(String key, Object value) {
+ if (parameters.get(key) instanceof IntegerParameter) {
+ ((IntegerParameter) parameters.get(key)).set(((Integer) value).intValue());
+ } else if (parameters.get(key) instanceof DoubleParameter) {
+ ((DoubleParameter) parameters.get(key)).set(((Double) value).doubleValue());
+ } else if (parameters.get(key) instanceof BooleanParameter) {
+ ((BooleanParameter) parameters.get(key)).set(((Boolean) value).booleanValue());
+ }
+ }
+
+ public void setFunctionSet(int index) {
+ functionSet = functionSets[index];
+ set("arity", functionSet.getMaxArity());
+ }
+
+ public void setConsole(Console console) {
+ this.console = console;
+ }
+
+}
diff --git a/src/jcgp/backend/resources/Resources.java b/src/jcgp/backend/resources/Resources.java
new file mode 100644
index 0000000..c1c3e4c
--- /dev/null
+++ b/src/jcgp/backend/resources/Resources.java
@@ -0,0 +1,310 @@
+package jcgp.backend.resources;
+
+import java.util.HashMap;
+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;
+import jcgp.backend.resources.parameters.Parameter;
+import jcgp.backend.resources.parameters.ParameterStatus;
+
+/**
+ *
+ * The resources class encapsulates all of the resources based on which the program operates.
+ * Each instance of JCGP contains a single instance of Resources, which gets passed to the selected
+ * modules as the program executes.
+ *
+ * @author Eduardo Pedroni
+ *
+ */
+public class Resources {
+ protected HashMap<String, Parameter> parameters = new HashMap<String, Parameter>();
+
+ protected Random numberGenerator = new Random();
+
+ // function sets
+ protected FunctionSet[] functionSets = new FunctionSet[] {
+ new IntegerArithmetic(),
+ new BitwiseLogic(),
+ new BooleanLogic() };
+ protected FunctionSet functionSet = functionSets[0];
+
+ // GUI console
+ protected Console console;
+
+ public Resources() {
+ createBaseParameters();
+ }
+
+ public int getInt(String key) {
+ if (parameters.get(key) instanceof IntegerParameter) {
+ return ((IntegerParameter) parameters.get(key)).get();
+ } else if (parameters.get(key) instanceof DoubleParameter) {
+ return (int) ((DoubleParameter) parameters.get(key)).get();
+ } else {
+ throw new ClassCastException("Could not cast " + parameters.get(key).getClass() + " to int.");
+ }
+ }
+
+ public double getDouble(String key) {
+ if (parameters.get(key) instanceof IntegerParameter) {
+ return ((IntegerParameter) parameters.get(key)).get();
+ } else if (parameters.get(key) instanceof DoubleParameter) {
+ return ((DoubleParameter) parameters.get(key)).get();
+ } else {
+ throw new ClassCastException("Could not cast " + parameters.get(key).getClass() + " to double.");
+ }
+ }
+
+ public boolean getBoolean(String key) {
+ if (parameters.get(key) instanceof BooleanParameter) {
+ return ((BooleanParameter) parameters.get(key)).get();
+ } else {
+ throw new ClassCastException("Could not cast " + parameters.get(key).getClass() + " to int.");
+ }
+ }
+
+ public Parameter getParameter(String key) {
+ return parameters.get(key);
+ }
+
+ public boolean contains(String key) {
+ return parameters.containsKey(key);
+ }
+
+ private void createBaseParameters() {
+ parameters.put("rows", new IntegerParameter(8, "Rows", false, true) {
+ @Override
+ public void validate(int newValue) {
+ if (newValue <= 0) {
+ status = ParameterStatus.INVALID;
+ status.setDetails("Chromosome must have at least 1 row.");
+ } else {
+ status = ParameterStatus.VALID;
+ }
+ }
+ });
+ parameters.put("columns", new IntegerParameter(9, "Columns", false, true) {
+ @Override
+ public void validate(int newValue) {
+ if (newValue <= 0) {
+ status = ParameterStatus.INVALID;
+ status.setDetails("Chromosome must have at least 1 column.");
+ } else {
+ status = ParameterStatus.VALID;
+ }
+ }
+ });
+ parameters.put("inputs", new IntegerParameter(3, "Inputs", false, true) {
+ @Override
+ public void validate(int newValue) {
+ if (newValue <= 0) {
+ status = ParameterStatus.INVALID;
+ status.setDetails("Chromosome must have at least 1 input.");
+ } else {
+ status = ParameterStatus.VALID;
+ }
+ }
+ });
+ parameters.put("outputs", new IntegerParameter(3, "Outputs", false, true) {
+ @Override
+ public void validate(int newValue) {
+ if (newValue <= 0) {
+ status = ParameterStatus.INVALID;
+ status.setDetails("Chromosome must have at least 1 output.");
+ } else {
+ status = ParameterStatus.VALID;
+ }
+ }
+ });
+ parameters.put("popSize", new IntegerParameter(5, "Population", false, true) {
+ @Override
+ public void validate(int newValue) {
+ if (newValue <= 0) {
+ status = ParameterStatus.INVALID;
+ status.setDetails("Population size must be at least 1.");
+ } else {
+ status = ParameterStatus.VALID;
+ }
+ }
+ });
+ parameters.put("levelsBack", new IntegerParameter(2, "Levels back", false, true) {
+ @Override
+ public void validate(int newValue) {
+ if (newValue <= 0) {
+ status = ParameterStatus.INVALID;
+ status.setDetails("Levels back must be at least 1.");
+ } else if (newValue > getInt("columns")) {
+ status = ParameterStatus.INVALID;
+ status.setDetails("Levels back must be less than or equal to the number of columns.");
+ } else {
+ status = ParameterStatus.VALID;
+ }
+ }
+ });
+
+ IntegerParameter nodes = new IntegerParameter(1, "Nodes", true, false) {
+ @Override
+ public void validate(int newValue) {
+ // blank
+ }
+ };
+ nodes.valueProperty().bind(((IntegerParameter) parameters.get("rows")).valueProperty().multiply(((IntegerParameter) parameters.get("columns")).valueProperty()));
+ parameters.put("nodes", nodes);
+
+ parameters.put("generations", new IntegerParameter(1000000, "Generations") {
+ @Override
+ public void validate(int newValue) {
+ if (newValue <= 0) {
+ status = ParameterStatus.INVALID;
+ status.setDetails("Number of generations must be greater than 0.");
+ } else if (newValue < getInt("currentGen")) {
+ status = ParameterStatus.WARNING_RESET;
+ status.setDetails("Setting generations to less than the current generation will cause the experiment to restart.");
+ } else {
+ status = ParameterStatus.VALID;
+ }
+ }
+ });
+ parameters.put("currentGen", new IntegerParameter(1, "Generation", true, false) {
+ @Override
+ public void validate(int newValue) {
+ // blank
+ }
+ });
+
+ parameters.put("runs", new IntegerParameter(5, "Runs") {
+ @Override
+ public void validate(int newValue) {
+ if (newValue <= 0) {
+ status = ParameterStatus.INVALID;
+ status.setDetails("Number of runs must be greater than 0.");
+ } else if (newValue < getInt("currentRun")) {
+ status = ParameterStatus.WARNING_RESET;
+ status.setDetails("Setting runs to less than the current run will cause the experiment to restart.");
+ } else {
+ status = ParameterStatus.VALID;
+ }
+ }
+ });
+ parameters.put("currentRun", new IntegerParameter(1, "Run", true, false) {
+ @Override
+ public void validate(int newValue) {
+ // blank
+ }
+ });
+
+ parameters.put("arity", new IntegerParameter(functionSet.getMaxArity(), "Max arity", true, false) {
+ @Override
+ public void validate(int newValue) {
+ // blank
+ }
+ });
+
+ IntegerParameter seed = new IntegerParameter(1234, "Seed", false, true) {
+ @Override
+ public void validate(int newValue) {
+ status = ParameterStatus.VALID;
+ }
+ };
+ seed.valueProperty().addListener(new ChangeListener<Number>() {
+ @Override
+ public void changed(
+ ObservableValue<? extends Number> observable,
+ Number oldValue, Number newValue) {
+ numberGenerator.setSeed(newValue.longValue());
+ }
+ });
+ numberGenerator.setSeed(seed.get());
+ parameters.put("seed", seed);
+
+ parameters.put("report", new IntegerParameter(1, "Report", false, false) {
+ @Override
+ public void validate(int newValue) {
+ if (newValue > getInt("generations")) {
+ status = ParameterStatus.WARNING;
+ status.setDetails("No reports will be printed.");
+ } else {
+ status = ParameterStatus.VALID;
+ }
+ }
+ });
+ }
+
+ /*
+ * Utility functions
+ */
+ public int getRandomInt(int limit) {
+ return numberGenerator.nextInt(limit);
+ }
+
+ public double getRandomDouble(int limit) {
+ return numberGenerator.nextDouble() * limit;
+ }
+
+ public double getRandomDouble() {
+ return numberGenerator.nextDouble();
+ }
+
+ /*
+ * FunctionSet functions
+ */
+ public Function getRandomFunction() {
+ Function f = functionSet.getAllowedFunction(numberGenerator.nextInt(functionSet.getAllowedFunctionCount()));
+ return f;
+ }
+
+ public Function getFunction(int index) {
+ return functionSet.getAllowedFunction(index);
+ }
+
+ /**
+ * @return the functionSets
+ */
+ public FunctionSet[] getFunctionSets() {
+ return functionSets;
+ }
+
+ /**
+ * @return the functionSet
+ */
+ public FunctionSet getFunctionSet() {
+ return functionSet;
+ }
+
+// /*
+// * Test cases
+// */
+// public TestCase getTestCase(int index) {
+// return testCases[index];
+// }
+//
+// public int getTestCaseCount() {
+// return testCases.length;
+// }
+
+ /*
+ * Console functionality
+ */
+ public void println(String s) {
+ System.out.println(s);
+ if (console != null) {
+ console.println(s);
+ }
+ }
+
+ public void print(String s) {
+ System.out.print(s);
+ if (console != null) {
+ console.print(s);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/jcgp/backend/resources/parameters/BooleanParameter.java b/src/jcgp/backend/resources/parameters/BooleanParameter.java
new file mode 100644
index 0000000..cd17649
--- /dev/null
+++ b/src/jcgp/backend/resources/parameters/BooleanParameter.java
@@ -0,0 +1,42 @@
+package jcgp.backend.resources.parameters;
+
+import javafx.beans.property.SimpleBooleanProperty;
+
+public abstract class BooleanParameter extends Parameter {
+
+ private SimpleBooleanProperty value;
+
+ public BooleanParameter(boolean value, String name, boolean monitor, boolean critical) {
+ super(name, monitor, critical);
+ this.value = new SimpleBooleanProperty(value);
+ }
+
+ /**
+ * Simple BooleanParameter constructor,
+ *
+ *
+ * @param value
+ * @param name
+ */
+ public BooleanParameter(boolean value, String name) {
+ super(name, false, false);
+ this.value = new SimpleBooleanProperty(value);
+ }
+
+ public boolean get() {
+ return value.get();
+ }
+
+ public void set(boolean newValue) {
+ if (!value.isBound()) {
+ value.set(newValue);
+ }
+ }
+
+ public abstract void validate(boolean newValue);
+
+ @Override
+ public SimpleBooleanProperty valueProperty() {
+ return value;
+ }
+}
diff --git a/src/jcgp/backend/resources/parameters/DoubleParameter.java b/src/jcgp/backend/resources/parameters/DoubleParameter.java
new file mode 100644
index 0000000..8464c83
--- /dev/null
+++ b/src/jcgp/backend/resources/parameters/DoubleParameter.java
@@ -0,0 +1,36 @@
+package jcgp.backend.resources.parameters;
+
+import javafx.beans.property.SimpleDoubleProperty;
+
+public abstract class DoubleParameter extends Parameter {
+
+ protected SimpleDoubleProperty value;
+
+ public DoubleParameter(double value, String name, boolean monitor, boolean critical) {
+ super(name, monitor, critical);
+ this.value = new SimpleDoubleProperty(value);
+ }
+
+ public DoubleParameter(double value, String name) {
+ super(name, false, false);
+ this.value = new SimpleDoubleProperty(value);
+ }
+
+ public double get() {
+ return value.get();
+ }
+
+ public void set(double newValue) {
+ if (!value.isBound()) {
+ value.set(newValue);
+ }
+ }
+
+ @Override
+ public SimpleDoubleProperty valueProperty() {
+ return value;
+ }
+
+ public abstract void validate(double newValue);
+
+}
diff --git a/src/jcgp/backend/resources/parameters/IntegerParameter.java b/src/jcgp/backend/resources/parameters/IntegerParameter.java
new file mode 100644
index 0000000..2a7b2a7
--- /dev/null
+++ b/src/jcgp/backend/resources/parameters/IntegerParameter.java
@@ -0,0 +1,37 @@
+package jcgp.backend.resources.parameters;
+
+import javafx.beans.property.SimpleIntegerProperty;
+
+public abstract class IntegerParameter extends Parameter {
+
+ private SimpleIntegerProperty value;
+
+ public IntegerParameter(int value, String name, boolean monitor, boolean critical) {
+ super(name, monitor, critical);
+ this.value = new SimpleIntegerProperty(value);
+ }
+
+ public IntegerParameter(int value, String name) {
+ super(name, false, false);
+ this.value = new SimpleIntegerProperty(value);
+ }
+
+ public int get() {
+ return value.get();
+ }
+
+ public void set(int newValue) {
+ if (!value.isBound()) {
+ validate(newValue);
+ value.set(newValue);
+ }
+ }
+
+ @Override
+ public SimpleIntegerProperty valueProperty() {
+ return value;
+ }
+
+ public abstract void validate(int newValue);
+
+}
diff --git a/src/jcgp/backend/resources/parameters/Parameter.java b/src/jcgp/backend/resources/parameters/Parameter.java
new file mode 100644
index 0000000..7e12ff8
--- /dev/null
+++ b/src/jcgp/backend/resources/parameters/Parameter.java
@@ -0,0 +1,41 @@
+package jcgp.backend.resources.parameters;
+
+import javafx.beans.property.Property;
+
+public abstract class Parameter {
+
+ protected boolean monitor, critical, reset = false;
+
+ protected ParameterStatus status = ParameterStatus.VALID;
+
+ protected String name;
+
+ public Parameter(String name, boolean monitor, boolean critical) {
+ this.name = name;
+ this.monitor = monitor;
+ this.critical = critical;
+ }
+
+ public boolean isMonitor() {
+ return monitor;
+ }
+
+ public boolean isCritical() {
+ return critical;
+ }
+
+ public boolean requiresReset() {
+ return critical || reset;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public ParameterStatus getStatus() {
+ return status;
+ }
+
+ public abstract Property<?> valueProperty();
+
+}
diff --git a/src/jcgp/backend/resources/parameters/ParameterStatus.java b/src/jcgp/backend/resources/parameters/ParameterStatus.java
new file mode 100644
index 0000000..11da4c2
--- /dev/null
+++ b/src/jcgp/backend/resources/parameters/ParameterStatus.java
@@ -0,0 +1,16 @@
+package jcgp.backend.resources.parameters;
+
+public enum ParameterStatus {
+ INVALID, WARNING, WARNING_RESET, VALID;
+
+ private String details;
+
+ public void setDetails(String details) {
+ this.details = details;
+ }
+
+ public String getDetails() {
+ return details;
+ }
+
+}