ec.gp
Class GPNode

java.lang.Object
  extended by ec.gp.GPNode
All Implemented Interfaces:
GPNodeParent, Prototype, Setup, java.io.Serializable, java.lang.Cloneable
Direct Known Subclasses:
A0, A0, A1, A1, A2, A2, Accept, Add, Add, ADF, ADFArgument, And, And, And, BAccept, BBud, BLoop, BStart, Bud, Cos, D0, D0, D0, D1, D1, D1, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D2, D2, D2, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D3, D3, D3, D30, D31, D4, D4, D4, D5, D5, D5, D6, D6, D6, D7, D7, D7, D8, D9, Div, Div, Double, Epsilon, ERC, Exp, Frog, H0, H1, If, If, IfFoodAhead, L0, L1, Left, Left, Log, Loop, Move, Mow, Mul, Mul, Nand, Nor, Not, Not, One, Or, Or, Or, Progn2, Progn2, Progn3, Progn4, Reverse, Right, Sin, Split, Start, Sub, Sub, V8a, W0, W1, X, Zero

public abstract class GPNode
extends java.lang.Object
implements GPNodeParent, Prototype

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 lightClone() 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:

In addition to serialization for checkpointing, GPNodes may read and write themselves to streams in three ways.

Parameters

base.nc
String
(name of the node constraints for the GPNode)

Default Base
gp.node

Version:
1.0
Author:
Sean Luke
See Also:
Serialized Form

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.
 java.lang.Object clone()
          Deep-clones the tree rooted at this node, and returns the entire copied tree.
 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 cloneReplacingNoSubclone(GPNode newSubtree, GPNode oldSubtree)
          Deep-clones the tree rooted at this node, and returns the entire copied tree.
 GPNodeConstraints constraints(GPInitializer initializer)
           
 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.
 GPNode lightClone()
           
 java.lang.String makeCTree(boolean parentMadeParens, boolean printTerminalsAsVariables, boolean useOperatorForm)
          Producess a String consisting of the tree in pseudo-C form, given that the parent already will wrap the expression in parentheses (or not).
 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" identical to this node, and our children arrays are the same length, though we may have different parents and children.
 boolean nodeEquivalentTo(GPNode node)
          Returns true if I and the provided node are the same kind of node -- that is, we could have both been cloned() and reset() from the same prototype node.
 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(GPInitializer initializer)
          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.
 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.
 void readNode(EvolutionState state, java.io.DataInput dataInput)
          Override this to read any additional node-specific information from dataInput besides: the number of arguments, the specific node class, the children, and the parent.
static GPNode readRootedTree(EvolutionState state, java.io.DataInput dataInput, GPType expectedType, GPFunctionSet set, GPNodeParent parent, int argposition)
           
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 replaceWith(GPNode newNode)
          Replaces the node with another node in its position in the tree.
 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(GPInitializer initializer, 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.
 void writeNode(EvolutionState state, java.io.DataOutput dataOutput)
          Override this to write any additional node-specific information to dataOutput besides: the number of arguments, the specific node class, the children, and the parent.
 void writeRootedTree(EvolutionState state, GPType expectedType, GPFunctionSet set, java.io.DataOutput dataOutput)
           
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

P_NODE

public static final java.lang.String P_NODE
See Also:
Constant Field Values

P_NODECONSTRAINTS

public static final java.lang.String P_NODECONSTRAINTS
See Also:
Constant Field Values

GPNODEPRINTTAB

public static final java.lang.String GPNODEPRINTTAB
See Also:
Constant Field Values

MAXPRINTBYTES

public static final int MAXPRINTBYTES
See Also:
Constant Field Values

NODESEARCH_ALL

public static final int NODESEARCH_ALL
See Also:
Constant Field Values

NODESEARCH_TERMINALS

public static final int NODESEARCH_TERMINALS
See Also:
Constant Field Values

NODESEARCH_NONTERMINALS

public static final int NODESEARCH_NONTERMINALS
See Also:
Constant Field Values

NODESEARCH_CUSTOM

public static final int NODESEARCH_CUSTOM
See Also:
Constant Field Values

SITUATION_NEWIND

public static final int SITUATION_NEWIND
See Also:
Constant Field Values

SITUATION_MUTATION

public static final int SITUATION_MUTATION
See Also:
Constant Field Values

parent

public GPNodeParent parent
The GPNode's parent. 4 bytes. :-( But it really helps simplify breeding.


children

public GPNode[] children

argposition

public byte argposition
The argument position of the child in its parent. This is a byte to save space (GPNode is the critical object space-wise) -- besides, how often do you have 256 children? You can change this to a short or int easily if you absolutely need to. It's possible to eliminate even this and have the child find itself in its parent, but that's an O(children[]) operation, and probably not inlinable, so I figure a byte is okay.


constraints

public byte constraints
The GPNode's constraints. This is a byte to save space -- how often do you have 256 different GPNodeConstraints? Well, I guess it's not infeasible. You can increase4 this to an int without much trouble. You typically shouldn't access the constraints through this variable -- use the constraints(state) method instead.


REPLACEMENT_CHAR

public static final char REPLACEMENT_CHAR
See Also:
Constant Field Values
Constructor Detail

GPNode

public GPNode()
Method Detail

constraints

public final GPNodeConstraints constraints(GPInitializer initializer)

defaultBase

public Parameter defaultBase()
The default base for GPNodes -- defined even though GPNode is abstract so you don't have to in subclasses.

Specified by:
defaultBase in interface Prototype

checkConstraints

public 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. Things you might check for: You can't check for everything, of course, but you might try some obvious checks for blunders. The default version of this method is empty for now, but you should still call super.checkConstraints(state) just to be certain. The ultimate caller of this method must guarantee that he will eventually call state.output.exitIfErrors(), so you can freely use state.output.error instead of state.output.fatal(), which will help a lot. Warning: this method may get called more than once.


setup

public void setup(EvolutionState state,
                  Parameter base)
Sets up a prototypical GPNode with those features all nodes of that prototype share, and nothing more. So no filled-in children, no argposition, no parent. Yet. This must be called after the GPTypes and GPNodeConstraints have been set up. Presently they're set up in GPInitializer, which gets called before this does, so we're safe. You should override this if you need to load some special features on a per-function basis. Note that base hangs off of a function set, so this method may get called for different instances in the same GPNode class if they're being set up as prototypes for different GPFunctionSets. If you absolutely need some global base, then you should use something hanging off of GPDefaults.base(). The ultimate caller of this method must guarantee that he will eventually call state.output.exitIfErrors(), so you can freely use state.output.error instead of state.output.fatal(), which will help a lot.

Specified by:
setup in interface Prototype
Specified by:
setup in interface Setup

parentType

public final GPType parentType(GPInitializer initializer)
Returns the argument type of the slot that I fit into in my parent. If I'm the root, returns the treetype of the GPTree.


swapCompatibleWith

public final boolean swapCompatibleWith(GPInitializer initializer,
                                        GPNode node)
Returns true if I can swap into node's position.


numNodes

public int numNodes(GPNodeGatherer g)
Returns the number of nodes, constrained by g.test(...) in the subtree for which this GPNode is root. This might be sped up by caching the value. O(n).


numNodes

public int numNodes(int nodesearch)
Returns the number of nodes, constrained by nodesearch, in the subtree for which this GPNode is root. This might be sped up by cacheing the value somehow. O(n).


depth

public int depth()
Returns the depth of the tree, which is a value >= 1. O(n).


atDepth

public int atDepth()
Returns the depth at which I appear in the tree, which is a value >= 0. O(ln n) avg.


nodeInPosition

public 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. Use numNodes(nodesearch) to determine the total number. Or if you used numNodes(g), then when nodesearch == NODESEARCH_CUSTOM, g.test(...) is used as the constraining predicate. p ranges from 0 to this number minus 1. O(n). The resultant node is returned in g.


rootParent

public GPNodeParent rootParent()
Returns the root ancestor of this node. O(ln n) average case, O(n) worst case.


contains

public boolean contains(GPNode subnode)
Returns true if the subtree rooted at this node contains subnode. O(n).


resetNode

public void resetNode(EvolutionState state,
                      int thread)
Starts a node in a new life immediately after it has been cloned. The default version of this function does nothing. The purpose of this function is to give ERCs a chance to set themselves to a new random value after they've been cloned from the prototype. You should not assume that the node is properly connected to other nodes in the tree at the point this method is called.


errorInfo

public java.lang.String errorInfo()
A convenience function for identifying a GPNode in an error message


lightClone

public GPNode lightClone()

clone

public java.lang.Object clone()
Deep-clones the tree rooted at this node, and returns the entire copied tree. The result has everything set except for the root node's parent and argposition.

Specified by:
clone in interface Prototype
Overrides:
clone in class java.lang.Object

cloneReplacing

public final GPNode cloneReplacing()
Deep-clones the tree rooted at this node, and returns the entire copied tree. The result has everything set except for the root node's parent and argposition.


cloneReplacing

public final GPNode cloneReplacing(GPNode newSubtree,
                                   GPNode oldSubtree)
Deep-clones the tree rooted at this node, and returns the entire copied tree. If the node oldSubtree is located somewhere in this tree, then its subtree is replaced with a deep-cloned copy of newSubtree. The result has everything set except for the root node's parent and argposition.


cloneReplacingNoSubclone

public final GPNode cloneReplacingNoSubclone(GPNode newSubtree,
                                             GPNode oldSubtree)
Deep-clones the tree rooted at this node, and returns the entire copied tree. If the node oldSubtree is located somewhere in this tree, then its subtree is replaced with newSubtree (not a copy of newSubtree). The result has everything set except for the root node's parent and argposition.


cloneReplacing

public final GPNode cloneReplacing(GPNode[] newSubtrees,
                                   GPNode[] oldSubtrees)
Deep-clones the tree rooted at this node, and returns the entire copied tree. If a node in oldSubtrees is located somewhere in this tree, then its subtree is replaced with a deep-cloned copy of the subtree rooted at its equivalent number in newSubtrees. The result has everything set except for the root node's parent and argposition.


cloneReplacingAtomic

public final 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). These nodes should be type-compatible both in argument and return types, and should have the same number of arguments obviously. This function will not check for this, and if they are not the result is undefined.


cloneReplacingAtomic

public final 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). The length of oldNodes[] and newNodes[] should be the same of course. These nodes should be type-compatible both in argument and return types, and should have the same number of arguments obviously. This function will not check for this, and if they are not the result is undefined.


replaceWith

public final void replaceWith(GPNode newNode)
Replaces the node with another node in its position in the tree. newNode should already have been cloned and ready to go. We presume that the other node is type-compatible and of the same arity (these things aren't checked).


nodeEquivalentTo

public boolean nodeEquivalentTo(GPNode node)
Returns true if I and the provided node are the same kind of node -- that is, we could have both been cloned() and reset() from the same prototype node. The default form of this function returns true if I and the node have the same class, the same length children array, and the same constraints. You may wish to override this in certain circumstances. Here's an example of how nodeEquivalentTo(node) differs from nodeEquals(node): two ERCs, both of the same class, but one holding '1.23' and the other holding '2.45', which came from the same prototype node in the same function set. They should NOT be nodeEquals(...) but *should* be nodeEquivalent(...).


nodeHashCode

public int nodeHashCode()
Returns a hashcode usually associated with all nodes that are equal to you (using nodeEquals(...)). The default form of this method returns the hashcode of the node's class. ERCs in particular probably will want to override this method.


rootedTreeHashCode

public int rootedTreeHashCode()
Returns a hashcode associated with all the nodes in the tree. The default version adds the hash of the node plus its child trees, rotated one-off each time, which seems reasonable.


nodeEquals

public boolean nodeEquals(GPNode node)
Returns true if I am the "genetically" identical to this node, and our children arrays are the same length, though we may have different parents and children. The default form of this method simply calls the much weaker nodeEquivalentTo(node). You may need to override this to perform exact comparisons, if you're an ERC, ADF, or ADM for example. Here's an example of how nodeEquivalentTo(node) differs from nodeEquals(node): two ERCs, both of the same class, but one holding '1.23' and the other holding '2.45', which came from the same prototype node in the same function set. They should NOT be nodeEquals(...) but *should* be nodeEquivalent(...).


rootedTreeEquals

public boolean rootedTreeEquals(GPNode node)
Returns true if the two rooted trees are "genetically" equal, though they may have different parents. O(n).


printNodeForHumans

public 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()). The default version gets the atom from toStringForHumans().


printNode

public 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()). The default version gets the atom from toString(). O(1).


printNode

public 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()). The default version gets the atom from toString(). O(1).


toString

public abstract java.lang.String toString()
Returns a Lisp-like atom for the node which can be read in again by computer. If you need to encode an integer or a float or whatever for some reason (perhaps if it's an ERC), you should use the ec.util.Code library.

Overrides:
toString in class java.lang.Object

toStringForHumans

public 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. The default version just calls toString().


toStringForError

public 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). It's okay if this is a reasonably expensive procedure -- it won't be called a lot.


makeLatexTree

public 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. For this to work, the output of toString() must not contain any weird latex characters, notably { or } or % or \, unless you know what you're doing. See the documentation for ec.gp.GPTree for information on how to take this code snippet and insert it into your LaTeX file.


makeCTree

public java.lang.String makeCTree(boolean parentMadeParens,
                                  boolean printTerminalsAsVariables,
                                  boolean useOperatorForm)
Producess a String consisting of the tree in pseudo-C form, given that the parent already will wrap the expression in parentheses (or not). In pseudo-C form, functions with one child are printed out as a(b), functions with more than two children are printed out as a(b, c, d, ...), and functions with exactly two children are either printed as a(b, c) or in operator form as (b a c) -- for example, (b * c). Whether or not to do this depends on the setting of useOperatorForm. Additionally, terminals will be printed out either in variable form -- a -- or in zero-argument function form -- a() -- depending on the setting of printTerminalsAsVariables.


printRootedTree

public 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. O(n). You should call this method with printbytes == 0.


printRootedTree

public 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. O(n). Returns the number of bytes printed. You should call this method with printbytes == 0.


printRootedTreeForHumans

public int printRootedTreeForHumans(EvolutionState state,
                                    int log,
                                    int verbosity,
                                    int tablevel,
                                    int printbytes)
Prints out the tree in a readable Lisp-like multi-line fashion. O(n). You should call this method with tablevel and printbytes == 0. No ending '\n' is printed.


readNode

public 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. You may assume that initial whitespace has been eliminated. Generally should be case-SENSITIVE, unlike in Lisp. The default version usually works for "simple" function names, that is, not ERCs or other stuff where you have to encode the symbol.


writeRootedTree

public void writeRootedTree(EvolutionState state,
                            GPType expectedType,
                            GPFunctionSet set,
                            java.io.DataOutput dataOutput)
                     throws java.io.IOException
Throws:
java.io.IOException

readRootedTree

public static GPNode readRootedTree(EvolutionState state,
                                    java.io.DataInput dataInput,
                                    GPType expectedType,
                                    GPFunctionSet set,
                                    GPNodeParent parent,
                                    int argposition)
                             throws java.io.IOException
Throws:
java.io.IOException

writeNode

public void writeNode(EvolutionState state,
                      java.io.DataOutput dataOutput)
               throws java.io.IOException
Override this to write any additional node-specific information to dataOutput besides: the number of arguments, the specific node class, the children, and the parent. The default version of this method does nothing.

Throws:
java.io.IOException

readNode

public void readNode(EvolutionState state,
                     java.io.DataInput dataInput)
              throws java.io.IOException
Override this to read any additional node-specific information from dataInput besides: the number of arguments, the specific node class, the children, and the parent. The default version of this method does nothing.

Throws:
java.io.IOException

readRootedTree

public 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.


eval

public 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. Your random number generator will be state.random[thread]. The node should, as appropriate, evaluate child nodes with these same items passed to eval(...).

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;
    }