diff options
author | Eduardo Pedroni <ep625@york.ac.uk> | 2014-01-31 13:06:54 +0000 |
---|---|---|
committer | Eduardo Pedroni <ep625@york.ac.uk> | 2014-01-31 13:06:54 +0000 |
commit | a02f1fff03ab58416da812597e67a0c7e21fdbd5 (patch) | |
tree | 0192f0db1d1bc8d6d29433f4e84d4c94a89ed2ac | |
parent | 8f7874fa75c532bab994af8e6553d37afe42ec4c (diff) |
Created most of the classes that will be necessary, content is blank for now.
29 files changed, 516 insertions, 125 deletions
@@ -16,4 +16,33 @@ ChromosomeElement tests: - Input returns the value it is set to - Outputs returns a single value from its source Node + + +30/1 + +Added class representations of functions and mutators, as well as the program itself (CGP). +Modified the way the chromosome stores its data to allow for more flexible mutations. + +31/1 + +Parity will be considered constant, at 2, for now. + +Added static nested classes for system-wide resources such as a random number generator, the function set +and the parameter set. These can be accessed from anywhere within the program, but not modified by any class +but CGP. + +Modularized design: + +Modules for fitness function, mutation operator, evolutionary algorithm and population. + +FF, EA and mutation modules act as callbacks; the user may specify how the module does its job, +but must comply with the interface. + +Population is slightly more complex: the user may define a custom chromosome and use it to generate a population, +so long as it extends Chromosome. In conjunction with modularized FF, EA and mutation, this makes for a very +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. + + +
\ No newline at end of file diff --git a/src/jcgp/CGP.java b/src/jcgp/CGP.java index d2cae80..e18e0ea 100644 --- a/src/jcgp/CGP.java +++ b/src/jcgp/CGP.java @@ -1,12 +1,205 @@ package jcgp; -public class CGP<T> { +import java.util.Random; + +import jcgp.ea.EvolutionaryAlgorithm; +import jcgp.ea.StandardEA; +import jcgp.ea.StandardMutator; +import jcgp.fitness.FitnessFunction; +import jcgp.fitness.TestFitFunction; +import jcgp.function.Addition; +import jcgp.function.Function; +import jcgp.function.FunctionSet; +import jcgp.function.Subtraction; +import jcgp.population.Population; + +public class CGP { - public static int ROWS, COLUMNS, INPUTS, OUTPUTS, MUTATION_RATE, GENERATIONS, RUNS; + public static class Parameters { + private static int rows, columns, inputs, outputs, mutationRate, generations, runs, populationSize; - public CGP() { + /** + * @return the populationSize + */ + public static int getPopulationSize() { + return populationSize; + } + + /** + * @param populationSize the populationSize to set + */ + private static void setPopulationSize(int populationSize) { + Parameters.populationSize = populationSize; + } + + /** + * @return the rows + */ + public static int getRows() { + return rows; + } + + /** + * @return the columns + */ + public static int getColumns() { + return columns; + } + + /** + * @return the inputs + */ + public static int getInputs() { + return inputs; + } + + /** + * @return the outputs + */ + public static int getOutputs() { + return outputs; + } + + /** + * @return the mutationRate + */ + public static int getMutationRate() { + return mutationRate; + } + + /** + * @return the generations + */ + public static int getGenerations() { + return generations; + } + + /** + * @return the runs + */ + public static int getRuns() { + return runs; + } + + /** + * @param rows the rows to set + */ + private static void setRows(int rows) { + Parameters.rows = rows; + } + + /** + * @param columns the columns to set + */ + private static void setColumns(int columns) { + Parameters.columns = columns; + } + + /** + * @param inputs the inputs to set + */ + private static void setInputs(int inputs) { + Parameters.inputs = inputs; + } + + /** + * @param outputs the outputs to set + */ + private static void setOutputs(int outputs) { + Parameters.outputs = outputs; + } + + /** + * @param mutationRate the mutationRate to set + */ + private static void setMutationRate(int mutationRate) { + Parameters.mutationRate = mutationRate; + } + + /** + * @param generations the generations to set + */ + private static void setGenerations(int generations) { + Parameters.generations = generations; + } + + /** + * @param runs the runs to set + */ + private static void setRuns(int runs) { + Parameters.runs = runs; + } } + public static class Utilities { + + public static int getRandomInt(int limit){ + return numberGenerator.nextInt(limit); + } + + public static double getRandomDouble(int limit){ + return numberGenerator.nextDouble() * limit; + } + + public static Function getRandomFunction() { + return functionSet.getFunction(Utilities.getRandomInt(functionSet.getFunctionCount())); + } + + public static Function getFunction(int index) { + return functionSet.getFunction(index); + } + } + + // system-wide resources + private static FunctionSet functionSet; + private static Random numberGenerator; + + // + private FitnessFunction fitnessFunction; + private EvolutionaryAlgorithm ea; + private Population population; + + public CGP() { + initialise(); + + fitnessFunction.evaluatePopulation(population); + + ea.evolve(population); + } + /** + * + */ + private void initialise() { + // initialise random number generator + numberGenerator = new Random(1234); + + // initialise parameters + Parameters.setInputs(3); + Parameters.setColumns(3); + Parameters.setRows(3); + Parameters.setOutputs(3); + Parameters.setGenerations(10); + Parameters.setMutationRate(1); + Parameters.setRuns(5); + Parameters.setPopulationSize(5); + + // initialise function set + functionSet = new FunctionSet(); + functionSet.setFunctions(new Addition(), new Subtraction()); + + // initialise EA + ea = new StandardEA(new StandardMutator()); + + // initialise fitness function + fitnessFunction = new TestFitFunction(); + + // initialise population + population = new Population(Parameters.getInputs(), + Parameters.getRows(), + Parameters.getColumns(), + Parameters.getOutputs(), + Parameters.getPopulationSize()); + } } diff --git a/src/jcgp/Main.java b/src/jcgp/Main.java index 007e617..39f3c4b 100644 --- a/src/jcgp/Main.java +++ b/src/jcgp/Main.java @@ -3,7 +3,7 @@ package jcgp; public class Main { public static void main(String[] args) { - // TODO Auto-generated method stub + CGP cgp = new CGP(); } diff --git a/src/jcgp/chromosome/Population.java b/src/jcgp/chromosome/Population.java deleted file mode 100644 index e720a24..0000000 --- a/src/jcgp/chromosome/Population.java +++ /dev/null @@ -1,16 +0,0 @@ -package jcgp.chromosome; - -import java.util.ArrayList; - -public class Population { - - private ArrayList<Chromosome> population; - - public Population(int size) { - population = new ArrayList<Chromosome>(size); - for (int c = 0; c < size; c++) { - population.add(new Chromosome()); - } - } - -} diff --git a/src/jcgp/chromosome/element/ChromosomeElement.java b/src/jcgp/chromosome/element/ChromosomeElement.java deleted file mode 100644 index 2dc9107..0000000 --- a/src/jcgp/chromosome/element/ChromosomeElement.java +++ /dev/null @@ -1,7 +0,0 @@ -package jcgp.chromosome.element; - -public abstract class ChromosomeElement { - - public abstract int evaluate(); - -} diff --git a/src/jcgp/chromosome/element/Input.java b/src/jcgp/chromosome/element/Input.java deleted file mode 100644 index de051dc..0000000 --- a/src/jcgp/chromosome/element/Input.java +++ /dev/null @@ -1,11 +0,0 @@ -package jcgp.chromosome.element; - -public class Input extends ChromosomeElement { - - @Override - public int evaluate() { - // TODO Auto-generated method stub - return 0; - } - -} diff --git a/src/jcgp/chromosome/element/Node.java b/src/jcgp/chromosome/element/Node.java deleted file mode 100644 index 761c3c9..0000000 --- a/src/jcgp/chromosome/element/Node.java +++ /dev/null @@ -1,20 +0,0 @@ -package jcgp.chromosome.element; - -import jcgp.chromosome.functions.Function; - - -public class Node extends ChromosomeElement implements MutableElement { - - private Function function; - - public Node() { - - } - - @Override - public int evaluate() { - // TODO Auto-generated method stub - return 0; - } - -} diff --git a/src/jcgp/chromosome/element/Output.java b/src/jcgp/chromosome/element/Output.java deleted file mode 100644 index ee4d204..0000000 --- a/src/jcgp/chromosome/element/Output.java +++ /dev/null @@ -1,12 +0,0 @@ -package jcgp.chromosome.element; - - -public class Output extends ChromosomeElement implements MutableElement { - - @Override - public int evaluate() { - // TODO Auto-generated method stub - return 0; - } - -} diff --git a/src/jcgp/chromosome/functions/Function.java b/src/jcgp/chromosome/functions/Function.java deleted file mode 100644 index 27697be..0000000 --- a/src/jcgp/chromosome/functions/Function.java +++ /dev/null @@ -1,7 +0,0 @@ -package jcgp.chromosome.functions; - -public abstract class Function { - - public abstract int run(); - -} diff --git a/src/jcgp/chromosome/functions/FunctionSet.java b/src/jcgp/chromosome/functions/FunctionSet.java deleted file mode 100644 index e9d197a..0000000 --- a/src/jcgp/chromosome/functions/FunctionSet.java +++ /dev/null @@ -1,14 +0,0 @@ -package jcgp.chromosome.functions; - -import java.util.ArrayList; - -public class FunctionSet { - - private ArrayList<Function> functions; - - public FunctionSet() { - functions = new ArrayList<Function>(); - } - - -} diff --git a/src/jcgp/ea/EvolutionaryAlgorithm.java b/src/jcgp/ea/EvolutionaryAlgorithm.java new file mode 100644 index 0000000..6e264aa --- /dev/null +++ b/src/jcgp/ea/EvolutionaryAlgorithm.java @@ -0,0 +1,15 @@ +package jcgp.ea; + +import jcgp.population.Population; + +public abstract class EvolutionaryAlgorithm { + + protected Mutator mutator; + + public EvolutionaryAlgorithm(Mutator mutator) { + this.mutator = mutator; + } + + public abstract void evolve(Population population); + +} diff --git a/src/jcgp/ea/Mutator.java b/src/jcgp/ea/Mutator.java new file mode 100644 index 0000000..df3fe1c --- /dev/null +++ b/src/jcgp/ea/Mutator.java @@ -0,0 +1,9 @@ +package jcgp.ea; + +import jcgp.population.Chromosome; + +public interface Mutator { + + void mutate(Chromosome chromosome); + +} diff --git a/src/jcgp/ea/StandardEA.java b/src/jcgp/ea/StandardEA.java new file mode 100644 index 0000000..fe0b3f9 --- /dev/null +++ b/src/jcgp/ea/StandardEA.java @@ -0,0 +1,20 @@ +package jcgp.ea; + +import jcgp.population.Chromosome; +import jcgp.population.Population; + +public class StandardEA extends EvolutionaryAlgorithm { + + public StandardEA(Mutator mutator) { + super(mutator); + + } + + @Override + public void evolve(Population population) { + for (Chromosome chromosome : population) { + mutator.mutate(chromosome); + } + } + +} diff --git a/src/jcgp/ea/StandardMutator.java b/src/jcgp/ea/StandardMutator.java new file mode 100644 index 0000000..731215d --- /dev/null +++ b/src/jcgp/ea/StandardMutator.java @@ -0,0 +1,13 @@ +package jcgp.ea; + +import jcgp.population.Chromosome; + +public class StandardMutator implements Mutator { + + @Override + public void mutate(Chromosome chromosome) { + + + } + +} diff --git a/src/jcgp/fitness/FitnessFunction.java b/src/jcgp/fitness/FitnessFunction.java new file mode 100644 index 0000000..2155542 --- /dev/null +++ b/src/jcgp/fitness/FitnessFunction.java @@ -0,0 +1,9 @@ +package jcgp.fitness; + +import jcgp.population.Population; + +public interface FitnessFunction { + + public void evaluatePopulation(Population population); + +} diff --git a/src/jcgp/fitness/TestFitFunction.java b/src/jcgp/fitness/TestFitFunction.java new file mode 100644 index 0000000..fea9f2d --- /dev/null +++ b/src/jcgp/fitness/TestFitFunction.java @@ -0,0 +1,15 @@ +package jcgp.fitness; + +import jcgp.population.Chromosome; +import jcgp.population.Population; + +public class TestFitFunction implements FitnessFunction { + + @Override + public void evaluatePopulation(Population population) { + + for (Chromosome c : population) { + c.setFitness(1); + } + } +} diff --git a/src/jcgp/function/Addition.java b/src/jcgp/function/Addition.java new file mode 100644 index 0000000..7dc17e2 --- /dev/null +++ b/src/jcgp/function/Addition.java @@ -0,0 +1,18 @@ +package jcgp.function; + +import jcgp.population.Connection; + +public class Addition extends Function { + + @Override + public int run(Connection... connections) { + int sum = 0; + if (connections.length > 0) { + for (int i = 0; i < connections.length; i++) { + sum += connections[i].evaluate(); + } + } + return sum; + } + +} diff --git a/src/jcgp/function/Function.java b/src/jcgp/function/Function.java new file mode 100644 index 0000000..0f0d8a3 --- /dev/null +++ b/src/jcgp/function/Function.java @@ -0,0 +1,9 @@ +package jcgp.function; + +import jcgp.population.Connection; + +public abstract class Function { + + public abstract int run(Connection ... connections); + +} diff --git a/src/jcgp/function/FunctionSet.java b/src/jcgp/function/FunctionSet.java new file mode 100644 index 0000000..e2d04a0 --- /dev/null +++ b/src/jcgp/function/FunctionSet.java @@ -0,0 +1,31 @@ +package jcgp.function; + +import java.util.ArrayList; + + +public class FunctionSet { + private ArrayList<Function> functionList; + + public void setFunctions(Function ... functions) { + functionList = new ArrayList<Function>(functions.length); + + for (int i = 0; i < functions.length; i++) { + functionList.add(functions[i]); + } + } + + public void addFunction(Function newFunction) { + if (functionList == null) { + functionList = new ArrayList<Function>(); + } + functionList.add(newFunction); + } + + public int getFunctionCount() { + return functionList.size(); + } + + public Function getFunction(int index) { + return functionList.get(index); + } + }
\ No newline at end of file diff --git a/src/jcgp/function/Subtraction.java b/src/jcgp/function/Subtraction.java new file mode 100644 index 0000000..70297c3 --- /dev/null +++ b/src/jcgp/function/Subtraction.java @@ -0,0 +1,16 @@ +package jcgp.function; + +import jcgp.population.Connection; + +public class Subtraction extends Function { + + @Override + public int run(Connection... connections) { + int subtraction = 0; + if (connections.length > 1) { + subtraction = connections[0].evaluate() - connections[1].evaluate(); + } + return subtraction; + } + +} diff --git a/src/jcgp/mutator/Mutator.java b/src/jcgp/mutator/Mutator.java deleted file mode 100644 index 577aa42..0000000 --- a/src/jcgp/mutator/Mutator.java +++ /dev/null @@ -1,15 +0,0 @@ -package jcgp.mutator; - -import jcgp.chromosome.Population; - -public class Mutator { - - public Mutator() { - - } - - public void mutate(Population population, int rate) { - - } - -} diff --git a/src/jcgp/chromosome/Chromosome.java b/src/jcgp/population/Chromosome.java index cdf2e4b..2e22cf9 100644 --- a/src/jcgp/chromosome/Chromosome.java +++ b/src/jcgp/population/Chromosome.java @@ -1,42 +1,44 @@ -package jcgp.chromosome; +package jcgp.population; import java.util.ArrayList; -import jcgp.CGP; -import jcgp.chromosome.element.Input; -import jcgp.chromosome.element.Node; -import jcgp.chromosome.element.Output; - public class Chromosome { private ArrayList<Input> inputs; private ArrayList<ArrayList<Node>> nodes; private ArrayList<Output> outputs; + private int fitness = 0; + /** * Good citizen. + * @param outputs + * @param columns + * @param rows + * @param inputs * */ - public Chromosome() { + public Chromosome(int inputCount, int rows, int columns, int outputCount) { - inputs = new ArrayList<Input>(CGP.INPUTS); - for (int i = 0; i < CGP.INPUTS; i++) { + inputs = new ArrayList<Input>(inputCount); + for (int i = 0; i < inputCount; i++) { inputs.add(new Input()); } // rows first - nodes = new ArrayList<ArrayList<Node>>(CGP.ROWS); - for (int r = 0; r < CGP.ROWS; r++) { - nodes.add(new ArrayList<Node>(CGP.COLUMNS)); - for (int c = 0; c < CGP.COLUMNS; c++) { + nodes = new ArrayList<ArrayList<Node>>(rows); + for (int r = 0; r < rows; r++) { + nodes.add(new ArrayList<Node>(columns)); + for (int c = 0; c < columns; c++) { nodes.get(r).add(new Node()); } } - outputs = new ArrayList<Output>(CGP.OUTPUTS); - for (int o = 0; o < CGP.OUTPUTS; o++) { + outputs = new ArrayList<Output>(outputCount); + for (int o = 0; o < outputCount; o++) { outputs.add(new Output()); } + } public int getActiveNodeCount() { @@ -76,4 +78,12 @@ public class Chromosome { return inputs.get(index); } + public int getFitness() { + return fitness; + } + + public void setFitness(int newFitness) { + fitness = newFitness; + } + } diff --git a/src/jcgp/population/Connection.java b/src/jcgp/population/Connection.java new file mode 100644 index 0000000..fa02a22 --- /dev/null +++ b/src/jcgp/population/Connection.java @@ -0,0 +1,6 @@ +package jcgp.population; + +public interface Connection { + + public abstract int evaluate(); +} diff --git a/src/jcgp/population/Input.java b/src/jcgp/population/Input.java new file mode 100644 index 0000000..b9c127f --- /dev/null +++ b/src/jcgp/population/Input.java @@ -0,0 +1,16 @@ +package jcgp.population; + +public class Input implements Connection { + + private int value = 0; + + public void setValue(int newValue) { + value = newValue; + } + + @Override + public int evaluate() { + return value; + } + +} diff --git a/src/jcgp/chromosome/element/MutableElement.java b/src/jcgp/population/MutableElement.java index 0122c69..4397e46 100644 --- a/src/jcgp/chromosome/element/MutableElement.java +++ b/src/jcgp/population/MutableElement.java @@ -1,4 +1,4 @@ -package jcgp.chromosome.element; +package jcgp.population; public interface MutableElement { diff --git a/src/jcgp/population/Node.java b/src/jcgp/population/Node.java new file mode 100644 index 0000000..cce8dfd --- /dev/null +++ b/src/jcgp/population/Node.java @@ -0,0 +1,28 @@ +package jcgp.population; + +import jcgp.function.Function; + + +public class Node implements MutableElement, Connection { + + private Function function; + private Connection[] connections; + + public Node() { + + } + + @Override + public int evaluate() { + return function.run(connections[0], connections[1]); + } + + public void setFunction(Function newFunction) { + function = newFunction; + } + + public void setConnection(Connection newConnection) { + + } + +} diff --git a/src/jcgp/population/Output.java b/src/jcgp/population/Output.java new file mode 100644 index 0000000..2f2df6e --- /dev/null +++ b/src/jcgp/population/Output.java @@ -0,0 +1,11 @@ +package jcgp.population; + + +public class Output implements MutableElement { + + public int calculate() { + // TODO Auto-generated method stub + return 0; + } + +} diff --git a/src/jcgp/population/Population.java b/src/jcgp/population/Population.java new file mode 100644 index 0000000..e1a9a3c --- /dev/null +++ b/src/jcgp/population/Population.java @@ -0,0 +1,46 @@ +package jcgp.population; + +import java.util.ArrayList; +import java.util.Iterator; + +public final class Population implements Iterable<Chromosome> { + + private ArrayList<Chromosome> population; + + public Population(int inputs, int rows, int columns, int outputs, int size) { + population = new ArrayList<Chromosome>(size); + for (int c = 0; c < size; c++) { + population.add(new Chromosome(inputs, rows, columns, outputs)); + } + } + + @Override + public Iterator<Chromosome> iterator() { + return new Iterator<Chromosome>() { + + private int index = 0; + + @Override + public boolean hasNext() { + if (index < population.size()) { + return true; + } else { + return false; + } + } + + @Override + public Chromosome next() { + Chromosome next = population.get(index); + index++; + return next; + } + + @Override + public void remove() { + // not allowed + } + + }; + } +} diff --git a/src/jcgp/tests/Tests.java b/src/jcgp/tests/Tests.java index 28bfd3d..8fbf0be 100644 --- a/src/jcgp/tests/Tests.java +++ b/src/jcgp/tests/Tests.java @@ -1,6 +1,6 @@ package jcgp.tests; -import static org.junit.Assert.*; +import static org.junit.Assert.fail; import org.junit.Before; import org.junit.Test; @@ -11,13 +11,12 @@ public class Tests { public void setUp() throws Exception { - } @Test public void test() { fail("Not yet implemented"); - + } } |