aboutsummaryrefslogtreecommitdiffstats
path: root/src/jcgp/backend/population/Node.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jcgp/backend/population/Node.java')
-rw-r--r--src/jcgp/backend/population/Node.java125
1 files changed, 99 insertions, 26 deletions
diff --git a/src/jcgp/backend/population/Node.java b/src/jcgp/backend/population/Node.java
index 74f6b54..704b24e 100644
--- a/src/jcgp/backend/population/Node.java
+++ b/src/jcgp/backend/population/Node.java
@@ -4,41 +4,63 @@ import java.util.ArrayList;
import jcgp.backend.function.Function;
-
-public class Node extends Gene implements MutableElement, Connection {
+/**
+ * Nodes make up the main part of the chromosome,
+ * where the actual functions are evolved. Each node
+ * contains a function and a number of connections.
+ * The node outputs the result of performing its function
+ * on the values of its connections. Nodes therefore
+ * implement both {@code MutableElement} and {@code Connection}
+ * since they can be mutated but also connected to.
+ * Nodes are constructed with a fixed number of connections
+ * (determined by the maximum arity of the function set)
+ * and must be reinstantiated if the experiment arity
+ * changes.
+ *
+ * @author Eduardo Pedroni
+ *
+ */
+public class Node implements MutableElement, Connection {
private Function function;
private Connection[] connections;
private int column, row;
private Chromosome chromosome;
+ /**
+ * Constructs a new instance of {@code Node} with the
+ * specified parameters. Nodes must contain their
+ * own row and column for ease of copying.
+ *
+ * @param chromosome the chromosome this node belongs to.
+ * @param row the node's row.
+ * @param column the node's column.
+ * @param arity the maximum arity of the experiment.
+ */
public Node(Chromosome chromosome, int row, int column, int arity) {
this.chromosome = chromosome;
this.column = column;
this.row = row;
}
-
- @Override
- public Object getValue() {
- Object[] args = new Object[function.getArity()];
- for (int i = 0; i < function.getArity(); i++) {
- args[i] = connections[i].getValue();
- }
- return function.run(args);
- }
-
+
+ /**
+ * Sets the node function.
+ *
+ * @param newFunction the new function to set.
+ */
public void setFunction(Function newFunction) {
function = newFunction;
}
- @Override
- public void setConnection(int index, Connection newConnection) {
- if (newConnection != null) {
- connections[index] = newConnection;
- chromosome.recomputeActiveNodes();
- }
- }
-
+ /**
+ * Initialises the node with the specified values.
+ * The number of connections passed as argument must
+ * be exactly the same as the experiment arity, or
+ * an {@code IllegalArgumentException} will be thrown.
+ *
+ * @param newFunction the node function to set.
+ * @param newConnections the node connections to set.
+ */
public void initialise(Function newFunction, Connection ... newConnections) {
function = newFunction;
if (newConnections.length == chromosome.getResources().arity()) {
@@ -48,41 +70,71 @@ public class Node extends Gene implements MutableElement, Connection {
}
}
+ /**
+ * @return this node's column.
+ */
public int getColumn() {
return column;
}
+ /**
+ * @return this node's row.
+ */
public int getRow() {
return row;
}
+ /**
+ * @return this node's function.
+ */
public Function getFunction() {
return function;
}
+ /**
+ * @param index the connection to return.
+ * @return the indexed connection.
+ */
public Connection getConnection(int index) {
return connections[index];
}
- public void getActive(ArrayList<Node> activeNodes) {
+ /**
+ * For package use, this is a recursive method
+ * used to create a collection of active nodes
+ * in the chromosome. If this node is not already
+ * in the active node list, this method adds it.
+ * It then calls {@code getActive()} on each of its
+ * connections, therefore recursively adding every
+ * single active node to the given list.
+ *
+ * @param activeNodes the list of active nodes being built.
+ */
+ protected void getActive(ArrayList<Node> activeNodes) {
+ // don't add the same node twice
if (!activeNodes.contains(this)) {
activeNodes.add(this);
}
+ // call getActive on all connections - they are all active
for (int i = 0; i < function.getArity(); i++) {
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;
+ public boolean copyOf(MutableElement element) {
+ // both cannot be the same instance
+ if (this != element) {
+ // element must be instance of node
+ if (element instanceof Node) {
+ Node n = (Node) element;
+ // must have the same function
if (function == n.getFunction()) {
+ // row and column must be the same
if (column == n.getColumn() && row == n.getRow()) {
+ // connections must be the equivalent, but not the same instance
for (int i = 0; i < connections.length; i++) {
if (connections[i] != n.getConnection(i)) {
if (connections[i] instanceof Input && n.getConnection(i) instanceof Input) {
@@ -101,6 +153,7 @@ public class Node extends Gene implements MutableElement, Connection {
return false;
}
}
+ // all connections checked, this really is a copy
return true;
}
}
@@ -108,6 +161,26 @@ public class Node extends Gene implements MutableElement, Connection {
}
return false;
}
+
+ @Override
+ public Object getValue() {
+ // build list of arguments recursively
+ Object[] args = new Object[function.getArity()];
+ for (int i = 0; i < function.getArity(); i++) {
+ args[i] = connections[i].getValue();
+ }
+ // return function result
+ return function.run(args);
+ }
+
+ @Override
+ public void setConnection(int index, Connection newConnection) {
+ // connection must not be null
+ if (newConnection != null) {
+ connections[index] = newConnection;
+ chromosome.recomputeActiveNodes();
+ }
+ }
@Override
public String toString() {