|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--ec.gp.GPNode
GPNode is a GPNodeParent which is the abstract superclass of all GP function nodes in trees. GPNode contains quite a few functions for cloning subtrees in special ways, counting the number of nodes in subtrees in special ways, and finding specific nodes in subtrees. GPNode's protoClone() method does not clone its children (it copies the array, but that's it). If you want to deep-clone a tree or subtree, you should use one of the cloneReplacing(...) methods instead.
GPNodes contain a number of important items:
Parameters
base.nc String |
(name of the node constraints for the GPNode) |
Default Base
gp.node
Field Summary | |
byte |
argposition
The argument position of the child in its parent. |
GPNode[] |
children
|
byte |
constraints
The GPNode's constraints. |
static java.lang.String |
GPNODEPRINTTAB
|
static int |
MAXPRINTBYTES
|
static int |
NODESEARCH_ALL
|
static int |
NODESEARCH_CUSTOM
|
static int |
NODESEARCH_NONTERMINALS
|
static int |
NODESEARCH_TERMINALS
|
static java.lang.String |
P_NODE
|
static java.lang.String |
P_NODECONSTRAINTS
|
GPNodeParent |
parent
The GPNode's parent. |
static char |
REPLACEMENT_CHAR
|
static int |
SITUATION_MUTATION
|
static int |
SITUATION_NEWIND
|
Constructor Summary | |
GPNode()
|
Method Summary | |
int |
atDepth()
Returns the depth at which I appear in the tree, which is a value >= 0. |
void |
checkConstraints(EvolutionState state,
int tree,
GPIndividual typicalIndividual,
Parameter individualBase)
You ought to override this method to check to make sure that the constraints are valid as best you can tell. |
GPNode |
cloneReplacing()
Deep-clones the tree rooted at this node, and returns the entire copied tree. |
GPNode |
cloneReplacing(GPNode[] newSubtrees,
GPNode[] oldSubtrees)
Deep-clones the tree rooted at this node, and returns the entire copied tree. |
GPNode |
cloneReplacing(GPNode newSubtree,
GPNode oldSubtree)
Deep-clones the tree rooted at this node, and returns the entire copied tree. |
GPNode |
cloneReplacingAtomic(GPNode[] newNodes,
GPNode[] oldNodes)
Clones a new subtree, but with each node in oldNodes[] respectively (which may or may not be in the subtree) replaced with the equivalent nodes in newNodes[] (and not clones). |
GPNode |
cloneReplacingAtomic(GPNode newNode,
GPNode oldNode)
Clones a new subtree, but with the single node oldNode (which may or may not be in the subtree) replaced with a newNode (not a clone of newNode). |
GPNode |
cloneReplacingAtomicSimple(GPNode[] newNodes,
GPNode[] oldNodes)
Clones a new subtree, but with each node in oldNodes[] respectively (which may or may not be in the subtree) replaced with the equivalent nodes in newNodes[] (and not clones of them). |
GPNode |
cloneReplacingAtomicSimple(GPNode newNode,
GPNode oldNode)
Clones a new subtree, but with the single node oldNode (which may or may not be in the subtree) replaced with newNode (not a clone of newNode). |
GPNode |
cloneReplacingNoSubclone(GPNode newSubtree,
GPNode oldSubtree)
Deep-clones the tree rooted at this node, and returns the entire copied tree. |
GPNode |
cloneReplacingNoSubcloneSimple(GPNode newSubtree,
GPNode oldSubtree)
Deep-clones the tree rooted at this node, and returns the entire copied tree. |
GPNode |
cloneReplacingSimple()
Deep-clones the tree rooted at this node, and returns the entire copied tree. |
GPNode |
cloneReplacingSimple(GPNode[] newSubtrees,
GPNode[] oldSubtrees)
Deep-clones the tree rooted at this node, and returns the entire copied tree. |
GPNode |
cloneReplacingSimple(GPNode newSubtree,
GPNode oldSubtree)
Deep-clones the tree rooted at this node, and returns the entire copied tree. |
GPNodeConstraints |
constraints()
|
boolean |
contains(GPNode subnode)
Returns true if the subtree rooted at this node contains subnode. |
Parameter |
defaultBase()
The default base for GPNodes -- defined even though GPNode is abstract so you don't have to in subclasses. |
int |
depth()
Returns the depth of the tree, which is a value >= 1. |
java.lang.String |
errorInfo()
A convenience function for identifying a GPNode in an error message |
abstract void |
eval(EvolutionState state,
int thread,
GPData input,
ADFStack stack,
GPIndividual individual,
Problem problem)
Evaluates the node with the given thread, state, individual, problem, and stack. |
java.lang.String |
makeLatexTree()
Produces the LaTeX code for a LaTeX tree of the subtree rooted at this node, using the epic and fancybox packages, as described in sections 10.5.2 (page 307) and 10.1.3 (page 278) of The LaTeX Companion, respectively. |
boolean |
nodeEquals(GPNode node)
Returns true if I am the "genetically" same as this node, and our children arrays are the same length, though we may have different parents and children. |
int |
nodeHashCode()
Returns a hashcode usually associated with all nodes that are equal to you (using nodeEquals(...)). |
int |
nodeInPosition(int p,
GPNodeGatherer g,
int nodesearch)
Returns the p'th node, constrained by nodesearch, in the subtree for which this GPNode is root. |
int |
numNodes(GPNodeGatherer g)
Returns the number of nodes, constrained by g.test(...) in the subtree for which this GPNode is root. |
int |
numNodes(int nodesearch)
Returns the number of nodes, constrained by nodesearch, in the subtree for which this GPNode is root. |
GPType |
parentType()
Returns the argument type of the slot that I fit into in my parent. |
int |
printNode(EvolutionState state,
int log,
int verbosity)
Prints out a COMPUTER-readable and Lisp-like atom for the node, which is also suitable for readNode to read, and returns the number of bytes in the string that you sent to the log (use print(), not println()). |
int |
printNode(EvolutionState state,
java.io.PrintWriter writer)
Prints out a COMPUTER-readable and Lisp-like atom for the node, which is also suitable for readNode to read, and returns the number of bytes in the string that you sent to the log (use print(), not println()). |
int |
printNodeForHumans(EvolutionState state,
int log,
int verbosity)
Prints out a human-readable and Lisp-like atom for the node, and returns the number of bytes in the string that you sent to the log (use print(), not println()). |
int |
printRootedTree(EvolutionState state,
int log,
int verbosity,
int printbytes)
Prints out the tree on a single line, with no ending \n, in a fashion that can be read in later by computer. |
int |
printRootedTree(EvolutionState state,
java.io.PrintWriter writer,
int printbytes)
Prints out the tree on a single line, with no ending \n, in a fashion that can be read in later by computer. |
int |
printRootedTreeForHumans(EvolutionState state,
int log,
int verbosity,
int tablevel,
int printbytes)
Prints out the tree in a readable Lisp-like multi-line fashion. |
java.lang.Object |
protoClone()
Creates a new individual cloned from a prototype, and suitable to begin use in its own evolutionary context. |
java.lang.Object |
protoCloneSimple()
This should be implemented in a the top-level Prototype ONLY; in fact, it should probably be declared final. |
GPNode |
readNode(DecodeReturn dret)
Reads the node symbol, advancing the DecodeReturn to the first character in the string beyond the node symbol, and returns a new, empty GPNode of the appropriate class representing that symbol, else null if the node symbol is not of the correct type for your GPNode class. |
static GPNode |
readRootedTree(int linenumber,
DecodeReturn dret,
GPType expectedType,
GPFunctionSet set,
GPNodeParent parent,
int argposition,
EvolutionState state)
Reads the node and its children from the form printed out by printRootedTree. |
void |
resetNode(EvolutionState state,
int thread)
Starts a node in a new life immediately after it has been cloned. |
boolean |
rootedTreeEquals(GPNode node)
Returns true if the two rooted trees are "genetically" equal, though they may have different parents. |
int |
rootedTreeHashCode()
Returns a hashcode associated with all the nodes in the tree. |
GPNodeParent |
rootParent()
Returns the root ancestor of this node. |
void |
setup(EvolutionState state,
Parameter base)
Sets up a prototypical GPNode with those features all nodes of that prototype share, and nothing more. |
boolean |
swapCompatibleWith(GPNode node)
Returns true if I can swap into node's position. |
abstract java.lang.String |
toString()
Returns a Lisp-like atom for the node which can be read in again by computer. |
java.lang.String |
toStringForError()
Returns a description of the node that can make it easy to identify in error messages (by default, at least its name and the tree it's found in). |
java.lang.String |
toStringForHumans()
Returns a Lisp-like atom for the node which is intended for human consumption, and not to be read in again. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
public static final java.lang.String P_NODE
public static final java.lang.String P_NODECONSTRAINTS
public static final java.lang.String GPNODEPRINTTAB
public static final int MAXPRINTBYTES
public static final int NODESEARCH_ALL
public static final int NODESEARCH_TERMINALS
public static final int NODESEARCH_NONTERMINALS
public static final int NODESEARCH_CUSTOM
public static final int SITUATION_NEWIND
public static final int SITUATION_MUTATION
public GPNodeParent parent
public GPNode[] children
public byte argposition
public byte constraints
public static final char REPLACEMENT_CHAR
Constructor Detail |
public GPNode()
Method Detail |
public final GPNodeConstraints constraints()
public Parameter defaultBase()
defaultBase
in interface Prototype
public void checkConstraints(EvolutionState state, int tree, GPIndividual typicalIndividual, Parameter individualBase)
public void setup(EvolutionState state, Parameter base)
setup
in interface Prototype
public final GPType parentType()
public final boolean swapCompatibleWith(GPNode node)
public int numNodes(GPNodeGatherer g)
public int numNodes(int nodesearch)
public int depth()
public int atDepth()
public int nodeInPosition(int p, GPNodeGatherer g, int nodesearch)
public GPNodeParent rootParent()
public boolean contains(GPNode subnode)
public void resetNode(EvolutionState state, int thread)
public java.lang.String errorInfo()
public java.lang.Object protoClone() throws java.lang.CloneNotSupportedException
Prototype
The question here is whether or not this means to perform a "deep" or "light" ("shallow") clone, or something in-between. You may need to deep-clone parts of your object rather than simply copying their references, depending on the situation:
Implementations.
public Object protoClone() throws CloneNotSupportedException
{
return super.clone();
}
public Object protoClone() throws CloneNotSupportedException
{
myobj = (MyObject) (super.clone());
// put your deep-cloning code here...
// ...you should use protoClone and not
// protoCloneSimple to clone subordinate objects...
return myobj;
}
public Object protoClone() throws CloneNotSupportedException
{
MyObject myobj = (MyObject)(super.protoClone());
// put your deep-cloning code here...
// ...you should use protoClone and not
// protoCloneSimple to clone subordinate objects...
return myobj;
}
If you know that your superclasses will never change their protoClone() implementations, you might try inlining them in your overridden protoClone() method. But this is dangerous (though it yields a small net increase).
In general, you want to keep your deep cloning to an absolute minimum, so that you don't have to call protoClone() but one time.
The approach taken here is the fastest that I am aware of while still permitting objects to be specified at runtime from a parameter file. It would be faster to use the "new" operator; but that would require hard-coding that we can't do. Although using java.lang.Object.clone() entails an extra layer that deals with stripping away the "protected" keyword and also wrapping the exception handling (which is a BIG hit, about three times as slow as using "new"), it's still MUCH faster than using java.lang.Class.newInstance(), and also much faster than rolling our own Clone() method.
protoClone
in interface Prototype
public final java.lang.Object protoCloneSimple()
Prototype
public final Object protoCloneSimple()
{
try { return protoClone(); }
catch (CloneNotSupportedException e)
{ throw new InternalError(); } // never happens
}
protoCloneSimple
in interface Prototype
public final GPNode cloneReplacing() throws java.lang.CloneNotSupportedException
public final GPNode cloneReplacingSimple()
public final GPNode cloneReplacing(GPNode newSubtree, GPNode oldSubtree) throws java.lang.CloneNotSupportedException
public final GPNode cloneReplacingSimple(GPNode newSubtree, GPNode oldSubtree)
public final GPNode cloneReplacingNoSubclone(GPNode newSubtree, GPNode oldSubtree) throws java.lang.CloneNotSupportedException
public final GPNode cloneReplacingNoSubcloneSimple(GPNode newSubtree, GPNode oldSubtree)
public final GPNode cloneReplacing(GPNode[] newSubtrees, GPNode[] oldSubtrees) throws java.lang.CloneNotSupportedException
public final GPNode cloneReplacingSimple(GPNode[] newSubtrees, GPNode[] oldSubtrees)
public final GPNode cloneReplacingAtomic(GPNode newNode, GPNode oldNode) throws java.lang.CloneNotSupportedException
public final GPNode cloneReplacingAtomicSimple(GPNode newNode, GPNode oldNode)
public final GPNode cloneReplacingAtomic(GPNode[] newNodes, GPNode[] oldNodes) throws java.lang.CloneNotSupportedException
public final GPNode cloneReplacingAtomicSimple(GPNode[] newNodes, GPNode[] oldNodes)
public int nodeHashCode()
public int rootedTreeHashCode()
public boolean nodeEquals(GPNode node)
public boolean rootedTreeEquals(GPNode node)
public int printNodeForHumans(EvolutionState state, int log, int verbosity)
public int printNode(EvolutionState state, int log, int verbosity)
public int printNode(EvolutionState state, java.io.PrintWriter writer)
public abstract java.lang.String toString()
toString
in class java.lang.Object
public java.lang.String toStringForHumans()
public java.lang.String toStringForError()
public java.lang.String makeLatexTree()
public int printRootedTree(EvolutionState state, int log, int verbosity, int printbytes)
public int printRootedTree(EvolutionState state, java.io.PrintWriter writer, int printbytes)
public int printRootedTreeForHumans(EvolutionState state, int log, int verbosity, int tablevel, int printbytes)
public GPNode readNode(DecodeReturn dret) throws java.lang.CloneNotSupportedException
public static GPNode readRootedTree(int linenumber, DecodeReturn dret, GPType expectedType, GPFunctionSet set, GPNodeParent parent, int argposition, EvolutionState state) throws java.lang.CloneNotSupportedException
public abstract void eval(EvolutionState state, int thread, GPData input, ADFStack stack, GPIndividual individual, Problem problem)
About input: input is special; it is how data is passed between parent and child nodes. If children "receive" data from their parent node when it evaluates them, they should receive this data stored in input. If (more likely) the parent "receives" results from its children, it should pass them an input object, which they'll fill out, then it should check this object for the returned value.
A tree is typically evaluated by dropping a GPData into the root. When the root returns, the resultant input should hold the return value.
In general, you should not be creating new GPDatas. If you think about it, in most conditions (excepting ADFs and ADMs) you can use and reuse input for most communications purposes between parents and children.
So, let's say that your GPNode function implements the boolean AND function,
and expects its children to return return boolean values (as it does itself).
You've implemented your GPData subclass to be, uh, BooleanData, which
looks like
public class BooleanData extends GPData
{
public boolean result;
public GPData copyTo(GPData gpd)
{
((BooleanData)gpd).result = result;
}
}
...so, you might implement your eval(...) function as follows:
public void eval(final EvolutionState state,
final int thread,
final GPData input,
final ADFStack stack,
final GPIndividual individual,
final Problem problem
{
BooleanData dat = (BooleanData)input;
boolean x;
// evaluate the first child
children[0].eval(state,thread,input,stack,individual,problem);
// store away its result
x = dat.result;
// evaluate the second child
children[1].eval(state,thread,input,stack,individual,problem);
// return (in input) the result of the two ANDed
dat.result = dat.result && x;
return;
}
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |