aboutsummaryrefslogtreecommitdiffstats
path: root/src/jcgp/population
diff options
context:
space:
mode:
Diffstat (limited to 'src/jcgp/population')
-rw-r--r--src/jcgp/population/Chromosome.java63
-rw-r--r--src/jcgp/population/Connection.java4
-rw-r--r--src/jcgp/population/Input.java9
-rw-r--r--src/jcgp/population/MutableElement.java18
-rw-r--r--src/jcgp/population/Node.java60
-rw-r--r--src/jcgp/population/Output.java30
6 files changed, 146 insertions, 38 deletions
diff --git a/src/jcgp/population/Chromosome.java b/src/jcgp/population/Chromosome.java
index 08ff9b9..f61b780 100644
--- a/src/jcgp/population/Chromosome.java
+++ b/src/jcgp/population/Chromosome.java
@@ -11,8 +11,8 @@ public class Chromosome {
private Input[] inputs;
private Node[][] nodes;
private Output[] outputs;
-
- private ArrayList<Connection> activeNodes;
+
+ private ArrayList<Node> activeNodes;
private int fitness = 0;
private boolean recomputeActiveNodes = true;
@@ -117,7 +117,7 @@ public class Chromosome {
nodes[r][c].initialise(clone.getNode(r, c).getFunction(), connections);
}
}
-
+
// do the same to outputs
Connection copyOutput;
for (int o = 0; o < outputs.length; o++) {
@@ -153,6 +153,11 @@ public class Chromosome {
fitness = newFitness;
}
+ /**
+ *
+ * @param values
+ * @throws ParameterMismatchException
+ */
public void setInputs(int ... values) throws ParameterMismatchException {
// if the values provided don't match the specified number of inputs, the user should be warned
if (values.length == inputs.length) {
@@ -232,31 +237,67 @@ public class Chromosome {
return nodes[index / Parameters.getColumns()][index % Parameters.getColumns()];
}
}
-
+
/**
* This causes the list of active nodes to be recomputed lazily (once it is actually requested).
*/
public void recomputeActiveNodes() {
recomputeActiveNodes = true;
}
-
+
/**
- * This method computes a list of active nodes (if necessary) and returns it.
+ * This method computes a list of active connections (if necessary) and returns it.
*
* @return
*/
- public ArrayList<Connection> getActiveNodes() {
+ public ArrayList<Node> getActiveNodes() {
+ computeActiveNodes();
+ return activeNodes;
+ }
+
+ private void computeActiveNodes() {
// lazy recomputation has been triggered, do it
if (recomputeActiveNodes) {
recomputeActiveNodes = false;
- activeNodes = new ArrayList<Connection>();
-
+ activeNodes = new ArrayList<Node>();
+
for (Output output : outputs) {
output.getActiveNodes(activeNodes);
}
-
}
- return activeNodes;
+
}
+ public boolean compareTo(Chromosome chromosome) {
+ for (int r = 0; r < Parameters.getRows(); r++) {
+ for (int c = 0; c < Parameters.getColumns(); c++) {
+ if (!(nodes[r][c].copyOf(chromosome.getNode(r, c)))) {
+ return false;
+ }
+ }
+ }
+
+ for (int o = 0; o < Parameters.getOutputs(); o++) {
+ if (!(outputs[o].copyOf(chromosome.getOutput(o)))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public boolean compareActiveTo(Chromosome chromosome) {
+ // update list if it is out of date
+ computeActiveNodes();
+
+ if (activeNodes.size() == chromosome.getActiveNodes().size()) {
+ for (int i = 0; i < activeNodes.size(); i++) {
+ if (!(activeNodes.get(i).copyOf(chromosome.getActiveNodes().get(i)))){
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
}
diff --git a/src/jcgp/population/Connection.java b/src/jcgp/population/Connection.java
index 12e92d6..3312de3 100644
--- a/src/jcgp/population/Connection.java
+++ b/src/jcgp/population/Connection.java
@@ -1,11 +1,7 @@
package jcgp.population;
-import java.util.ArrayList;
-
public interface Connection {
public int getValue();
- public void getActive(ArrayList<Connection> activeNodes);
-
}
diff --git a/src/jcgp/population/Input.java b/src/jcgp/population/Input.java
index f3199b8..ee008ce 100644
--- a/src/jcgp/population/Input.java
+++ b/src/jcgp/population/Input.java
@@ -1,7 +1,5 @@
package jcgp.population;
-import java.util.ArrayList;
-
public class Input implements Connection {
private int value = 0, index;
@@ -23,11 +21,4 @@ public class Input implements Connection {
return index;
}
- @Override
- public void getActive(ArrayList<Connection> activeNodes) {
- if (!activeNodes.contains(this)) {
- activeNodes.add(this);
- }
- }
-
}
diff --git a/src/jcgp/population/MutableElement.java b/src/jcgp/population/MutableElement.java
index 5eae4ef..114a4ab 100644
--- a/src/jcgp/population/MutableElement.java
+++ b/src/jcgp/population/MutableElement.java
@@ -3,5 +3,23 @@ package jcgp.population;
public interface MutableElement {
public void setConnection(Connection newConnection);
+
+ /**
+ * This method returns true if and only if:</br>
+ * - the elements being compared are not the same instance;</br>
+ * - the connections of the compared elements are not the same instance;</br>
+ * - the elements have the same function (in the case of Node);</br>
+ * - the grid position of the elements themselves are the same;</br>
+ * - the grid position of all equivalent connections are the same;</br></br>
+ *
+ * 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>
+ *
+ * @param m
+ * @return
+ */
+ boolean copyOf(MutableElement m);
}
diff --git a/src/jcgp/population/Node.java b/src/jcgp/population/Node.java
index c09532c..b2e29df 100644
--- a/src/jcgp/population/Node.java
+++ b/src/jcgp/population/Node.java
@@ -1,6 +1,7 @@
package jcgp.population;
import java.util.ArrayList;
+import java.util.Arrays;
import jcgp.Parameters;
import jcgp.Utilities;
@@ -8,7 +9,7 @@ import jcgp.function.Function;
public class Node implements MutableElement, Connection {
-
+
private Function function;
private Connection[] connections;
private int column, row;
@@ -18,28 +19,29 @@ public class Node implements MutableElement, Connection {
this.chromosome = chromosome;
this.column = column;
this.row = row;
+ this.connections = new Connection[Parameters.getMaxArity()];
}
-
+
@Override
public int getValue() {
- return function.run(connections);
+ return function.run(Arrays.copyOfRange(connections, 0, function.getArity()));
}
-
+
public void setFunction(Function newFunction) {
function = newFunction;
chromosome.recomputeActiveNodes();
}
-
+
@Override
public void setConnection(Connection newConnection) {
connections[Utilities.getRandomInt(connections.length)] = newConnection;
chromosome.recomputeActiveNodes();
}
-
+
public void initialise(Function newFunction, Connection ... newConnections) throws InsufficientConnectionsException {
-
+
function = newFunction;
-
+
if (newConnections.length >= Parameters.getMaxArity()) {
connections = newConnections;
} else {
@@ -48,7 +50,6 @@ public class Node implements MutableElement, Connection {
}
public int getColumn() {
-
return column;
}
@@ -64,13 +65,48 @@ public class Node implements MutableElement, Connection {
return connections[index];
}
- @Override
- public void getActive(ArrayList<Connection> activeNodes) {
+ public void getActive(ArrayList<Node> activeNodes) {
if (!activeNodes.contains(this)) {
activeNodes.add(this);
}
for (int i = 0; i < function.getArity(); i++) {
- connections[i].getActive(activeNodes);
+ if (connections[i] instanceof Node) {
+ ((Node) connections[i]).getActive(activeNodes);
+ }
+
+ }
+ }
+
+ @Override
+ public boolean copyOf(MutableElement m) {
+ if (this != m) {
+ if (m instanceof Node) {
+ Node n = (Node) m;
+ if (function == 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()) {
+ 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()) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ }
}
+ return false;
}
}
diff --git a/src/jcgp/population/Output.java b/src/jcgp/population/Output.java
index 0171d7b..f0bcbbf 100644
--- a/src/jcgp/population/Output.java
+++ b/src/jcgp/population/Output.java
@@ -31,7 +31,33 @@ public class Output implements MutableElement {
return source;
}
- public void getActiveNodes(ArrayList<Connection> activeNodes) {
- source.getActive(activeNodes);
+ public void getActiveNodes(ArrayList<Node> activeNodes) {
+ if (source instanceof Node) {
+ ((Node) source).getActive(activeNodes);
+ }
+ }
+
+ @Override
+ public boolean copyOf(MutableElement m) {
+ if (this != m) {
+ 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()) {
+ 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()) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
}
}