aboutsummaryrefslogtreecommitdiffstats
path: root/src/jcgp/backend/tests
diff options
context:
space:
mode:
authorEduardo Pedroni <ep625@york.ac.uk>2014-04-01 23:00:53 +0100
committerEduardo Pedroni <ep625@york.ac.uk>2014-04-01 23:00:53 +0100
commit02fd2bc7059da416937beb1abe67e5ca60379030 (patch)
tree609341fe10aaa0f2dc45a1e72eba20bd24fb1281 /src/jcgp/backend/tests
parenta757deacded0d7357a9f68462d3f2051e16004ee (diff)
Settings pane now actually controls the parameters, not much left to do.
Diffstat (limited to 'src/jcgp/backend/tests')
-rw-r--r--src/jcgp/backend/tests/ChromosomeTests.java334
-rw-r--r--src/jcgp/backend/tests/InputTests.java47
-rw-r--r--src/jcgp/backend/tests/NodeTests.java196
-rw-r--r--src/jcgp/backend/tests/OutputTests.java93
-rw-r--r--src/jcgp/backend/tests/PopulationTests.java86
5 files changed, 756 insertions, 0 deletions
diff --git a/src/jcgp/backend/tests/ChromosomeTests.java b/src/jcgp/backend/tests/ChromosomeTests.java
new file mode 100644
index 0000000..1cd067e
--- /dev/null
+++ b/src/jcgp/backend/tests/ChromosomeTests.java
@@ -0,0 +1,334 @@
+package jcgp.backend.tests;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import jcgp.JCGP.Resources;
+import jcgp.backend.population.Chromosome;
+import jcgp.backend.population.Connection;
+import jcgp.backend.population.Input;
+import jcgp.backend.population.MutableElement;
+import jcgp.backend.population.Node;
+import jcgp.backend.population.Output;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ *
+ * Tests which cover the behaviour specified for a chromosome.
+ *
+ * - The chromosome should be able to return a specified node, input or output.
+ * - It should be able to return a random MutableElement.
+ * - It should be able to return a random allowed connection given a column.
+ * - It should be able to return a random connection.
+ * - It should contain a freely modifiable fitness value.
+ * - For truth table evaluations, it should be able to have its inputs set.
+ * - For truth table evaluations, the output should return a value according to the inputs.
+ * - It should feature a copy method, which creates a deep copy of a specified Chromosome object.
+ * - It should be able to return a list of active nodes.
+ * - It should contain a method to evaluate whether a given chromosome is identical
+ * to it.
+ * - Same as above, but only looking at the active portion of a chromosome.
+ *
+ *
+ * WARNING: changing parameters may cause the tests to incorrectly fail!
+ *
+ * @author Eduardo Pedroni
+ *
+ */
+public class ChromosomeTests {
+
+ private Chromosome chromosome;
+ private static Resources resources;
+
+ @BeforeClass
+ public static void setUpBeforeClass() {
+ resources = new Resources();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ chromosome = new Chromosome(resources);
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void cloneTest() {
+ // create a clone, check to see if it really is a clone
+ Chromosome clone = new Chromosome(chromosome);
+
+ // compare all elements, one by one
+ // check outputs
+ for (int o = 0; o < resources.getInt("outputs"); o++) {
+ // check that no cross-references exist between chromosomes
+ assertTrue("Cloned chromosome contains a reference to a member of the original chromosome.",
+ clone.getOutput(o) != chromosome.getOutput(o) &&
+ clone.getOutput(o).getSource() != chromosome.getOutput(o).getSource());
+ // check that the connections are equivalent
+ if (clone.getOutput(o).getSource() instanceof Input && chromosome.getOutput(o).getSource() instanceof Input) {
+ assertTrue("Outputs did not connect to equivalent inputs.",
+ ((Input) clone.getOutput(o).getSource()).getIndex() == ((Input) chromosome.getOutput(o).getSource()).getIndex());
+ } else if (clone.getOutput(o).getSource() instanceof Node && chromosome.getOutput(o).getSource() instanceof Node) {
+ assertTrue("Outputs did not connect to equivalent nodes.",
+ ((Node) clone.getOutput(o).getSource()).getRow() == ((Node) chromosome.getOutput(o).getSource()).getRow() &&
+ ((Node) clone.getOutput(o).getSource()).getColumn() == ((Node) chromosome.getOutput(o).getSource()).getColumn());
+ } else {
+ fail("Output source types did not match.");
+ }
+ }
+ // check nodes, rows first
+ for (int row = 0; row < resources.getInt("rows"); row++) {
+ for (int column = 0; column < resources.getInt("columns"); column++) {
+ // check that nodes are not pointers to the same instance
+ assertTrue("Both chromosomes contain a reference to the same node.", clone.getNode(row, column) != chromosome.getNode(row, column));
+ // check that both nodes reference their own position in the grid correctly
+ assertTrue("Equivalent nodes self-reference differently.", clone.getNode(row, column).getRow() == chromosome.getNode(row, column).getRow() &&
+ clone.getNode(row, column).getColumn() == chromosome.getNode(row, column).getColumn());
+ // check that the two nodes have the same function
+ assertTrue("Equivalent nodes have different functions.", clone.getNode(row, column).getFunction() == chromosome.getNode(row, column).getFunction());
+
+ // compare each connection
+ for (int connection = 0; connection < resources.getInt("arity"); connection++) {
+ // first look at whether they are actually the same instance
+ assertTrue("Nodes are connected to the same connection instance.",
+ clone.getNode(row, column).getConnection(connection) != chromosome.getNode(row, column).getConnection(connection));
+
+ // if the connections aren't the same instance, check that their addresses are the same
+ if (clone.getNode(row, column).getConnection(connection) instanceof Input &&
+ chromosome.getNode(row, column).getConnection(connection) instanceof Input) {
+
+ assertTrue("Nodes did not connect to equivalent inputs.",
+ ((Input) clone.getNode(row, column).getConnection(connection)).getIndex() ==
+ ((Input) chromosome.getNode(row, column).getConnection(connection)).getIndex());
+
+ } else if (clone.getNode(row, column).getConnection(connection) instanceof Node &&
+ chromosome.getNode(row, column).getConnection(connection) instanceof Node) {
+
+ assertTrue("Nodes did not connect to equivalent nodes.",
+ ((Node) clone.getNode(row, column).getConnection(connection)).getRow() ==
+ ((Node) chromosome.getNode(row, column).getConnection(connection)).getRow() &&
+
+ ((Node) clone.getNode(row, column).getConnection(connection)).getColumn() ==
+ ((Node) chromosome.getNode(row, column).getConnection(connection)).getColumn());
+
+ } else {
+ fail("Connection types did not match.");
+ }
+ }
+ }
+ }
+
+ // check cloning given a known topology
+ chromosome = createKnownConfiguration();
+ clone = new Chromosome(chromosome);
+
+ Integer[] testInputs = new Integer[] {5, 8, 4};
+ chromosome.setInputs((Object[]) testInputs);
+ clone.setInputs((Object[]) testInputs);
+
+ // check that both chromosomes have the same outputs
+ for (int i = 0; i < resources.getInt("outputs"); i++) {
+ assertTrue("Incorrect output returned", ((Integer) chromosome.getOutput(i).calculate()) == ((Integer) clone.getOutput(i).calculate()));
+ }
+
+ // mutate an output in clone, check that the same node in chromosome produces a different output
+ clone.getOutput(1).setConnection(resources.getRandomInt(resources.getInt("arity")), clone.getInput(2));
+
+ assertTrue("Mutation affected nodes in both chromosomes.",
+ clone.getOutput(1).calculate() != chromosome.getOutput(1).calculate());
+
+ }
+ /**
+ *
+ */
+ @Test
+ public void fitnessTest() {
+ // set a fitness value, check if returned value is the same
+ chromosome.setFitness(10);
+ assertTrue("Incorrect fitness returned.", chromosome.getFitness() == 10);
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void randomConnectionTest() {
+ // get random connections with column 0, check that they are all inputs
+ for (int i = 0; i < 10000; i++) {
+ boolean connectionReturn = chromosome.getRandomConnection(0) instanceof Input;
+ assertTrue("Connection is not an input.", connectionReturn);
+ }
+
+ // get random connections with the last column as reference, check that they're all within range
+ int connectionNodes = 0, connectionOutOfRange = 0, connectionInputs = 0, connectionPicks = 100000;
+ int chosenColumn = resources.getInt("columns") - 1;
+ for (int i = 0; i < connectionPicks; i++) {
+ Connection c = chromosome.getRandomConnection(chosenColumn);
+ if (c instanceof Node) {
+ connectionNodes++;
+ if (((Node) c).getColumn() >= chosenColumn) {
+ connectionOutOfRange++;
+ }
+ assertTrue("Connection is not allowed : " + ((Node) c).getColumn(), ((Node) c).getColumn() < chosenColumn && ((Node) c).getColumn() < chosenColumn);
+ } else if (c instanceof Input) {
+ connectionInputs++;
+ } else {
+ fail("Return is neither Node nor Input.");
+
+ }
+ }
+ System.out.println("Out of " + connectionPicks + " connections picked from " + ((chosenColumn >= resources.getInt("levelsBack")) ? resources.getInt("levelsBack") : chosenColumn) * resources.getInt("rows") +
+ " allowed nodes and " + resources.getInt("inputs") + " inputs, " + connectionNodes + " were nodes and " + connectionInputs + " were inputs.");
+
+ System.out.println("Node/input ratio: " + (chosenColumn >= resources.getInt("levelsBack") ? resources.getInt("levelsBack") : chosenColumn) * resources.getDouble("rows") / resources.getDouble("inputs") +
+ ", picked ratio: " + (double) connectionNodes / (double) connectionInputs);
+
+ System.out.println(connectionOutOfRange + " nodes that disrespected levels back were picked.");
+ }
+ /**
+ *
+ */
+ @Test
+ public void randomMutableTest() {
+ // get mutable elements, check Node to Output ratio
+ int mutablePicks = 100000;
+ int mutableNodes = 0, mutableOutputs = 0;
+ for (int i = 0; i < mutablePicks; i++) {
+ MutableElement m = chromosome.getRandomMutableElement();
+
+ if (m instanceof Node) {
+ mutableNodes++;
+ } else if (m instanceof Output) {
+ mutableOutputs++;
+ } else {
+ fail("Return is neither Node nor Output.");
+ }
+ }
+ System.out.println("Out of " + mutablePicks + " mutable elements picked from " + resources.getInt("nodes") +
+ " nodes and " + resources.getInt("outputs") + " outputs, " + mutableNodes + " were nodes and " +
+ mutableOutputs + " were outputs.");
+ System.out.println("Node/output ratio: " + resources.getDouble("nodes") / resources.getDouble("outputs") +
+ ", picked ratio: " + (double) mutableNodes / (double) mutableOutputs + "\n");
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void getOutputsTest() {
+ chromosome = createKnownConfiguration();
+
+ chromosome.setInputs(5, 8, 4);
+
+ // with this configuration, the outputs should be 13 and 25.
+ assertTrue("Incorrect output returned.", (Integer) chromosome.getOutput(0).calculate() == 13);
+ assertTrue("Incorrect output returned.", (Integer) chromosome.getOutput(1).calculate() == 25);
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void setInputTest() {
+ // set input values, check that acquired values are correct
+ Integer[] testInputs = new Integer[resources.getInt("inputs")];
+ for (int i = 0; i < resources.getInt("inputs"); i++) {
+ testInputs[i] = i * 2 - 3;
+ }
+ chromosome.setInputs((Object[]) testInputs);
+ for (int i = 0; i < resources.getInt("inputs"); i++) {
+ assertTrue("Incorrect input returned.", ((Integer) chromosome.getInput(i).getValue()) == i * 2 - 3);
+ }
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void getNodeTest() {
+ // get all nodes one by one, check that they are all correct
+ for (int r = 0; r < resources.getInt("rows"); r++) {
+ for (int c = 0; c < resources.getInt("columns"); c++) {
+ assertTrue("Incorrect node returned.", chromosome.getNode(r, c).getColumn() == c &&
+ chromosome.getNode(r, c).getRow() == r);
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void activeNodeTest() {
+ // active node detection happens recursively, the user only calls a single method
+ // set connections to a known configuration
+ chromosome = createKnownConfiguration();
+
+ assertTrue("Active node missing from list.", chromosome.getActiveNodes().contains(chromosome.getNode(0, 0)));
+ assertTrue("Active node missing from list.", chromosome.getActiveNodes().contains(chromosome.getNode(1, 1)));
+ assertTrue("Active node missing from list.", chromosome.getActiveNodes().contains(chromosome.getNode(1, 2)));
+
+ assertTrue("List has the wrong number of nodes.", chromosome.getActiveNodes().size() == 3);
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void compareActiveTest() {
+ // create a clone of the chromosome, compare active nodes - should return true
+ Chromosome c = new Chromosome(chromosome);
+ assertTrue("Active nodes did not match.", chromosome.compareActiveTo(c));
+ assertTrue("Symmetry not obeyed.", c.compareActiveTo(chromosome));
+
+ // create a new random chromosome, this time they should not match
+ c = new Chromosome(resources);
+ assertTrue("Active nodes did match.", !chromosome.compareActiveTo(c));
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void compareTest() {
+ // create a clone of the chromosome, compare - should return true
+ Chromosome c = new Chromosome(chromosome);
+ assertTrue("Chromosomes did not match.", chromosome.compareTo(c));
+ assertTrue("Symmetry not obeyed.", c.compareTo(chromosome));
+
+ // create a new random chromosome, this time they should not match
+ c = new Chromosome(resources);
+ assertTrue("Chromosomes did match.", !chromosome.compareTo(c));
+ }
+ /**
+ * Utility for creating a chromosome of known configuration.
+ * Topology is 3x3, with 3 inputs and 2 outputs.
+ * Given inputs 5, 8 and 4 outputs should be 13 and 25.
+ *
+ * Active nodes (r, c): [0, 0], [1, 1], [1, 2]
+ *
+ * @return the configured chromosome
+ */
+ private Chromosome createKnownConfiguration() {
+ // with a small topology, build a chromosome of known connections and check outputs
+ resources.set("columns", 3);
+ resources.set("rows", 3);
+ resources.set("inputs", 3);
+ resources.set("outputs", 2);
+ resources.set("levelsBack", 3);
+
+ Chromosome c = new Chromosome(resources);
+
+ c.getNode(0, 0).initialise(resources.getFunction(0), c.getInput(0), c.getInput(1));
+ c.getNode(1, 1).initialise(resources.getFunction(0), c.getNode(0, 0), c.getInput(1));
+ c.getNode(1, 2).initialise(resources.getFunction(0), c.getNode(1, 1), c.getInput(2));
+
+ c.getOutput(0).setConnection(0, c.getNode(0, 0));
+ c.getOutput(1).setConnection(0, c.getNode(1, 2));
+
+ return c;
+ }
+}
diff --git a/src/jcgp/backend/tests/InputTests.java b/src/jcgp/backend/tests/InputTests.java
new file mode 100644
index 0000000..4d15667
--- /dev/null
+++ b/src/jcgp/backend/tests/InputTests.java
@@ -0,0 +1,47 @@
+package jcgp.backend.tests;
+
+import static org.junit.Assert.assertTrue;
+import jcgp.backend.population.Input;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ *
+ * Tests which cover the behaviour specified for an input.
+ *
+ * - An input contains a single set value. This value can be freely set for
+ * fitness evaluation purposes.
+ * - It must be addressable by an index set upon construction only.
+ *
+ *
+ * @author Eduardo Pedroni
+ *
+ */
+public class InputTests {
+
+ private Input input;
+ // these are the test values
+ private final int inputValue = 19;
+ private final int inputIndex = 12;
+
+ @Before
+ public void setUp() throws Exception {
+ input = new Input(inputIndex);
+ }
+
+ @Test
+ public void valueTest() {
+ // assign a value to input, check that the returned value is correct
+ input.setValue(inputValue);
+
+ assertTrue("Incorrect value returned.", ((Integer) input.getValue()) == inputValue);
+ }
+
+ @Test
+ public void indexTest() {
+ // check that the index returned is the one passed to the constructor
+ assertTrue("Incorrect index returned.", input.getIndex() == inputIndex);
+ }
+
+}
diff --git a/src/jcgp/backend/tests/NodeTests.java b/src/jcgp/backend/tests/NodeTests.java
new file mode 100644
index 0000000..7121e81
--- /dev/null
+++ b/src/jcgp/backend/tests/NodeTests.java
@@ -0,0 +1,196 @@
+package jcgp.backend.tests;
+
+import static org.junit.Assert.assertTrue;
+import jcgp.JCGP.Resources;
+import jcgp.backend.function.Arithmetic;
+import jcgp.backend.function.Function;
+import jcgp.backend.population.Chromosome;
+import jcgp.backend.population.Connection;
+import jcgp.backend.population.Node;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ *
+ * Tests which cover the behaviour specified for a node.
+ *
+ * - A node should contain read-only row and column values which are set upon construction.
+ * - It should contain a fully accessible Function object.
+ * - It should contain a set of connections which can be initialised and randomly
+ * modified. It should be able to return an addressed connection.
+ * - It should be able to compute a value using its function with its connections as arguments.
+ *
+ * WARNING: changing parameters may cause the tests to incorrectly fail!
+ *
+ * @author Eduardo Pedroni
+ *
+ */
+public class NodeTests {
+
+ private Node node;
+ private static Chromosome chromosome;
+ private static Resources resources;
+ // these numbers will be used by the node under test
+ private final int arg1 = 2;
+ private final int arg2 = 5;
+
+ @BeforeClass
+ public static void setUpBeforeClass() {
+
+ resources = new Resources();
+
+ chromosome = new Chromosome(resources);
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ node = new Node(chromosome, 0, 0, resources.getInt("arity"));
+ // make node with anonymous addition function and hard-coded value connections
+ node.initialise(new Arithmetic.Addition(),
+ new Connection[]{new Connection() {
+
+ @Override
+ public Object getValue() {
+ // hardcode a value
+ return arg1;
+ }
+
+ @Override
+ public String getDescription() {
+ // blank
+ return null;
+ }
+
+ },
+ new Connection() {
+
+ @Override
+ public Object getValue() {
+ // hardcode a value
+ return arg2;
+ }
+
+ @Override
+ public String getDescription() {
+ // blank
+ return null;
+ }
+
+ }});
+ }
+
+ @Test
+ public void rowAndColumnTest() {
+ assertTrue("Incorrect row.", node.getRow() == 0);
+ assertTrue("Incorrect column.", node.getColumn() == 0);
+ }
+
+ @Test
+ public void functionTest() {
+ // make a new function and assign to node
+ Function f = new Function() {
+
+ @Override
+ public Object run(Connection... connections) {
+ // blank
+ return 0;
+ }
+
+ @Override
+ public int getArity() {
+ // blank
+ return 0;
+ }
+
+ @Override
+ public String getName() {
+ // blank
+ return null;
+ }
+ };
+
+ node.setFunction(f);
+
+ // check that the function returned by the node is f
+ assertTrue("Incorrect function returned.", node.getFunction() == f);
+ // check that it outputs 0 as it should
+ assertTrue("Incorrect function output.", ((Integer) node.getValue()) == 0);
+ }
+
+ @Test
+ public void evaluationTest() {
+ // check that addition is working
+ assertTrue("Node did not return expected value (sum of arguments). Output was: " + ((int) node.getValue()),
+ ((int) node.getValue()) == arg1 + arg2);
+
+ // put in a different function, check the output has changed appropriately
+ node.setFunction(new Arithmetic.Subtraction());
+
+ assertTrue("Node did not return expected value (difference of arguments).", ((Integer) node.getValue()) == arg1 - arg2);
+
+ }
+
+ @Test
+ public void connectionsTest() {
+ // make new blank connections, check that they are returned correctly when addressed
+ Connection conn0, conn1, conn2;
+ conn0 = new Connection() {
+
+ @Override
+ public Object getValue() {
+ // blank
+ return 0;
+ }
+
+ @Override
+ public String getDescription() {
+ // blank
+ return null;
+ }
+
+ };
+ conn1 = new Connection() {
+
+ @Override
+ public Object getValue() {
+ // blank
+ return 0;
+ }
+
+ @Override
+ public String getDescription() {
+ // blank
+ return null;
+ }
+
+ };
+ node.initialise(null, conn0, conn1);
+
+ assertTrue("Connection 0 is incorrect.", node.getConnection(0) == conn0);
+ assertTrue("Connection 1 is incorrect.", node.getConnection(1) == conn1);
+
+ // make yet another connection, set it randomly, check that it is one of the node's connections
+ conn2 = new Connection() {
+
+ @Override
+ public Object getValue() {
+ // blank
+ return 0;
+ }
+
+ @Override
+ public String getDescription() {
+ // blank
+ return null;
+ }
+ };
+ node.setConnection(resources.getRandomInt(resources.getInt("arity")), conn2);
+
+ assertTrue("Connection was not found in node.", node.getConnection(0) == conn2 || node.getConnection(1) == conn2);
+
+ }
+
+
+}
diff --git a/src/jcgp/backend/tests/OutputTests.java b/src/jcgp/backend/tests/OutputTests.java
new file mode 100644
index 0000000..7ff8a4a
--- /dev/null
+++ b/src/jcgp/backend/tests/OutputTests.java
@@ -0,0 +1,93 @@
+package jcgp.backend.tests;
+
+import static org.junit.Assert.assertTrue;
+import jcgp.JCGP.Resources;
+import jcgp.backend.population.Chromosome;
+import jcgp.backend.population.Connection;
+import jcgp.backend.population.Output;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ *
+ * Tests which cover the behaviour specified for an output.
+ *
+ * - An output contains a single source Connection, which can be set and got.
+ * - It should return the value of its source connection.
+ * - It must be addressable by an index set upon construction only.
+ *
+ *
+ * @author Eduardo Pedroni
+ *
+ */
+public class OutputTests {
+
+ private Output output;
+ private static Chromosome chromosome;
+ private static Resources resources;
+ // these are the test values
+ private final int outputValue = 10;
+ private final int outputIndex = 2;
+
+ @BeforeClass
+ public static void setUpBeforeClass() {
+ resources = new Resources();
+ chromosome = new Chromosome(resources);
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ output = new Output(chromosome, outputIndex);
+ }
+
+ @Test
+ public void evaluationsTest() {
+ // set source connection, check that the appropriate value is returned
+ output.setConnection(0, new Connection() {
+
+ @Override
+ public Object getValue() {
+ // test value
+ return outputValue;
+ }
+
+ @Override
+ public String getDescription() {
+ // blank
+ return null;
+ }
+ });
+
+ assertTrue("Incorrect evaluation.", ((Integer) output.calculate()) == outputValue);
+ }
+
+ @Test
+ public void connectionTest() {
+ // set a new connection, check that it is correctly returned
+ Connection newConn = new Connection() {
+
+ @Override
+ public Object getValue() {
+ // blank
+ return 0;
+ }
+
+ @Override
+ public String getDescription() {
+ // blank
+ return null;
+ }
+ };
+ output.setConnection(0, newConn);
+
+ assertTrue("Incorrect connection returned.", output.getSource() == newConn);
+ }
+
+ @Test
+ public void indexTest() {
+ // check that the index returned is the one passed to the constructor
+ assertTrue("Incorrect index returned.", output.getIndex() == outputIndex);
+ }
+}
diff --git a/src/jcgp/backend/tests/PopulationTests.java b/src/jcgp/backend/tests/PopulationTests.java
new file mode 100644
index 0000000..51b5168
--- /dev/null
+++ b/src/jcgp/backend/tests/PopulationTests.java
@@ -0,0 +1,86 @@
+package jcgp.backend.tests;
+
+import static org.junit.Assert.assertTrue;
+import jcgp.JCGP.Resources;
+import jcgp.backend.population.Chromosome;
+import jcgp.backend.population.Population;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ *
+ * Tests which cover the behaviour specified for a population.
+ *
+ * - It should be possible to iterate through all the chromosomes in a population.
+ * - When constructed with no arguments, it should generate populationSize
+ * random chromosomes, distributed according to the EA parameters.
+ * - If one or more chromosomes are passed into the constructor, it should use them
+ * as parents to create the rest of the population.
+ *
+ *
+ * @author Eduardo Pedroni
+ *
+ */
+public class PopulationTests {
+
+ private Population population;
+ private static Resources resources;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ resources = new Resources();
+
+
+// // initialise function set
+// FunctionSet functionSet = new FunctionSet(new Arithmetic.Addition(), new Arithmetic.Subtraction());
+//
+// // initialise utilities
+// Utilities.setResources(new Random(1234), functionSet);
+//
+// // initialise parameters
+// Resources.setColumns(20);
+// Resources.setRows(20);
+// Resources.setInputs(2);
+// Resources.setOutputs(4);
+// Resources.setLevelsBack(1);
+// Resources.setMutationRate(10);
+// Resources.setTotalGenerations(100);
+// Resources.setTotalRuns(5);
+// Resources.setPopulationSize(1, 4);
+// Resources.setMaxArity(functionSet.getMaxArity());
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ population = new Population(resources);
+ }
+
+ @Test
+ public void defaultPopulationTest() {
+ // check that the constructor really generates populationSize chromosomes when none is given
+ int chromosomes = 0;
+ while (true) {
+ try {
+ population.getChromosome(chromosomes);
+ } catch (IndexOutOfBoundsException e) {
+ break;
+ }
+ chromosomes++;
+ }
+
+ assertTrue("Incorrect number of chromosomes generated.", chromosomes == resources.getInt("popSize"));
+ }
+
+ @Test
+ public void preinitialisedChromosomeTest() {
+ // the original chromosome that will be cloned
+ Chromosome oc = new Chromosome(resources);
+
+ // initialise a population with a copy of it
+ population = new Population(oc, resources);
+ // check that the first parent chromosome is identical to, but not the same instance as, the one given
+ assertTrue("Incorrect chromosome in population.", population.getChromosome(0).compareTo(oc) && population.getChromosome(0) != oc);
+ }
+}