diff options
Diffstat (limited to 'src/jcgp/backend/population/Node.java')
-rw-r--r-- | src/jcgp/backend/population/Node.java | 125 |
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() { |