diff options
Diffstat (limited to 'src/jcgp/JCGP.java')
-rw-r--r-- | src/jcgp/JCGP.java | 237 |
1 files changed, 164 insertions, 73 deletions
diff --git a/src/jcgp/JCGP.java b/src/jcgp/JCGP.java index 7451d4f..0c75f2b 100644 --- a/src/jcgp/JCGP.java +++ b/src/jcgp/JCGP.java @@ -25,6 +25,7 @@ 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.backend.population.Population; import jcgp.gui.console.Console; @@ -114,26 +115,143 @@ public class JCGP { } private void createBaseParameters() { - parameters.put("rows", new IntegerParameter(8, "Rows")); - parameters.put("columns", new IntegerParameter(9, "Columns")); - parameters.put("inputs", new IntegerParameter(3, "Inputs")); - parameters.put("outputs", new IntegerParameter(3, "Outputs")); - parameters.put("popSize", new IntegerParameter(5, "Population")); - parameters.put("levelsBack", new IntegerParameter(2, "Levels back")); + parameters.put("rows", new IntegerParameter(8, "Rows", false, true) { + @Override + protected 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 + protected 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 + protected 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 + protected 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 + protected 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 + protected 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, true, false); + IntegerParameter nodes = new IntegerParameter(1, "Nodes", true, false) { + @Override + protected void validate(int newValue) { + // blank + } + }; nodes.valueProperty().bind(((SimpleIntegerProperty) ((IntegerParameter) parameters.get("rows")).valueProperty()).multiply((SimpleIntegerProperty) ((IntegerParameter) parameters.get("columns")).valueProperty())); parameters.put("nodes", nodes); - parameters.put("generations", new IntegerParameter(1000000, "Generations")); - parameters.put("currentGen", new IntegerParameter(1, "Generation", true, false, false)); - - parameters.put("runs", new IntegerParameter(5, "Runs")); - parameters.put("currentRun", new IntegerParameter(1, "Run", true, false, false)); + parameters.put("generations", new IntegerParameter(1000000, "Generations") { + @Override + protected 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; + 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 + protected void validate(int newValue) { + // blank + } + }); - parameters.put("arity", new IntegerParameter(0, "Max arity", false, true, false)); + parameters.put("runs", new IntegerParameter(5, "Runs") { + @Override + protected void validate(int newValue) { + if (newValue <= getInt("currentRun")) { + status = ParameterStatus.WARNING; + 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 + protected void validate(int newValue) { + // blank + } + }); + + parameters.put("arity", new IntegerParameter(0, "Max arity", true, false) { + @Override + protected void validate(int newValue) { + // blank + } + }); + parameters.put("maxFitness", new IntegerParameter(6, "Max fitness", true, true) { + @Override + protected void validate(int newValue) { + // blank + } + }); - IntegerParameter seed = new IntegerParameter(123, "Seed"); + IntegerParameter seed = new IntegerParameter(123, "Seed", false, true) { + @Override + protected void validate(int newValue) { + status = ParameterStatus.VALID; + } + }; seed.valueProperty().addListener(new ChangeListener<Number>() { @Override public void changed( @@ -144,50 +262,17 @@ public class JCGP { }); parameters.put("seed", seed); - parameters.put("report", new IntegerParameter(1, "Report", false, false, false)); - } - - private boolean validateBaseParameters() { - boolean valid = true; - - if (getInt("rows") <= 0) { - valid = false; - println("Error: number of rows must be greater than 0."); - } - if (getInt("columns") <= 0) { - valid = false; - println("Error: number of columns must be greater than 0."); - } - if (getInt("inputs") <= 0) { - valid = false; - println("Error: number of inputs must be greater than 0."); - } - if (getInt("outputs") <= 0) { - println("Error: number of outputs must be greater than 0."); - valid = false; - } - if (getInt("popSize") <= 0) { - println("Error: population size must be greater than 0."); - valid = false; - } - if (getInt("levelsBack") <= 0 || getInt("levelsBack") > getInt("columns")) { - println("Error: levels back must be greater than 0 and no greater than the number of columns."); - valid = false; - } - if (getInt("generations") <= 0) { - println("Error: number of generations must be greater than 0."); - valid = false; - } - if (getInt("runs") <= 0) { - println("Error: number of runs must be greater than 0."); - valid = false; - } - if (getInt("report") < 0) { - println("Error: report frequency must not be smaller than 0."); - valid = false; - } - - return valid; + parameters.put("report", new IntegerParameter(1, "Report", false, false) { + @Override + protected void validate(int newValue) { + if (newValue > getInt("generations")) { + status = ParameterStatus.WARNING; + status.setDetails("No reports will be printed."); + } else { + status = ParameterStatus.VALID; + } + } + }); } /** @@ -310,6 +395,8 @@ public class JCGP { * the population of chromosomes */ private Population population; + + private boolean solutionFound = false; public JCGP() { @@ -323,21 +410,14 @@ public class JCGP { fitnessFunction = fitnessFunctions[0]; resources.setTestCases(new TestCase(new Integer[]{1, 2, 3}, new Integer[]{4, 5, 6}), - new TestCase(new Integer[]{1, 12, 4}, new Integer[]{6, 21, 2})); + new TestCase(new Integer[]{4, 7, 4}, new Integer[]{6, 21, 2})); } - - public void remakePopulation() { - population = new Population(resources); - } - - public Resources getResources() { return resources; } - public Population getPopulation() { return population; } @@ -415,22 +495,33 @@ public class JCGP { } public void nextGeneration() { - fitnessFunction.evaluate(population, resources); - evolutionaryAlgorithm.evolve(population, mutator, resources); - if (evolutionaryAlgorithm.getFittestChromosome().getFitness() >= 6) { - resources.println("solution found"); - evolutionaryAlgorithm.getFittestChromosome().printNodes(); + 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: " + evolutionaryAlgorithm.getFittestChromosome().getFitness()); + resources.println("Generation: " + resources.getInt("currentGen") + ", fitness: " + population.getChromosome(evolutionaryAlgorithm.getFittestChromosome()).getFitness()); + resources.set("currentGen", resources.getInt("currentGen") + 1); } - resources.set("currentGen", resources.getInt("currentGen") + 1); + + evolutionaryAlgorithm.evolve(population, mutator, resources); } public void start() { while (resources.getInt("currentGen") <= resources.getInt("generations")) { nextGeneration(); + + if (solutionFound) { + break; + } } } + + public void reset() { + solutionFound = false; + population = new Population(resources); + } + } |