aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README7
-rw-r--r--src/jcgp/population/Population.java23
-rw-r--r--src/jcgp/tests/ChromosomeTests.java55
-rw-r--r--src/jcgp/tests/PopulationTests.java106
4 files changed, 161 insertions, 30 deletions
diff --git a/README b/README
index f08fe1b..bf92331 100644
--- a/README
+++ b/README
@@ -114,5 +114,12 @@ Node tests done. Added exception support for Function in case not enough argumen
Chromosome tests refactored to include the special case where columns = 1.
Input and output tests written.
+Population tests under way.
+
+
+13/2
+
+Writing the test for the population copy constructor will require the production of a method which compares two chromosomes.
+It might be useful to incorporate this into the program as it is an interesting utility function.
diff --git a/src/jcgp/population/Population.java b/src/jcgp/population/Population.java
index 56f1b50..4153e0f 100644
--- a/src/jcgp/population/Population.java
+++ b/src/jcgp/population/Population.java
@@ -8,14 +8,17 @@ public class Population implements Iterable<Chromosome> {
private Chromosome[] population;
- public Population(Chromosome ... chromosomes) {
- if (chromosomes.length > 0) {
- population = chromosomes;
- } else {
- population = new Chromosome[Parameters.getPopulationSize()];
- for (int c = 0; c < population.length; c++) {
- population[c] = new Chromosome();
- }
+ public Population(Chromosome chromosome) {
+ population = new Chromosome[Parameters.getPopulationSize()];
+ for (int c = 0; c < population.length; c++) {
+ population[c] = new Chromosome(chromosome);
+ }
+ }
+
+ public Population() {
+ population = new Chromosome[Parameters.getPopulationSize()];
+ for (int c = 0; c < population.length; c++) {
+ population[c] = new Chromosome();
}
}
@@ -44,10 +47,8 @@ public class Population implements Iterable<Chromosome> {
@Override
public void remove() {
// not allowed
- // since this would shift everything back one position, increment index
- // index++;
+ throw new UnsupportedOperationException("Removing chromosomes from the population is not allowed. Instead, re-instantiate the chromosome.");
}
-
};
}
}
diff --git a/src/jcgp/tests/ChromosomeTests.java b/src/jcgp/tests/ChromosomeTests.java
index cb2cb95..ff1de18 100644
--- a/src/jcgp/tests/ChromosomeTests.java
+++ b/src/jcgp/tests/ChromosomeTests.java
@@ -57,7 +57,7 @@ public class ChromosomeTests {
Utilities.setResources(new Random(1234), functionSet);
// initialise parameters
- Parameters.setColumns(1);
+ Parameters.setColumns(30);
Parameters.setRows(20);
Parameters.setInputs(2);
Parameters.setOutputs(4);
@@ -90,13 +90,54 @@ public class ChromosomeTests {
chromosome.setInputs(testInputs);
clone.setInputs(testInputs);
- // connect outputs to inputs, check that the outputs match
- for (int i = 0; i < Parameters.getOutputs(); i++) {
- chromosome.getOutput(i).setConnection(chromosome.getInput(i % Parameters.getInputs()));
- clone.getOutput(i).setConnection(clone.getInput(i % Parameters.getInputs()));
- assertTrue("Incorrect output returned.", chromosome.getOutput(i).calculate() ==
- clone.getOutput(i).calculate());
+ // compare all elements, one by one
+ // check outputs
+ for (int o = 0; o < Parameters.getOutputs(); o++) {
+ // check that no cross-references exist between chromosomes
+ assertTrue("Cloned chromosome contained a reference to a member of the original chromosome.",
+ c.getOutput(o) != oc.getOutput(o) &&
+ c.getOutput(o).getSource() != oc.getOutput(o).getSource());
+ // check that the connections are equivalent
+ if (c.getOutput(o).getSource() instanceof Input && oc.getOutput(o).getSource() instanceof Input) {
+ assertTrue("Outputs did not connect to equivalent inputs.",
+ ((Input) c.getOutput(o).getSource()).getIndex() == ((Input) oc.getOutput(o).getSource()).getIndex());
+ } else if (c.getOutput(o).getSource() instanceof Node && oc.getOutput(o).getSource() instanceof Node) {
+ assertTrue("Outputs did not connect to equivalent nodes.",
+ ((Node) c.getOutput(o).getSource()).getRow() == ((Node) oc.getOutput(o).getSource()).getRow() &&
+ ((Node) c.getOutput(o).getSource()).getColumn() == ((Node) oc.getOutput(o).getSource()).getColumn());
+ } else {
+ fail("Output source types did not match.");
+ }
}
+ // check nodes, rows first
+ for (int row = 0; row < Parameters.getRows(); row++) {
+ for (int column = 0; column < Parameters.getColumns(); column++) {
+ // look at each connection
+ for (int connection = 0; connection < Parameters.getMaxArity(); connection++) {
+ if (c.getNode(row, column).getConnection(connection) instanceof Input &&
+ oc.getNode(row, column).getConnection(connection) instanceof Input) {
+
+ assertTrue("Nodes did not connect to equivalent inputs.",
+ ((Input) c.getNode(row, column).getConnection(connection)).getIndex() ==
+ ((Input) oc.getNode(row, column).getConnection(connection)).getIndex());
+
+ } else if (c.getNode(row, column).getConnection(connection) instanceof Node &&
+ oc.getNode(row, column).getConnection(connection) instanceof Node) {
+
+ assertTrue("Nodes did not connect to equivalent nodes.",
+ ((Node) c.getNode(row, column).getConnection(connection)).getRow() ==
+ ((Node) oc.getNode(row, column).getConnection(connection)).getRow() &&
+
+ ((Node) c.getNode(row, column).getConnection(connection)).getColumn() ==
+ ((Node) oc.getNode(row, column).getConnection(connection)).getColumn());
+
+ } else {
+ fail("Connection types did not match.");
+ }
+ }
+ }
+ }
+
// change clone inputs, outputs should no longer match
testInputs = new int[Parameters.getInputs()];
diff --git a/src/jcgp/tests/PopulationTests.java b/src/jcgp/tests/PopulationTests.java
index 16a8d89..a8f55a2 100644
--- a/src/jcgp/tests/PopulationTests.java
+++ b/src/jcgp/tests/PopulationTests.java
@@ -2,6 +2,7 @@ package jcgp.tests;
import static org.junit.Assert.*;
+import java.util.Iterator;
import java.util.Random;
import jcgp.Parameters;
@@ -10,6 +11,8 @@ import jcgp.function.Addition;
import jcgp.function.FunctionSet;
import jcgp.function.Subtraction;
import jcgp.population.Chromosome;
+import jcgp.population.Input;
+import jcgp.population.Node;
import jcgp.population.Population;
import org.junit.Before;
@@ -21,19 +24,20 @@ import org.junit.Test;
* Tests which cover the behaviour specified for a population.
*
* - A population is a collection of chromosomes. It should be Iterable
- * so the chromosomes can be accessed. Chromosomes should never be removed
- * via the iterator.
+ * so the chromosomes can be accessed.
+ * - Iterator.remove() should generate an UnsupportedOperationException
+ * since chromosomes may not be removed.
* - When constructed with no arguments, it should generate populationSize
* random chromosomes.
- * - If an array of chromosomes is passed as an argument to the constructor,
- * it should use those chromosomes as the population.
+ * - If a chromosome is passed as an argument to the constructor, it should
+ * create a population of copies of that chromosome.
*
*
* @author Eduardo Pedroni
*
*/
public class PopulationTests {
-
+
private Population population;
@BeforeClass
@@ -66,29 +70,107 @@ public class PopulationTests {
public void iterableTest() {
// check that Population is really Iterable
assertTrue("Population must implement Iterable.", population instanceof Iterable);
-
+
// iterate through, check that different chromosomes are returned and no chromosome can be removed
Chromosome comparison = null;
int iterationCount = 0;
+ boolean exceptionThrown = false;
+
for (Chromosome chromosome : population) {
iterationCount++;
assertTrue("Same chromosome returned twice.", comparison != chromosome);
comparison = chromosome;
- population.iterator().remove();
- assertTrue("Chromosome removed.", comparison == chromosome);
+
+ try {
+ population.iterator().remove();
+ } catch (UnsupportedOperationException e) {
+ exceptionThrown = true;
+ }
+ assertTrue("Chromosome removed.", exceptionThrown);
+ exceptionThrown = false;
}
// check that all chromosomes were iterated through
- assertTrue("Not enough itearations occurred.", iterationCount == Parameters.getPopulationSize());
+ assertTrue("Number of elements in population does not match specified parameter size.",
+ iterationCount == Parameters.getPopulationSize());
}
-
+
@Test
- public void contentsTest() {
+ public void defaultPopulationTest() {
// check that the constructor really generates populationSize chromosomes when none is given
int populationCount = 0;
- for (Chromosome chromosome : population) {
+ for (Iterator<Chromosome> iterator = population.iterator(); iterator.hasNext();) {
populationCount++;
+ iterator.next();
}
assertTrue("Incorrect number of chromosomes generated.", populationCount == Parameters.getPopulationSize());
}
+ @Test
+ public void preinitialisedChromosomeTest() {
+ // the original chromosome that will be cloned
+ Chromosome oc = new Chromosome();
+
+ // initialise a population with copies of it
+ population = new Population(oc);
+ // check that the chromosomes returned are identical to the one given
+ int index = 0;
+ for (Chromosome c : population) {
+ assertTrue("Incorrect chromosome in population.", c != oc);
+ index++;
+ }
+ // check that the right number of copies was made
+ assertTrue("Wrong number of chromosomes in population.", index == Parameters.getPopulationSize());
+
+ // check that the copies are exact copies
+ for (Chromosome c : population) {
+ // check outputs
+ for (int o = 0; o < Parameters.getOutputs(); o++) {
+ // check that no cross-references exist between chromosomes
+ assertTrue("Cloned chromosome contained a reference to a member of the original chromosome.",
+ c.getOutput(o) != oc.getOutput(o) &&
+ c.getOutput(o).getSource() != oc.getOutput(o).getSource());
+ // check that the connections are equivalent
+ if (c.getOutput(o).getSource() instanceof Input && oc.getOutput(o).getSource() instanceof Input) {
+ assertTrue("Outputs did not connect to equivalent inputs.",
+ ((Input) c.getOutput(o).getSource()).getIndex() == ((Input) oc.getOutput(o).getSource()).getIndex());
+ } else if (c.getOutput(o).getSource() instanceof Node && oc.getOutput(o).getSource() instanceof Node) {
+ assertTrue("Outputs did not connect to equivalent nodes.",
+ ((Node) c.getOutput(o).getSource()).getRow() == ((Node) oc.getOutput(o).getSource()).getRow() &&
+ ((Node) c.getOutput(o).getSource()).getColumn() == ((Node) oc.getOutput(o).getSource()).getColumn());
+ } else {
+ fail("Output source types did not match.");
+ }
+ }
+ // check nodes, rows first
+ for (int row = 0; row < Parameters.getRows(); row++) {
+ for (int column = 0; column < Parameters.getColumns(); column++) {
+ // look at each connection
+ for (int connection = 0; connection < Parameters.getMaxArity(); connection++) {
+ if (c.getNode(row, column).getConnection(connection) instanceof Input &&
+ oc.getNode(row, column).getConnection(connection) instanceof Input) {
+
+ assertTrue("Nodes did not connect to equivalent inputs.",
+ ((Input) c.getNode(row, column).getConnection(connection)).getIndex() ==
+ ((Input) oc.getNode(row, column).getConnection(connection)).getIndex());
+
+ } else if (c.getNode(row, column).getConnection(connection) instanceof Node &&
+ oc.getNode(row, column).getConnection(connection) instanceof Node) {
+
+ assertTrue("Nodes did not connect to equivalent nodes.",
+ ((Node) c.getNode(row, column).getConnection(connection)).getRow() ==
+ ((Node) oc.getNode(row, column).getConnection(connection)).getRow() &&
+
+ ((Node) c.getNode(row, column).getConnection(connection)).getColumn() ==
+ ((Node) oc.getNode(row, column).getConnection(connection)).getColumn());
+
+ } else {
+ fail("Connection types did not match.");
+ }
+ }
+ }
+ }
+ }
+
+ }
+
}