From d9671c354080de20bba4f70438af9242c8ecd675 Mon Sep 17 00:00:00 2001 From: Eduardo Pedroni Date: Mon, 3 Feb 2014 23:23:55 +0000 Subject: Fixed FunctionSet issue, planned testbench evaluator interface, will implement tomorrow. --- README | 20 ++++++- src/jcgp/fitness/FitnessEvaluator.java | 17 ++++++ src/jcgp/function/FunctionSet.java | 38 ++++++------- src/jcgp/population/Chromosome.java | 98 ++++++++++++++++------------------ src/jcgp/population/Population.java | 23 ++++---- 5 files changed, 112 insertions(+), 84 deletions(-) create mode 100644 src/jcgp/fitness/FitnessEvaluator.java diff --git a/README b/README index 52c2ef9..0b886c9 100644 --- a/README +++ b/README @@ -45,6 +45,24 @@ so long as it extends Chromosome. In conjunction with modularized FF, EA and mut flexible and versatile system. The Population class itself is immutable, since the system relies heavily on it. Finally, it is Iterable to for access to the chromosomes within. + Arity may vary across functions, but all nodes contain enough connections to cope with the largest arity. - \ No newline at end of file +FunctionSet presents a bit of a problem in case the user retains references to the Functions passed into it. + + +3/2 + +Solved the FunctionSet problem; since Function does not specify a way to modify the function once it is instantiated, +concurrent accesses should not be a problem. Should the user extend Function and implement a way to modify it at +runtime, the CGP program won't really use it; if the user modifies the CGP program to use it, then the user must +be ready to deal with the consequences. + +A fitness evaluation testbench of sorts will be implemented next. This testbench will take a set of "stimuli" (inputs), +use them to compute outputs with each chromosome, and compare those with the expected outputs, thus assigning fitness. + +This will be achieved for now using a TestCase object which contains a set of inputs and outputs. The evaluator simply +sets the chromosome inputs and compares outputs for all TestCase objects given, and computes a fitness function +accordingly. + + diff --git a/src/jcgp/fitness/FitnessEvaluator.java b/src/jcgp/fitness/FitnessEvaluator.java new file mode 100644 index 0000000..5ecf679 --- /dev/null +++ b/src/jcgp/fitness/FitnessEvaluator.java @@ -0,0 +1,17 @@ +package jcgp.fitness; + +import jcgp.population.Population; + +public class FitnessEvaluator { + + private FitnessFunction fitnessFunction; + + public FitnessEvaluator(FitnessFunction fitnessFunction) { + this.fitnessFunction = fitnessFunction; + } + + public void evaluateFitness(Population population) { + + } + +} diff --git a/src/jcgp/function/FunctionSet.java b/src/jcgp/function/FunctionSet.java index 30e1067..cbe2f05 100644 --- a/src/jcgp/function/FunctionSet.java +++ b/src/jcgp/function/FunctionSet.java @@ -1,37 +1,39 @@ package jcgp.function; -import java.util.ArrayList; - - +/** + * + * TODO: if function set flexibility is desired (i.e. add more functions as the program runs) + * an add function method should be created + * this would lead to concurrency problems, so tread lightly! + * + * + * @author Eduardo Pedroni + * + */ public class FunctionSet { - private ArrayList functionList; + private Function[] functionList; + private int maxArity = 0; public FunctionSet(Function ... functions) { - functionList = new ArrayList(functions.length); + functionList = functions; - for (int i = 0; i < functions.length; i++) { - functionList.add(functions[i]); + for (Function function : functionList) { + if (function.getArity() > maxArity) { + maxArity = function.getArity(); + } } + } public int getFunctionCount() { - return functionList.size(); + return functionList.length; } public Function getFunction(int index) { - return functionList.get(index); + return functionList[index]; } public int getMaxArity(){ - - int maxArity = 0; - - for (Function function : functionList) { - if (function.getArity() > maxArity) { - maxArity = function.getArity(); - } - } - return maxArity; } } \ No newline at end of file diff --git a/src/jcgp/population/Chromosome.java b/src/jcgp/population/Chromosome.java index 76667e5..70e8836 100644 --- a/src/jcgp/population/Chromosome.java +++ b/src/jcgp/population/Chromosome.java @@ -1,14 +1,13 @@ package jcgp.population; -import java.util.ArrayList; - +import jcgp.CGP.Parameters; import jcgp.CGP.Utilities; public class Chromosome { - private final ArrayList inputs = new ArrayList(); - private final ArrayList> nodes = new ArrayList>();; - private final ArrayList outputs = new ArrayList(); + private Input[] inputs; + private Node[][] nodes; + private Output[] outputs; private int fitness = 0; @@ -29,25 +28,6 @@ public class Chromosome { } - private void initialiseConnections() { - - // initialise nodes - for (int r = 0; r < nodes.size(); r++) { - for (int c = 0; c < nodes.size(); c++) { - Connection[] connections = new Connection[Utilities.getMaxArity()]; - for (int i = 0; i < connections.length; i++) { - connections[i] = Utilities.getRandomConnection(this, c); - } - nodes.get(r).get(c).initialise(Utilities.getRandomFunction(), connections); - } - } - - for (Output output : outputs) { - output.setConnection(Utilities.getRandomNode(this)); - } - - } - /** * @param inputCount * @param rows @@ -55,58 +35,58 @@ public class Chromosome { * @param outputCount */ private void instantiateElements(int inputCount, int rows, int columns, int outputCount) { + inputs = new Input[inputCount]; for (int i = 0; i < inputCount; i++) { - inputs.add(new Input()); + inputs[i] = new Input(); } // rows first + nodes = new Node[Parameters.getRows()][Parameters.getColumns()]; for (int r = 0; r < rows; r++) { - nodes.add(new ArrayList(columns)); + //nodes[r] = new Node[Parameters.getColumns()]; for (int c = 0; c < columns; c++) { - nodes.get(r).add(new Node()); + nodes[r][c] = new Node(); } } - + outputs = new Output[outputCount]; for (int o = 0; o < outputCount; o++) { - outputs.add(new Output()); + outputs[o] = new Output(); + } + } + + private void initialiseConnections() { + + // initialise nodes - [rows][columns] + for (int r = 0; r < nodes.length; r++) { + for (int c = 0; c < nodes.length; c++) { + Connection[] connections = new Connection[Utilities.getMaxArity()]; + for (int i = 0; i < connections.length; i++) { + connections[i] = Utilities.getRandomConnection(this, c); + } + nodes[r][c].initialise(Utilities.getRandomFunction(), connections); + } + } + + for (Output output : outputs) { + output.setConnection(Utilities.getRandomNode(this)); } + } public int getActiveNodeCount() { return 0; } - /** - * @return the inputs - */ - public ArrayList getInputs() { - return inputs; - } - - /** - * @return the nodes - */ - public ArrayList> getNodes() { - return nodes; - } - - /** - * @return the outputs - */ - public ArrayList getOutputs() { - return outputs; - } - public Node getNode(int row, int column) { - return nodes.get(row).get(column); + return nodes[row][column]; } public Output getOutput(int index) { - return outputs.get(index); + return outputs[index]; } public Input getInput(int index) { - return inputs.get(index); + return inputs[index]; } public int getFitness() { @@ -117,4 +97,16 @@ public class Chromosome { fitness = newFitness; } + public void setInputs(int ... values) { + // if the values provided dont match the specified number of inputs, the user should be warned + if (values.length == inputs.length) { + // set inputs for evaluation + for (int i = 0; i < values.length; i++) { + inputs[i].setValue(values[i]); + } + } else { + System.out.println("Input mismatch: chromosome has a different number of inputs than the truth table."); + } + } + } diff --git a/src/jcgp/population/Population.java b/src/jcgp/population/Population.java index 67b6695..55f756a 100644 --- a/src/jcgp/population/Population.java +++ b/src/jcgp/population/Population.java @@ -1,21 +1,20 @@ package jcgp.population; -import java.util.ArrayList; import java.util.Iterator; import jcgp.CGP.Parameters; -public final class Population implements Iterable { +public class Population implements Iterable { - private ArrayList population; + private Chromosome[] population; public Population() { - population = new ArrayList(Parameters.getPopulationSize()); - for (int c = 0; c < Parameters.getPopulationSize(); c++) { - population.add(new Chromosome(Parameters.getInputs(), - Parameters.getRows(), - Parameters.getColumns(), - Parameters.getOutputs())); + population = new Chromosome[Parameters.getPopulationSize()]; + for (int c = 0; c < population.length; c++) { + population[c] = new Chromosome(Parameters.getInputs(), + Parameters.getRows(), + Parameters.getColumns(), + Parameters.getOutputs()); } } @@ -27,7 +26,7 @@ public final class Population implements Iterable { @Override public boolean hasNext() { - if (index < population.size()) { + if (index < population.length) { return true; } else { return false; @@ -36,14 +35,14 @@ public final class Population implements Iterable { @Override public Chromosome next() { - Chromosome next = population.get(index); + Chromosome next = population[index]; index++; return next; } @Override public void remove() { - // not allowed + // not allowed } }; -- cgit v1.2.3