aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/jcgp/JCGP.java141
-rw-r--r--src/jcgp/backend/modules/ea/MuPlusLambda.java37
-rw-r--r--src/jcgp/backend/modules/ea/TournamentSelection.java4
-rw-r--r--src/jcgp/backend/parameters/BooleanParameter.java9
-rw-r--r--src/jcgp/backend/parameters/DoubleParameter.java2
-rw-r--r--src/jcgp/backend/parameters/IntegerParameter.java2
-rw-r--r--src/jcgp/backend/parameters/Parameter.java8
-rw-r--r--src/jcgp/backend/parameters/ParameterStatus.java2
-rw-r--r--src/jcgp/backend/population/Chromosome.java1
-rw-r--r--src/jcgp/gui/GUI.java126
-rw-r--r--src/jcgp/gui/console/GUIConsole.java7
-rw-r--r--src/jcgp/gui/settings/SettingsPane.java109
-rw-r--r--src/jcgp/gui/settings/parameters/GUIBooleanParameter.java43
-rw-r--r--src/jcgp/gui/settings/parameters/GUIDoubleParameter.java41
-rw-r--r--src/jcgp/gui/settings/parameters/GUIIntegerParameter.java42
-rw-r--r--src/jcgp/gui/settings/parameters/GUIParameter.java18
16 files changed, 390 insertions, 202 deletions
diff --git a/src/jcgp/JCGP.java b/src/jcgp/JCGP.java
index 0c75f2b..962ddec 100644
--- a/src/jcgp/JCGP.java
+++ b/src/jcgp/JCGP.java
@@ -117,7 +117,7 @@ public class JCGP {
private void createBaseParameters() {
parameters.put("rows", new IntegerParameter(8, "Rows", false, true) {
@Override
- protected void validate(int newValue) {
+ public void validate(int newValue) {
if (newValue <= 0) {
status = ParameterStatus.INVALID;
status.setDetails("Chromosome must have at least 1 row.");
@@ -128,7 +128,7 @@ public class JCGP {
});
parameters.put("columns", new IntegerParameter(9, "Columns", false, true) {
@Override
- protected void validate(int newValue) {
+ public void validate(int newValue) {
if (newValue <= 0) {
status = ParameterStatus.INVALID;
status.setDetails("Chromosome must have at least 1 column.");
@@ -139,7 +139,7 @@ public class JCGP {
});
parameters.put("inputs", new IntegerParameter(3, "Inputs", false, true) {
@Override
- protected void validate(int newValue) {
+ public void validate(int newValue) {
if (newValue <= 0) {
status = ParameterStatus.INVALID;
status.setDetails("Chromosome must have at least 1 input.");
@@ -150,7 +150,7 @@ public class JCGP {
});
parameters.put("outputs", new IntegerParameter(3, "Outputs", false, true) {
@Override
- protected void validate(int newValue) {
+ public void validate(int newValue) {
if (newValue <= 0) {
status = ParameterStatus.INVALID;
status.setDetails("Chromosome must have at least 1 output.");
@@ -161,7 +161,7 @@ public class JCGP {
});
parameters.put("popSize", new IntegerParameter(5, "Population", false, true) {
@Override
- protected void validate(int newValue) {
+ public void validate(int newValue) {
if (newValue <= 0) {
status = ParameterStatus.INVALID;
status.setDetails("Population size must be at least 1.");
@@ -172,7 +172,7 @@ public class JCGP {
});
parameters.put("levelsBack", new IntegerParameter(2, "Levels back", false, true) {
@Override
- protected void validate(int newValue) {
+ public void validate(int newValue) {
if (newValue <= 0) {
status = ParameterStatus.INVALID;
status.setDetails("Levels back must be at least 1.");
@@ -187,7 +187,7 @@ public class JCGP {
IntegerParameter nodes = new IntegerParameter(1, "Nodes", true, false) {
@Override
- protected void validate(int newValue) {
+ public void validate(int newValue) {
// blank
}
};
@@ -196,12 +196,12 @@ public class JCGP {
parameters.put("generations", new IntegerParameter(1000000, "Generations") {
@Override
- protected void validate(int newValue) {
+ 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;
+ } 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;
@@ -210,16 +210,19 @@ public class JCGP {
});
parameters.put("currentGen", new IntegerParameter(1, "Generation", true, false) {
@Override
- protected void validate(int newValue) {
+ public void validate(int newValue) {
// blank
}
});
parameters.put("runs", new IntegerParameter(5, "Runs") {
@Override
- protected void validate(int newValue) {
- if (newValue <= getInt("currentRun")) {
- status = ParameterStatus.WARNING;
+ 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;
@@ -228,27 +231,27 @@ public class JCGP {
});
parameters.put("currentRun", new IntegerParameter(1, "Run", true, false) {
@Override
- protected void validate(int newValue) {
+ public void validate(int newValue) {
// blank
}
});
parameters.put("arity", new IntegerParameter(0, "Max arity", true, false) {
@Override
- protected void validate(int newValue) {
+ public void validate(int newValue) {
// blank
}
});
- parameters.put("maxFitness", new IntegerParameter(6, "Max fitness", true, true) {
+ parameters.put("maxFitness", new IntegerParameter(3, "Max fitness", true, true) {
@Override
- protected void validate(int newValue) {
+ public void validate(int newValue) {
// blank
}
});
IntegerParameter seed = new IntegerParameter(123, "Seed", false, true) {
@Override
- protected void validate(int newValue) {
+ public void validate(int newValue) {
status = ParameterStatus.VALID;
}
};
@@ -264,7 +267,7 @@ public class JCGP {
parameters.put("report", new IntegerParameter(1, "Report", false, false) {
@Override
- protected void validate(int newValue) {
+ public void validate(int newValue) {
if (newValue > getInt("generations")) {
status = ParameterStatus.WARNING;
status.setDetails("No reports will be printed.");
@@ -366,7 +369,7 @@ public class JCGP {
}
}
- private Resources resources = new Resources();
+ private final Resources resources = new Resources();
/*
* The following arrays contain all available modules. These collections are read by the GUI
@@ -382,7 +385,7 @@ public class JCGP {
// evolutionary algorithms
private EvolutionaryAlgorithm[] evolutionaryAlgorithms = new EvolutionaryAlgorithm[] {
- new MuPlusLambda(),
+ new MuPlusLambda(resources),
new TournamentSelection()};
private EvolutionaryAlgorithm evolutionaryAlgorithm;
@@ -396,7 +399,7 @@ public class JCGP {
*/
private Population population;
- private boolean solutionFound = false;
+ private boolean finished = false;
public JCGP() {
@@ -409,8 +412,7 @@ public class JCGP {
fitnessFunction = fitnessFunctions[0];
- resources.setTestCases(new TestCase(new Integer[]{1, 2, 3}, new Integer[]{4, 5, 6}),
- new TestCase(new Integer[]{4, 7, 4}, new Integer[]{6, 21, 2}));
+ resources.setTestCases(new TestCase(new Integer[]{1, 2, 3}, new Integer[]{-4, 5, 6}));
}
@@ -495,33 +497,88 @@ public class JCGP {
}
public void nextGeneration() {
- fitnessFunction.evaluate(population, resources);
-
- if (population.getChromosome(evolutionaryAlgorithm.getFittestChromosome()).getFitness() >= resources.getInt("maxFitness")) {
- solutionFound = true;
- resources.println("Solution found!");
- population.getChromosome(evolutionaryAlgorithm.getFittestChromosome()).printNodes();
- } else {
- resources.println("Generation: " + resources.getInt("currentGen") + ", fitness: " + population.getChromosome(evolutionaryAlgorithm.getFittestChromosome()).getFitness());
- resources.set("currentGen", resources.getInt("currentGen") + 1);
+ if (!finished) {
+ fitnessFunction.evaluate(population, 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")) {
+ // solution has been found, start next run
+ resources.println("Solution found in generation " + resources.getInt("currentGen") + ", chromosome: " + evolutionaryAlgorithm.getFittestChromosome());
+
+ if (resources.getInt("currentRun") < resources.getInt("runs")) {
+ // there are still runs left
+ resources.set("currentRun", resources.getInt("currentRun") + 1);
+ resources.set("currentGen", 0);
+
+ // start a new population
+ population = new Population(resources);
+ } else {
+ // no more generations and no more runs, we're done
+ finished = true;
+ }
+ } 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 "
+ + population.getChromosome(evolutionaryAlgorithm.getFittestChromosome()).getFitness()
+ + " by chromosome " + evolutionaryAlgorithm.getFittestChromosome());
+
+ if (resources.getInt("currentRun") < resources.getInt("runs")) {
+ // the run has ended but there are still runs left
+ resources.set("currentRun", resources.getInt("currentRun") + 1);
+ resources.set("currentGen", 0);
+
+ // start a new population
+ population = new Population(resources);
+ } else {
+ // no more generations and no more runs, we're done
+ finished = true;
+ }
+ }
}
-
+
evolutionaryAlgorithm.evolve(population, mutator, resources);
+
}
- public void start() {
- while (resources.getInt("currentGen") <= resources.getInt("generations")) {
- nextGeneration();
-
- if (solutionFound) {
- break;
+ private void report() {
+ if (resources.getInt("report") > 0) {
+ if (resources.getInt("currentGen") % resources.getInt("report") == 0) {
+ resources.println("Generation: " + resources.getInt("currentGen") + ", fitness: " + population.getChromosome(evolutionaryAlgorithm.getFittestChromosome()).getFitness());
}
}
+
+ }
+
+ public void start() {
+ if (!finished) {
+ while (resources.getInt("currentGen") <= resources.getInt("generations")) {
+ nextGeneration();
+ if (finished) {
+ break;
+ }
+ }
+ }
+
}
public void reset() {
- solutionFound = false;
+ finished = false;
population = new Population(resources);
+ resources.set("currentGen", 1);
+ resources.set("currentRun", 1);
+ resources.println("-----------------------------");
+ resources.println("New experiment");
}
+ public boolean isFinished() {
+ return finished;
+ }
+
}
diff --git a/src/jcgp/backend/modules/ea/MuPlusLambda.java b/src/jcgp/backend/modules/ea/MuPlusLambda.java
index 22a0876..ad8c5d8 100644
--- a/src/jcgp/backend/modules/ea/MuPlusLambda.java
+++ b/src/jcgp/backend/modules/ea/MuPlusLambda.java
@@ -3,8 +3,10 @@ package jcgp.backend.modules.ea;
import jcgp.JCGP.Resources;
import jcgp.backend.modules.ModuleStatus;
import jcgp.backend.modules.mutator.Mutator;
+import jcgp.backend.parameters.BooleanParameter;
import jcgp.backend.parameters.IntegerParameter;
import jcgp.backend.parameters.Parameter;
+import jcgp.backend.parameters.ParameterStatus;
import jcgp.backend.population.Population;
/**
@@ -19,18 +21,41 @@ public class MuPlusLambda implements EvolutionaryAlgorithm {
private int fittestChromosome;
private IntegerParameter parents, offspring;
+ private BooleanParameter report;
- public MuPlusLambda() {
+ public MuPlusLambda(final Resources resources) {
parents = new IntegerParameter(1, "Parents") {
@Override
- protected void validate(int newValue) {
-
+ public void validate(int newValue) {
+ if (newValue + offspring.get() != resources.getInt("popSize")) {
+ status = ParameterStatus.INVALID;
+ status.setDetails("Parents + offspring must equal population size.");
+ } else if (newValue <= 0) {
+ status = ParameterStatus.INVALID;
+ status.setDetails("EA needs at least 1 parent.");
+ } else {
+ status = ParameterStatus.VALID;
+ }
}
};
offspring = new IntegerParameter(4, "Offspring") {
@Override
- protected void validate(int newValue) {
-
+ public void validate(int newValue) {
+ if (newValue + parents.get() != resources.getInt("popSize")) {
+ status = ParameterStatus.INVALID;
+ status.setDetails("Parents + offspring must equal population size.");
+ } else if (newValue <= 0) {
+ status = ParameterStatus.INVALID;
+ status.setDetails("EA needs at least 1 offspring.");
+ } else {
+ status = ParameterStatus.VALID;
+ }
+ }
+ };
+ report = new BooleanParameter(false, "Report") {
+ @Override
+ public void validate(boolean newValue) {
+ // nothing
}
};
}
@@ -63,7 +88,7 @@ public class MuPlusLambda implements EvolutionaryAlgorithm {
@Override
public Parameter[] getLocalParameters() {
- return new Parameter[] {parents, offspring};
+ return new Parameter[] {parents, offspring, report};
}
@Override
diff --git a/src/jcgp/backend/modules/ea/TournamentSelection.java b/src/jcgp/backend/modules/ea/TournamentSelection.java
index 3c4a539..32ac54d 100644
--- a/src/jcgp/backend/modules/ea/TournamentSelection.java
+++ b/src/jcgp/backend/modules/ea/TournamentSelection.java
@@ -19,8 +19,8 @@ public class TournamentSelection implements EvolutionaryAlgorithm {
public TournamentSelection() {
tournament = new IntegerParameter(1, "Tournament size") {
@Override
- protected void validate(int newValue) {
-
+ public void validate(int newValue) {
+ // TODO this
}
};
diff --git a/src/jcgp/backend/parameters/BooleanParameter.java b/src/jcgp/backend/parameters/BooleanParameter.java
index db78419..43825be 100644
--- a/src/jcgp/backend/parameters/BooleanParameter.java
+++ b/src/jcgp/backend/parameters/BooleanParameter.java
@@ -11,6 +11,13 @@ public abstract class BooleanParameter extends Parameter {
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);
@@ -26,7 +33,7 @@ public abstract class BooleanParameter extends Parameter {
}
}
- protected abstract void validate(boolean newValue);
+ public abstract void validate(boolean newValue);
public SimpleBooleanProperty valueProperty() {
return value;
diff --git a/src/jcgp/backend/parameters/DoubleParameter.java b/src/jcgp/backend/parameters/DoubleParameter.java
index 2b98991..53551f5 100644
--- a/src/jcgp/backend/parameters/DoubleParameter.java
+++ b/src/jcgp/backend/parameters/DoubleParameter.java
@@ -30,6 +30,6 @@ public abstract class DoubleParameter extends Parameter {
return value;
}
- protected abstract void validate(double newValue);
+ public abstract void validate(double newValue);
}
diff --git a/src/jcgp/backend/parameters/IntegerParameter.java b/src/jcgp/backend/parameters/IntegerParameter.java
index 1127817..68095d9 100644
--- a/src/jcgp/backend/parameters/IntegerParameter.java
+++ b/src/jcgp/backend/parameters/IntegerParameter.java
@@ -31,6 +31,6 @@ public abstract class IntegerParameter extends Parameter {
return value;
}
- protected abstract void validate(int newValue);
+ public abstract void validate(int newValue);
}
diff --git a/src/jcgp/backend/parameters/Parameter.java b/src/jcgp/backend/parameters/Parameter.java
index 26bc8f1..ddd5d5b 100644
--- a/src/jcgp/backend/parameters/Parameter.java
+++ b/src/jcgp/backend/parameters/Parameter.java
@@ -4,7 +4,7 @@ import javafx.beans.property.Property;
public abstract class Parameter {
- protected boolean monitor, critical;
+ protected boolean monitor, critical, reset = false;
protected ParameterStatus status = ParameterStatus.VALID;
@@ -24,6 +24,10 @@ public abstract class Parameter {
return critical;
}
+ public boolean requiresReset() {
+ return critical || reset;
+ }
+
public String getName() {
return name;
}
@@ -33,5 +37,5 @@ public abstract class Parameter {
}
public abstract Property<?> valueProperty();
-
+
}
diff --git a/src/jcgp/backend/parameters/ParameterStatus.java b/src/jcgp/backend/parameters/ParameterStatus.java
index ed235d4..86abe33 100644
--- a/src/jcgp/backend/parameters/ParameterStatus.java
+++ b/src/jcgp/backend/parameters/ParameterStatus.java
@@ -1,7 +1,7 @@
package jcgp.backend.parameters;
public enum ParameterStatus {
- INVALID, WARNING, VALID;
+ INVALID, WARNING, WARNING_RESET, VALID;
private String details;
diff --git a/src/jcgp/backend/population/Chromosome.java b/src/jcgp/backend/population/Chromosome.java
index 41ba06e..c7493b9 100644
--- a/src/jcgp/backend/population/Chromosome.java
+++ b/src/jcgp/backend/population/Chromosome.java
@@ -310,6 +310,7 @@ public class Chromosome {
}
public void printNodes() {
+ // TODO make this proper
int arity = resources.getInt("arity");
for (int r = 0; r < (resources.getInt("rows")); r++) {
diff --git a/src/jcgp/gui/GUI.java b/src/jcgp/gui/GUI.java
index 0902b21..f7aa25d 100644
--- a/src/jcgp/gui/GUI.java
+++ b/src/jcgp/gui/GUI.java
@@ -53,12 +53,38 @@ public class GUI extends Application {
private GUIConsole console = new GUIConsole();
private SettingsPane settings;
- private Service<Void> cgpService;
-
private boolean evolving = false;
private Object printLock = new Object();
+ private Service<Void> cgpService = new Service<Void> () {
+ @Override
+ protected Task<Void> createTask() {
+ Task<Void> t = new Task<Void>() {
+ @Override
+ protected Void call() throws Exception {
+ while (!isCancelled() && !cgp.isFinished()) {
+ synchronized (printLock) {
+ Platform.runLater(consoleFlush);
+ cgp.nextGeneration();
+ printLock.wait();
+ }
+ }
+ if (cgp.isFinished()) {
+ Platform.runLater(new Runnable() {
+ @Override
+ public void run() {
+ runningMode(false);
+ }
+ });
+ }
+ return null;
+ }
+ };
+ return t;
+ }
+ };
+
private Runnable consoleFlush = new Runnable() {
@Override
public void run() {
@@ -80,27 +106,6 @@ public class GUI extends Application {
public void start(Stage primaryStage) throws Exception {
resources.setConsole(console);
- cgpService = new Service<Void> () {
- @Override
- protected Task<Void> createTask() {
-
- Task<Void> t = new Task<Void>() {
- @Override
- protected Void call() throws Exception {
- while (!isCancelled()) {
- Platform.runLater(consoleFlush);
- synchronized (printLock) {
- cgp.nextGeneration();
- printLock.wait();
- }
- }
- return null;
- }
- };
- return t;
- }
- };
-
/*
* Instantiate the various GUI elements here.
*
@@ -167,45 +172,68 @@ public class GUI extends Application {
chromosomeTabs.setDisable(value);
}
- public void disable(boolean value) {
- chromosomeTabs.setDisable(value);
- settings.disableSettings(value);
- }
-
- public void playPause() {
- if (!evolving) {
- disable(true);
- unlockOutputs();
- evolving = true;
- cgpService.restart();
- } else {
- disable(false);
- updateNodeGrids();
- evolving = false;
- cgpService.cancel();
- relockOutputs();
+ public void runPause() {
+ if (!cgp.isFinished() && settings.areParametersValid()) {
+ if (!evolving) {
+ runningMode(true);
+ cgpService.restart();
+ } else {
+ cgpService.cancel();
+ runningMode(false);
+ }
}
}
public void step() {
- if (!evolving) {
- Thread t = new Thread(new Task<Void>() {
+ if (!evolving && !cgp.isFinished() && settings.areParametersValid()) {
+ if (settings.isResetRequired()) {
+ reset();
+ }
+ unlockOutputs();
+ Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
- unlockOutputs();
cgp.nextGeneration();
- console.flush();
- updateNodeGrids();
- relockOutputs();
+ Platform.runLater(consoleFlush);
return null;
}
- });
+ };
+ Thread t = new Thread(task);
t.start();
+ try {
+ t.join();
+ } catch (InterruptedException e) {
+ // nothing
+ } finally {
+ updateNodeGrids();
+ relockOutputs();
+ }
}
}
public void reset() {
- cgp.reset();
- makeChromosomeTabPane();
+ if (!evolving && settings.areParametersValid()) {
+ settings.applyParameters();
+ cgp.reset();
+ makeChromosomeTabPane();
+ settings.revalidateParameters();
+ }
+ }
+
+ private void runningMode(boolean value) {
+ chromosomeTabs.setDisable(value);
+ settings.disableSettings(value);
+ if (value) {
+ unlockOutputs();
+ settings.getRunButton().setText("Pause");
+ if (settings.isResetRequired()) {
+ reset();
+ }
+ } else {
+ updateNodeGrids();
+ relockOutputs();
+ settings.getRunButton().setText("Run");
+ }
+ evolving = value;
}
}
diff --git a/src/jcgp/gui/console/GUIConsole.java b/src/jcgp/gui/console/GUIConsole.java
index 8fdb1a5..d8625f5 100644
--- a/src/jcgp/gui/console/GUIConsole.java
+++ b/src/jcgp/gui/console/GUIConsole.java
@@ -10,15 +10,14 @@ import jcgp.gui.GUI;
public class GUIConsole extends AnchorPane implements Console {
private boolean dragging;
- private TextArea textArea = new TextArea("Welcome to JCGP!\n");
+ private TextArea textArea = new TextArea("Welcome to JCGP!");
private StringBuffer printBuffer = new StringBuffer();
public GUIConsole() {
super();
textArea.setEditable(false);
- textArea.setWrapText(true);
-
+
setResizeListeners();
AnchorPane.setTopAnchor(textArea, GUI.RESIZE_MARGIN);
@@ -91,7 +90,7 @@ public class GUIConsole extends AnchorPane implements Console {
@Override
public void println(String s) {
- printBuffer.append(s + "\n");
+ printBuffer.append("\n" + s);
}
@Override
diff --git a/src/jcgp/gui/settings/SettingsPane.java b/src/jcgp/gui/settings/SettingsPane.java
index 41b1bba..cb066b7 100644
--- a/src/jcgp/gui/settings/SettingsPane.java
+++ b/src/jcgp/gui/settings/SettingsPane.java
@@ -32,17 +32,16 @@ public class SettingsPane extends AnchorPane {
private VBox mainContainer;
private VBox bpPane, eaPane, mutatorPane, ffPane, nfPane;
- private ArrayList<GUIParameter> parameters = new ArrayList<GUIParameter>();
- private GUI gui;
+ private Button runPause;
+ private ArrayList<GUIParameter> parameters = new ArrayList<GUIParameter>();
+
private boolean dragging = false;
public SettingsPane(JCGP cgp, GUI gui) {
super();
-
- this.gui = gui;
-
+
setResizeListeners();
mainContainer = new VBox(8);
@@ -85,22 +84,22 @@ public class SettingsPane extends AnchorPane {
bpPane.getChildren().add(header);
- parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("rows")));
- parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("columns")));
- parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("inputs")));
- parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("outputs")));
- parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("levelsBack")));
+ parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("rows"), this));
+ parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("columns"), this));
+ parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("inputs"), this));
+ parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("outputs"), this));
+ parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("levelsBack"), this));
- parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("popSize")));
- parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("generations")));
- parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("runs")));
+ parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("popSize"), this));
+ parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("generations"), this));
+ parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("runs"), this));
- parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("currentGen")));
- parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("currentRun")));
+ parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("currentGen"), this));
+ parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("currentRun"), this));
- parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("maxFitness")));
- parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("seed")));
- parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("report")));
+ parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("maxFitness"), this));
+ parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("seed"), this));
+ parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("report"), this));
bpPane.getChildren().addAll(parameters);
@@ -238,43 +237,41 @@ public class SettingsPane extends AnchorPane {
controls.setFillWidth(true);
final HBox flowButtons = new HBox(2);
- final Button play = new Button("Run");
-
- play.setOnAction(new EventHandler<ActionEvent>() {
+ runPause = new Button("Run");
+ runPause.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
- if (play.getText() == "Run") {
- if (isResetRequired()) {
- resetExperiment();
- }
- play.setText("Pause");
- } else {
- play.setText("Run");
- }
- gui.playPause();
+ gui.runPause();
}
});
Button step = new Button("Step");
-
step.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
- if (isResetRequired()) {
- resetExperiment();
- }
gui.step();
}
});
- flowButtons.getChildren().addAll(play, step);
+ Button reset = new Button("Reset");
+ reset.setOnAction(new EventHandler<ActionEvent>() {
+ @Override
+ public void handle(ActionEvent event) {
+ gui.reset();
+ }
+ });
+
+ flowButtons.getChildren().addAll(runPause, step, reset);
- HBox.setHgrow(play, Priority.ALWAYS);
- play.setMaxWidth(Double.MAX_VALUE);
+ HBox.setHgrow(runPause, Priority.ALWAYS);
+ runPause.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(step, Priority.ALWAYS);
step.setMaxWidth(Double.MAX_VALUE);
+ HBox.setHgrow(reset, Priority.ALWAYS);
+ reset.setMaxWidth(Double.MAX_VALUE);
+
controls.getChildren().add(flowButtons);
mainContainer.getChildren().add(controls);
@@ -288,11 +285,12 @@ public class SettingsPane extends AnchorPane {
parameters.removeAll(vb.getChildren());
vb.getChildren().clear();
for (int i = 0; i < newParameters.length; i++) {
- GUIParameter gp = GUIParameter.create(newParameters[i]);
+ GUIParameter gp = GUIParameter.create(newParameters[i], this);
parameters.add(gp);
vb.getChildren().add(gp);
}
+ revalidateParameters();
}
private void refreshFunctions(final FunctionSet fs, VBox vb) {
@@ -377,21 +375,38 @@ public class SettingsPane extends AnchorPane {
*
* @return true if the experiment needs to be reset, false otherwise.
*/
- private boolean isResetRequired() {
- boolean reset = false;
+ public boolean isResetRequired() {
for (GUIParameter parameter : parameters) {
- reset |= parameter.requiresReset();
+ if (parameter.requiresReset()) {
+ return true;
+ }
}
- System.out.println("reset: " + reset);
- return reset;
+ return false;
}
- private void resetExperiment() {
+ public boolean areParametersValid() {
for (GUIParameter parameter : parameters) {
- parameter.applyValue();
+ if (!parameter.isValid()) {
+ return false;
+ }
}
- gui.reset();
-
+ return true;
+ }
+
+ public void revalidateParameters() {
+ for (GUIParameter parameter : parameters) {
+ parameter.validate();
+ }
+ }
+
+ public void applyParameters() {
+ for (GUIParameter parameter : parameters) {
+ parameter.applyValue();
+ }
+ }
+
+ public Button getRunButton() {
+ return runPause;
}
diff --git a/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java b/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java
index da564f7..fc66e7d 100644
--- a/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java
+++ b/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java
@@ -6,12 +6,13 @@ import javafx.scene.control.CheckBox;
import jcgp.backend.parameters.BooleanParameter;
import jcgp.backend.parameters.ParameterStatus;
import jcgp.gui.GUI;
+import jcgp.gui.settings.SettingsPane;
public class GUIBooleanParameter extends GUIParameter {
private boolean originalValue;
- GUIBooleanParameter(final BooleanParameter parameter) {
+ GUIBooleanParameter(final BooleanParameter parameter, final SettingsPane sp) {
super();
this.parameter = parameter;
@@ -32,18 +33,8 @@ public class GUIBooleanParameter extends GUIParameter {
ObservableValue<? extends Boolean> observable,
Boolean oldValue, Boolean newValue) {
parameter.set(newValue);
- if (parameter.getStatus() == ParameterStatus.INVALID) {
- valueControl.setStyle(GUI.INVALID_PARAMETER_STYLE);
- valueControl.setTooltip(tooltip);
- tooltip.setText(parameter.getStatus().getDetails());
- } else if (parameter.getStatus() == ParameterStatus.WARNING) {
- valueControl.setStyle(GUI.WARNING_PARAMETER_STYLE);
- valueControl.setTooltip(tooltip);
- tooltip.setText(parameter.getStatus().getDetails());
- } else {
- valueControl.setStyle(GUI.VALID_PARAMETER_STYLE);
- valueControl.setTooltip(null);
- }
+ setValidityStyle();
+ sp.revalidateParameters();
}
});
}
@@ -60,7 +51,8 @@ public class GUIBooleanParameter extends GUIParameter {
@Override
public boolean requiresReset() {
- return parameter.isCritical() && ((BooleanParameter) parameter).get() != originalValue;
+ return (parameter.isCritical() && ((BooleanParameter) parameter).get() != originalValue)
+ || parameter.getStatus() == ParameterStatus.WARNING_RESET;
}
@Override
@@ -68,4 +60,27 @@ public class GUIBooleanParameter extends GUIParameter {
originalValue = ((BooleanParameter) parameter).get();
}
+ /**
+ * @param parameter
+ */
+ private void setValidityStyle() {
+ if (parameter.getStatus() == ParameterStatus.INVALID) {
+ valueControl.setStyle(GUI.INVALID_PARAMETER_STYLE);
+ valueControl.setTooltip(tooltip);
+ tooltip.setText(parameter.getStatus().getDetails());
+ } else if (parameter.getStatus() == ParameterStatus.WARNING || parameter.getStatus() == ParameterStatus.WARNING_RESET) {
+ valueControl.setStyle(GUI.WARNING_PARAMETER_STYLE);
+ valueControl.setTooltip(tooltip);
+ tooltip.setText(parameter.getStatus().getDetails());
+ } else {
+ valueControl.setStyle(GUI.VALID_PARAMETER_STYLE);
+ valueControl.setTooltip(null);
+ }
+ }
+
+ @Override
+ public void validate() {
+ ((BooleanParameter) parameter).validate(((BooleanParameter) parameter).get());
+ setValidityStyle();
+ }
}
diff --git a/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java b/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java
index a1b4526..190f4b7 100644
--- a/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java
+++ b/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java
@@ -11,12 +11,13 @@ import javafx.scene.text.Text;
import jcgp.backend.parameters.DoubleParameter;
import jcgp.backend.parameters.ParameterStatus;
import jcgp.gui.GUI;
+import jcgp.gui.settings.SettingsPane;
public class GUIDoubleParameter extends GUIParameter {
private double originalValue;
- GUIDoubleParameter(final DoubleParameter parameter) {
+ GUIDoubleParameter(final DoubleParameter parameter, final SettingsPane sp) {
super();
this.parameter = parameter;
@@ -54,18 +55,8 @@ public class GUIDoubleParameter extends GUIParameter {
String oldValue, String newValue) {
if (!newValue.isEmpty()) {
parameter.set(Double.parseDouble(newValue));
- if (parameter.getStatus() == ParameterStatus.INVALID) {
- valueControl.setStyle(GUI.INVALID_PARAMETER_STYLE);
- valueControl.setTooltip(tooltip);
- tooltip.setText(parameter.getStatus().getDetails());
- } else if (parameter.getStatus() == ParameterStatus.WARNING) {
- valueControl.setStyle(GUI.WARNING_PARAMETER_STYLE);
- valueControl.setTooltip(tooltip);
- tooltip.setText(parameter.getStatus().getDetails());
- } else {
- valueControl.setStyle(GUI.VALID_PARAMETER_STYLE);
- valueControl.setTooltip(null);
- }
+ setValidityStyle();
+ sp.revalidateParameters();
}
}
@@ -93,7 +84,8 @@ public class GUIDoubleParameter extends GUIParameter {
@Override
public boolean requiresReset() {
- return parameter.isCritical() && ((DoubleParameter) parameter).get() != originalValue;
+ return (parameter.isCritical() && ((DoubleParameter) parameter).get() != originalValue)
+ || parameter.getStatus() == ParameterStatus.WARNING_RESET;
}
@Override
@@ -101,4 +93,25 @@ public class GUIDoubleParameter extends GUIParameter {
originalValue = ((DoubleParameter) parameter).get();
}
+ @Override
+ public void validate() {
+ ((DoubleParameter) parameter).validate(((DoubleParameter) parameter).get());
+ setValidityStyle();
+ }
+
+ private void setValidityStyle() {
+ if (parameter.getStatus() == ParameterStatus.INVALID) {
+ valueControl.setStyle(GUI.INVALID_PARAMETER_STYLE);
+ valueControl.setTooltip(tooltip);
+ tooltip.setText(parameter.getStatus().getDetails());
+ } else if (parameter.getStatus() == ParameterStatus.WARNING || parameter.getStatus() == ParameterStatus.WARNING_RESET) {
+ valueControl.setStyle(GUI.WARNING_PARAMETER_STYLE);
+ valueControl.setTooltip(tooltip);
+ tooltip.setText(parameter.getStatus().getDetails());
+ } else {
+ valueControl.setStyle(GUI.VALID_PARAMETER_STYLE);
+ valueControl.setTooltip(null);
+ }
+ }
+
}
diff --git a/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java b/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java
index bf1a61e..a2040d7 100644
--- a/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java
+++ b/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java
@@ -11,12 +11,13 @@ import javafx.scene.text.Text;
import jcgp.backend.parameters.IntegerParameter;
import jcgp.backend.parameters.ParameterStatus;
import jcgp.gui.GUI;
+import jcgp.gui.settings.SettingsPane;
public class GUIIntegerParameter extends GUIParameter {
private int originalValue;
- GUIIntegerParameter(final IntegerParameter parameter) {
+ GUIIntegerParameter(final IntegerParameter parameter, final SettingsPane sp) {
super();
this.parameter = parameter;
@@ -54,18 +55,8 @@ public class GUIIntegerParameter extends GUIParameter {
String oldValue, String newValue) {
if (!newValue.isEmpty()) {
parameter.set(Integer.parseInt(newValue));
- if (parameter.getStatus() == ParameterStatus.INVALID) {
- valueControl.setStyle(GUI.INVALID_PARAMETER_STYLE);
- valueControl.setTooltip(tooltip);
- tooltip.setText(parameter.getStatus().getDetails());
- } else if (parameter.getStatus() == ParameterStatus.WARNING) {
- valueControl.setStyle(GUI.WARNING_PARAMETER_STYLE);
- valueControl.setTooltip(tooltip);
- tooltip.setText(parameter.getStatus().getDetails());
- } else {
- valueControl.setStyle(GUI.VALID_PARAMETER_STYLE);
- valueControl.setTooltip(null);
- }
+ setValidityStyle();
+ sp.revalidateParameters();
}
}
@@ -92,7 +83,9 @@ public class GUIIntegerParameter extends GUIParameter {
@Override
public boolean requiresReset() {
- return parameter.isCritical() && ((IntegerParameter) parameter).get() != originalValue;
+ // true if critical and the value has changed, or it requires a reset anyway
+ return (parameter.isCritical() && ((IntegerParameter) parameter).get() != originalValue)
+ || parameter.getStatus() == ParameterStatus.WARNING_RESET;
}
@Override
@@ -100,4 +93,25 @@ public class GUIIntegerParameter extends GUIParameter {
originalValue = ((IntegerParameter) parameter).get();
}
+ @Override
+ public void validate() {
+ ((IntegerParameter) parameter).validate(((IntegerParameter) parameter).get());
+ setValidityStyle();
+ }
+
+ private void setValidityStyle() {
+ if (parameter.getStatus() == ParameterStatus.INVALID) {
+ valueControl.setStyle(GUI.INVALID_PARAMETER_STYLE);
+ valueControl.setTooltip(tooltip);
+ tooltip.setText(parameter.getStatus().getDetails());
+ } else if (parameter.getStatus() == ParameterStatus.WARNING || parameter.getStatus() == ParameterStatus.WARNING_RESET) {
+ valueControl.setStyle(GUI.WARNING_PARAMETER_STYLE);
+ valueControl.setTooltip(tooltip);
+ tooltip.setText(parameter.getStatus().getDetails());
+ } else {
+ valueControl.setStyle(GUI.VALID_PARAMETER_STYLE);
+ valueControl.setTooltip(null);
+ }
+ }
+
}
diff --git a/src/jcgp/gui/settings/parameters/GUIParameter.java b/src/jcgp/gui/settings/parameters/GUIParameter.java
index 9d6f07a..da2fe86 100644
--- a/src/jcgp/gui/settings/parameters/GUIParameter.java
+++ b/src/jcgp/gui/settings/parameters/GUIParameter.java
@@ -14,6 +14,8 @@ import jcgp.backend.parameters.BooleanParameter;
import jcgp.backend.parameters.DoubleParameter;
import jcgp.backend.parameters.IntegerParameter;
import jcgp.backend.parameters.Parameter;
+import jcgp.backend.parameters.ParameterStatus;
+import jcgp.gui.settings.SettingsPane;
public abstract class GUIParameter extends HBox {
@@ -59,15 +61,23 @@ public abstract class GUIParameter extends HBox {
public abstract void applyValue();
- public static GUIParameter create(Parameter parameter) {
+ public abstract void validate();
+
+ public static GUIParameter create(Parameter parameter, SettingsPane sp) {
if (parameter instanceof IntegerParameter) {
- return new GUIIntegerParameter((IntegerParameter) parameter);
+ return new GUIIntegerParameter((IntegerParameter) parameter, sp);
} else if (parameter instanceof DoubleParameter) {
- return new GUIDoubleParameter((DoubleParameter) parameter);
+ return new GUIDoubleParameter((DoubleParameter) parameter, sp);
} else if (parameter instanceof BooleanParameter) {
- return new GUIBooleanParameter((BooleanParameter) parameter);
+ return new GUIBooleanParameter((BooleanParameter) parameter, sp);
} else {
throw new ClassCastException("No GUIParameter subclass exists for argument of type " + parameter.getClass());
}
}
+
+ public boolean isValid() {
+ return parameter.getStatus() == ParameterStatus.VALID
+ || parameter.getStatus() == ParameterStatus.WARNING
+ || parameter.getStatus() == ParameterStatus.WARNING_RESET;
+ }
}