aboutsummaryrefslogtreecommitdiffstats
path: root/src/jcgp/population
diff options
context:
space:
mode:
authorEduardo Pedroni <ep625@york.ac.uk>2014-03-23 18:05:13 +0000
committerEduardo Pedroni <ep625@york.ac.uk>2014-03-23 18:05:13 +0000
commit0c288cc1952809294c8d70d86b9f41b04878ac2e (patch)
treeef9671b711fe665a3156594663c083595861a4e6 /src/jcgp/population
parentd3527a63e12c0e5288f1e7d2e2dc18e61d16b760 (diff)
Majorly refactored, node grid is fully implemented. About to attempt active path locking.
Diffstat (limited to 'src/jcgp/population')
-rw-r--r--src/jcgp/population/Chromosome.java85
-rw-r--r--src/jcgp/population/Gene.java5
-rw-r--r--src/jcgp/population/Input.java2
-rw-r--r--src/jcgp/population/MutableElement.java15
-rw-r--r--src/jcgp/population/Node.java75
-rw-r--r--src/jcgp/population/Output.java31
-rw-r--r--src/jcgp/population/Population.java27
7 files changed, 146 insertions, 94 deletions
diff --git a/src/jcgp/population/Chromosome.java b/src/jcgp/population/Chromosome.java
index 1f0b312..a7f2ed3 100644
--- a/src/jcgp/population/Chromosome.java
+++ b/src/jcgp/population/Chromosome.java
@@ -2,11 +2,12 @@ package jcgp.population;
import java.util.ArrayList;
-import jcgp.Utilities;
+import jcgp.CGP.Resources;
import jcgp.exceptions.ParameterMismatchException;
-import jcgp.parameters.Parameters;
public class Chromosome {
+
+ private Resources resources;
private Input[] inputs;
private Node[][] nodes;
@@ -21,13 +22,12 @@ public class Chromosome {
* Initialise a chromosome with the specified parameters. Random valid connections
* are created.
*
- * @param outputs
- * @param columns
- * @param rows
- * @param inputs
*
*/
- public Chromosome() {
+ public Chromosome(Resources resources) {
+ // store a reference to the parameters
+ this.resources = resources;
+
// allocate memory for all elements of the chromosome
instantiateElements();
// set random connections so that the chromosome can be evaluated
@@ -42,6 +42,9 @@ public class Chromosome {
* @param clone the chromosome to be copied
*/
public Chromosome(Chromosome clone) {
+ // store a reference to the parameters
+ this.resources = clone.getParameters();
+
// allocate memory for all elements of the chromosome
instantiateElements();
// initialise all connections based on argument
@@ -52,20 +55,22 @@ public class Chromosome {
*
*/
private void instantiateElements() {
- inputs = new Input[((int) Parameters.get("inputs").getValue())];
- for (int i = 0; i < ((int) Parameters.get("inputs").getValue()); i++) {
+ inputs = new Input[((int) resources.get("inputs"))];
+ for (int i = 0; i < ((int) resources.get("inputs")); i++) {
inputs[i] = new Input(i);
}
+ int arity = (int) resources.get("arity");
+
// rows first
- nodes = new Node[((int) Parameters.get("rows").getValue())][((int) Parameters.get("columns").getValue())];
- for (int r = 0; r < ((int) Parameters.get("rows").getValue()); r++) {
- for (int c = 0; c < ((int) Parameters.get("columns").getValue()); c++) {
- nodes[r][c] = new Node(this, r, c);
+ nodes = new Node[((int) resources.get("rows"))][((int) resources.get("columns"))];
+ for (int r = 0; r < ((int) resources.get("rows")); r++) {
+ for (int c = 0; c < ((int) resources.get("columns")); c++) {
+ nodes[r][c] = new Node(this, r, c, arity);
}
}
- outputs = new Output[((int) Parameters.get("outputs").getValue())];
- for (int o = 0; o < ((int) Parameters.get("outputs").getValue()); o++) {
+ outputs = new Output[((int) resources.get("outputs"))];
+ for (int o = 0; o < ((int) resources.get("outputs")); o++) {
outputs[o] = new Output(this, o);
}
}
@@ -75,19 +80,21 @@ public class Chromosome {
*/
private void initialiseConnections() {
+ int arity = (int) resources.get("arity");
+
// initialise nodes - [rows][columns]
for (int r = 0; r < nodes.length; r++) {
for (int c = 0; c < nodes[r].length; c++) {
- Connection[] connections = new Connection[((int) Parameters.get("maxArity").getValue())];
+ Connection[] connections = new Connection[arity];
for (int i = 0; i < connections.length; i++) {
connections[i] = getRandomConnection(c);
}
- nodes[r][c].initialise(Utilities.getRandomFunction(), connections);
+ nodes[r][c].initialise(resources.getRandomFunction(), connections);
}
}
for (Output output : outputs) {
- output.setConnection(getRandomConnection());
+ output.setConnection(0, getRandomConnection());
}
}
@@ -96,11 +103,13 @@ public class Chromosome {
* @param clone
*/
public void copyConnections(Chromosome clone) {
+ int arity = (int) resources.get("arity");
+
// copy nodes - [rows][columns]
for (int r = 0; r < nodes.length; r++) {
for (int c = 0; c < nodes[r].length; c++) {
// make array of connections to initialise with
- Connection[] connections = new Connection[((int) Parameters.get("maxArity").getValue())];
+ Connection[] connections = new Connection[arity];
// populate with connections equivalent to clone
Connection copyConnection;
for (int i = 0; i < connections.length; i++) {
@@ -123,9 +132,9 @@ public class Chromosome {
for (int o = 0; o < outputs.length; o++) {
copyOutput = clone.getOutput(o).getSource();
if (copyOutput instanceof Input) {
- outputs[o].setConnection(inputs[((Input) copyOutput).getIndex()]);
+ outputs[o].setConnection(0, inputs[((Input) copyOutput).getIndex()]);
} else if (copyOutput instanceof Node) {
- outputs[o].setConnection(nodes[((Node) copyOutput).getRow()][((Node) copyOutput).getColumn()]);
+ outputs[o].setConnection(0, nodes[((Node) copyOutput).getRow()][((Node) copyOutput).getColumn()]);
} else {
// something bad happened
System.out.println("Warning: Connection of subtype " + copyOutput.getClass().toString() + " is not explicitly handled by copy constructor.");
@@ -177,7 +186,7 @@ public class Chromosome {
*/
public MutableElement getRandomMutableElement() {
// choose output or node
- int index = Utilities.getRandomInt(outputs.length + ((int) Parameters.get("rows").getValue()) * ((int) Parameters.get("columns").getValue()));
+ int index = resources.getRandomInt(outputs.length + ((int) resources.get("rows")) * ((int) resources.get("columns")));
if (index < outputs.length) {
// outputs
@@ -185,7 +194,7 @@ public class Chromosome {
} else {
// node
index -= outputs.length;
- return nodes[index / ((int) Parameters.get("columns").getValue())][index % ((int) Parameters.get("columns").getValue())];
+ return nodes[index / ((int) resources.get("columns"))][index % ((int) resources.get("columns"))];
}
}
@@ -199,11 +208,11 @@ public class Chromosome {
*/
public Connection getRandomConnection(int column) {
// work out the allowed range obeying levels back
- int allowedColumns = ((column >= ((int) Parameters.get("levelsBack").getValue())) ? ((int) Parameters.get("levelsBack").getValue()) : column);
+ int allowedColumns = ((column >= ((int) resources.get("levelsBack"))) ? ((int) resources.get("levelsBack")) : column);
int offset = ((column - allowedColumns) * nodes.length) - inputs.length;
// choose input or allowed node
- int index = Utilities.getRandomInt(inputs.length + (nodes.length * allowedColumns));
+ int index = resources.getRandomInt(inputs.length + (nodes.length * allowedColumns));
if (index < inputs.length) {
// input
return inputs[index];
@@ -226,7 +235,7 @@ public class Chromosome {
*/
public Connection getRandomConnection() {
// choose output or node
- int index = Utilities.getRandomInt(inputs.length + ((int) Parameters.get("columns").getValue()) * ((int) Parameters.get("rows").getValue()));
+ int index = resources.getRandomInt(inputs.length + ((int) resources.get("columns")) * ((int) resources.get("rows")));
if (index < inputs.length) {
// outputs
@@ -234,7 +243,7 @@ public class Chromosome {
} else {
// node
index -= inputs.length;
- return nodes[index / ((int) Parameters.get("columns").getValue())][index % ((int) Parameters.get("columns").getValue())];
+ return nodes[index / ((int) resources.get("columns"))][index % ((int) resources.get("columns"))];
}
}
@@ -269,15 +278,15 @@ public class Chromosome {
}
public boolean compareTo(Chromosome chromosome) {
- for (int r = 0; r < ((int) Parameters.get("rows").getValue()); r++) {
- for (int c = 0; c < ((int) Parameters.get("columns").getValue()); c++) {
+ for (int r = 0; r < ((int) resources.get("rows")); r++) {
+ for (int c = 0; c < ((int) resources.get("columns")); c++) {
if (!(nodes[r][c].copyOf(chromosome.getNode(r, c)))) {
return false;
}
}
}
- for (int o = 0; o < ((int) Parameters.get("outputs").getValue()); o++) {
+ for (int o = 0; o < ((int) resources.get("outputs")); o++) {
if (!(outputs[o].copyOf(chromosome.getOutput(o)))) {
return false;
}
@@ -302,20 +311,26 @@ public class Chromosome {
}
public void printNodes() {
- for (int r = 0; r < ((int) Parameters.get("rows").getValue()); r++) {
+ int arity = (int) resources.get("arity");
+
+ for (int r = 0; r < ((int) resources.get("rows")); r++) {
System.out.print("r: " + r + "\t");
- for (int c = 0; c < ((int) Parameters.get("columns").getValue()); c++) {
+ for (int c = 0; c < ((int) resources.get("columns")); c++) {
System.out.print("N: (" + r + ", " + c + ") ");
- for (int i = 0; i < ((int) Parameters.get("maxArity").getValue()); i++) {
+ for (int i = 0; i < arity; i++) {
System.out.print("C" + i + ": (" + nodes[r][c].getConnection(i).getDescription() + ") ");
}
- System.out.print("F: " + nodes[r][c].getFunction().toString() + "\t");
+ System.out.print("F: " + nodes[r][c].getFunction().getName() + "\t");
}
System.out.print("\n");
}
- for (int o = 0; o < ((int) Parameters.get("outputs").getValue()); o++) {
+ for (int o = 0; o < ((int) resources.get("outputs")); o++) {
System.out.print("o: " + o + " (" + outputs[o].getSource().getDescription() + ")\t");
}
}
+
+ public Resources getParameters() {
+ return resources;
+ }
}
diff --git a/src/jcgp/population/Gene.java b/src/jcgp/population/Gene.java
new file mode 100644
index 0000000..8865a01
--- /dev/null
+++ b/src/jcgp/population/Gene.java
@@ -0,0 +1,5 @@
+package jcgp.population;
+
+public abstract class Gene {
+
+}
diff --git a/src/jcgp/population/Input.java b/src/jcgp/population/Input.java
index 5c545d6..cfcb3ce 100644
--- a/src/jcgp/population/Input.java
+++ b/src/jcgp/population/Input.java
@@ -1,6 +1,6 @@
package jcgp.population;
-public class Input implements Connection {
+public class Input extends Gene implements Connection {
private Object value = 0;
private int index;
diff --git a/src/jcgp/population/MutableElement.java b/src/jcgp/population/MutableElement.java
index 114a4ab..12f6bd1 100644
--- a/src/jcgp/population/MutableElement.java
+++ b/src/jcgp/population/MutableElement.java
@@ -2,8 +2,16 @@ package jcgp.population;
public interface MutableElement {
- public void setConnection(Connection newConnection);
-
+ /**
+ * This method sets the indexed connection to the specified new connection.
+ * Implementing classes may choose to ignore the given index (such as in the
+ * case of outputs, which only have one connection).
+ *
+ * @param index
+ * @param newConnection
+ */
+ public void setConnection(int index, Connection newConnection);
+
/**
* This method returns true if and only if:</br>
* - the elements being compared are not the same instance;</br>
@@ -15,7 +23,8 @@ public interface MutableElement {
* The relationship computed by this method is:</br>
* - symmetric: a.copyOf(b) == b.copyOf(a);</br>
* - not reflexive: a.copyOf(a) returns false;</br>
- * - not transitive: if a.copyOf(b) is true and b.copyOf(c) is true, a.copyOf(c) is not necessarily true;</br>
+ * - not transitive: if a.copyOf(b) is true and b.copyOf(c) is true, a.copyOf(c) is
+ * not necessarily true since it is possible that a == c.</br>
*
* @param m
* @return
diff --git a/src/jcgp/population/Node.java b/src/jcgp/population/Node.java
index 9fafe32..d7013d3 100644
--- a/src/jcgp/population/Node.java
+++ b/src/jcgp/population/Node.java
@@ -1,51 +1,58 @@
package jcgp.population;
import java.util.ArrayList;
-import java.util.Arrays;
-import jcgp.Utilities;
+import javafx.beans.property.SimpleObjectProperty;
import jcgp.exceptions.InsufficientConnectionsException;
-import jcgp.modules.function.Function;
-import jcgp.parameters.Parameters;
+import jcgp.function.Function;
-public class Node implements MutableElement, Connection {
+public class Node extends Gene implements MutableElement, Connection {
- private Function function;
- private Connection[] connections;
+ private SimpleObjectProperty<Function> function;
+ private ArrayList<SimpleObjectProperty<Connection>> connections;
private int column, row;
private Chromosome chromosome;
- public Node(Chromosome chromosome, int row, int column) {
+ public Node(Chromosome chromosome, int row, int column, int arity) {
+ this.function = new SimpleObjectProperty<Function>();
this.chromosome = chromosome;
this.column = column;
this.row = row;
- this.connections = new Connection[((int) Parameters.get("maxArity").getValue())];
+ this.connections = new ArrayList<SimpleObjectProperty<Connection>>(arity);
+ for (int c = 0; c < arity; c++) {
+ connections.add(new SimpleObjectProperty<Connection>());
+ }
}
@Override
public Object getValue() {
//System.out.print("Calculating node: (" + row + ", " + column + ") > ");
- return function.run(Arrays.copyOfRange(connections, 0, function.getArity()));
+ Connection[] list = new Connection[function.get().getArity()];
+ for (int i = 0; i < list.length; i++) {
+ list[i] = connections.get(i).get();
+ }
+
+ return function.get().run(list);
}
public void setFunction(Function newFunction) {
- function = newFunction;
+ function.set(newFunction);
chromosome.recomputeActiveNodes();
}
@Override
- public void setConnection(Connection newConnection) {
- connections[Utilities.getRandomInt(connections.length)] = newConnection;
+ public void setConnection(int index, Connection newConnection) {
+ connections.get(index).set(newConnection);
chromosome.recomputeActiveNodes();
}
public void initialise(Function newFunction, Connection ... newConnections) throws InsufficientConnectionsException {
-
- function = newFunction;
-
- if (newConnections.length >= ((int) Parameters.get("maxArity").getValue())) {
- connections = newConnections;
+ function.set(newFunction);
+ if (newConnections.length >= connections.size()) {
+ for (int i = 0; i < connections.size(); i++) {
+ connections.get(i).set(newConnections[i]);
+ }
} else {
throw new InsufficientConnectionsException();
}
@@ -60,20 +67,28 @@ public class Node implements MutableElement, Connection {
}
public Function getFunction() {
+ return function.get();
+ }
+
+ public SimpleObjectProperty<Function> functionProperty() {
return function;
}
+ public ArrayList<SimpleObjectProperty<Connection>> connections() {
+ return connections;
+ }
+
public Connection getConnection(int index) {
- return connections[index];
+ return connections.get(index).get();
}
public void getActive(ArrayList<Node> activeNodes) {
if (!activeNodes.contains(this)) {
activeNodes.add(this);
}
- for (int i = 0; i < function.getArity(); i++) {
- if (connections[i] instanceof Node) {
- ((Node) connections[i]).getActive(activeNodes);
+ for (int i = 0; i < function.get().getArity(); i++) {
+ if (connections.get(i).get() instanceof Node) {
+ ((Node) connections.get(i).get()).getActive(activeNodes);
}
}
@@ -84,17 +99,17 @@ public class Node implements MutableElement, Connection {
if (this != m) {
if (m instanceof Node) {
Node n = (Node) m;
- if (function == n.getFunction()) {
+ if (function.get() == n.getFunction()) {
if (column == n.getColumn() && row == n.getRow()) {
- for (int i = 0; i < connections.length; i++) {
- if (connections[i] != n.getConnection(i)) {
- if (connections[i] instanceof Input && n.getConnection(i) instanceof Input) {
- if (((Input) connections[i]).getIndex() != ((Input) n.getConnection(i)).getIndex()) {
+ for (int i = 0; i < connections.size(); i++) {
+ if (connections.get(i).get() != n.getConnection(i)) {
+ if (connections.get(i).get() instanceof Input && n.getConnection(i) instanceof Input) {
+ if (((Input) connections.get(i).get()).getIndex() != ((Input) n.getConnection(i)).getIndex()) {
return false;
}
- } else if (connections[i] instanceof Node && n.getConnection(i) instanceof Node) {
- if (((Node) connections[i]).getRow() != ((Node) n.getConnection(i)).getRow() &&
- ((Node) connections[i]).getColumn() != ((Node) n.getConnection(i)).getColumn()) {
+ } else if (connections.get(i).get() instanceof Node && n.getConnection(i) instanceof Node) {
+ if (((Node) connections.get(i).get()).getRow() != ((Node) n.getConnection(i)).getRow() &&
+ ((Node) connections.get(i).get()).getColumn() != ((Node) n.getConnection(i)).getColumn()) {
return false;
}
} else {
diff --git a/src/jcgp/population/Output.java b/src/jcgp/population/Output.java
index ccecae0..b7c6128 100644
--- a/src/jcgp/population/Output.java
+++ b/src/jcgp/population/Output.java
@@ -2,15 +2,18 @@ package jcgp.population;
import java.util.ArrayList;
-public class Output implements MutableElement {
+import javafx.beans.property.SimpleObjectProperty;
+
+public class Output extends Gene implements MutableElement {
- private Connection source;
+ private SimpleObjectProperty<Connection> source;
private Chromosome chromosome;
private int index;
public Output(Chromosome chromosome, int index) {
this.chromosome = chromosome;
this.index = index;
+ this.source = new SimpleObjectProperty<Connection>();
}
public Object calculate() {
@@ -19,8 +22,8 @@ public class Output implements MutableElement {
}
@Override
- public void setConnection(Connection newConnection) {
- source = newConnection;
+ public void setConnection(int index, Connection newConnection) {
+ source.set(newConnection);
chromosome.recomputeActiveNodes();
}
@@ -29,12 +32,16 @@ public class Output implements MutableElement {
}
public Connection getSource() {
+ return source.get();
+ }
+
+ public SimpleObjectProperty<Connection> sourceProperty() {
return source;
}
public void getActiveNodes(ArrayList<Node> activeNodes) {
- if (source instanceof Node) {
- ((Node) source).getActive(activeNodes);
+ if (source.get() instanceof Node) {
+ ((Node) source.get()).getActive(activeNodes);
}
}
@@ -44,14 +51,14 @@ public class Output implements MutableElement {
if (m instanceof Output) {
Output o = (Output) m;
if (index == o.getIndex()) {
- if (source != o.getSource()) {
- if (source instanceof Input && o.getSource() instanceof Input) {
- if (((Input) source).getIndex() == ((Input) o.getSource()).getIndex()) {
+ if (source.get() != o.getSource()) {
+ if (source.get() instanceof Input && o.getSource() instanceof Input) {
+ if (((Input) source.get()).getIndex() == ((Input) o.getSource()).getIndex()) {
return true;
}
- } else if (source instanceof Node && o.getSource() instanceof Node) {
- if (((Node) source).getRow() == ((Node) o.getSource()).getRow() &&
- ((Node) source).getColumn() == ((Node) o.getSource()).getColumn()) {
+ } else if (source.get() instanceof Node && o.getSource() instanceof Node) {
+ if (((Node) source.get()).getRow() == ((Node) o.getSource()).getRow() &&
+ ((Node) source.get()).getColumn() == ((Node) o.getSource()).getColumn()) {
return true;
}
}
diff --git a/src/jcgp/population/Population.java b/src/jcgp/population/Population.java
index 5718515..bc9c9e8 100644
--- a/src/jcgp/population/Population.java
+++ b/src/jcgp/population/Population.java
@@ -1,14 +1,22 @@
package jcgp.population;
-import jcgp.parameters.Parameters;
+import jcgp.CGP.Resources;
+
public class Population {
private Chromosome[] chromosomes;
- private Chromosome bestIndividual;
+ private int fittest;
+
+ public Population(Resources parameters) {
+ chromosomes = new Chromosome[((int) parameters.get("popSize"))];
+ for (int c = 0; c < chromosomes.length; c++) {
+ chromosomes[c] = new Chromosome(parameters);
+ }
+ }
- public Population(Chromosome parent) {
- chromosomes = new Chromosome[((int) Parameters.get("population").getValue())];
+ public Population(Chromosome parent, Resources parameters) {
+ chromosomes = new Chromosome[((int) parameters.get("popSize"))];
// make a clone for safety
this.chromosomes[0] = new Chromosome(parent);
// generate the rest of the individuals
@@ -16,13 +24,6 @@ public class Population {
chromosomes[c] = new Chromosome(chromosomes[0]);
}
}
-
- public Population() {
- chromosomes = new Chromosome[((int) Parameters.get("population").getValue())];
- for (int c = 0; c < chromosomes.length; c++) {
- chromosomes[c] = new Chromosome();
- }
- }
/**
* Returns all chromosomes, parents first, then offspring.
@@ -35,10 +36,10 @@ public class Population {
}
public void setBestIndividual(int index) {
- bestIndividual = chromosomes[index];
+ fittest = index;
}
public Chromosome getBestIndividual() {
- return bestIndividual;
+ return chromosomes[fittest];
}
}