next up previous
Next: Populations Up: Implementation in C++ Previous: Program Trees

Node Classes

Each type of node is a subclass of the Node class. The two non-terminal node classes are Binary_Node and Unary_Node. They are basically identical, with the obvious exception of the number of children. All additional functions provided in these classes are mainly used for access to private fields and are self-explanatory. Constructors for each subclass take a pointer to the parent node, along with the operator or terminal that will be associated with the new node. Descriptions of the two classes:

// binary operation node
class Binary_Node : public Node {

  private:
    Node *left;                 // left child
    Node *right;                // right child
    Binary_Func *f;             // the function of this node

  public:
    // constructor takes the parent and the function
    Binary_Node(Node *,Binary_Func *);
    ~Binary_Node(void);         // destructor will delete the children

    // adds a node to the left
    void set_left(Node *l) {left = l;};
    // adds a node to the right
    void set_right(Node *r) {right = r;};
    // accesses the left child
    Node *get_left(void) {return left;};
    // accesses the right child
    Node *get_right(void) {return right;};
    // accesses the function
    Binary_Func *get_func(void) {return f;};

    double fitness;             // fitness of the tree (if this is the root)

    // value function just needs to pass the values of the children to
    // f
    Val value(void);            // value function
    int count(void);            // counter function
    Node *find(int);            // finder function
    char *print(void);          // printer function
};

// unary operation node
class Unary_Node : public Node {

  private:
    Node *child;                // the (single) child
    Unary_Func *f;              // the function of this node

  public:
    // constructor takes the parent and the function
    Unary_Node(Node *,Unary_Func *);
    ~Unary_Node(void);          // destructor will delete the child

    // adds a child node
    void set_child(Node *c) {child = c;};
    // accesses the child node
    Node *get_child(void) {return child;};
    // accesses the function
    Unary_Func *get_func(void) {return f;};

    // value function just passes the value of the child to f
    Val value(void);            // value function
    int count(void);            // counter function
    Node *find(int);            // finder function
    char *print(void);          // printer function
};
The value of these types of nodes is obtained by simply calling the operator with the values of each child. For example, the value function of the Binary_Node class:
// value function - pretty simple, just evaluate the function using the 
// left and right children's values
Val Binary_Node::value(void)
{
    // if the left or right does not exist, generate an error and return
    // zero
    if ((!left) || (!right)) {
        fprintf(stderr,"A binary node is missing a child!\n");
        return (Val)0;
    }

    // return it
    return (f->eval(left->value(),right->value()));
}
Terminal nodes may contain either constants or variables; these are represented by the Terminal_Const and Terminal_Var classes. These two subclasses are only slightly different:
// a constant value terminal node
class Terminal_Const : public Node {
    
  private:
    Val constant;               // the constant value

  public:
    // constructor takes the parent and value
    Terminal_Const(Node *, Val); 

    // the value function just needs to return the constant
    Val value(void) {return constant;}; 
    // counter function is just 1 for this node
    int count(void) {return 1;};
    Node *find(int);            // finder function
    char *print(void);          // printer function
};

// variable terminal node.  uses a Val ref for the value
class Terminal_Var : public Node {

  private:
    Variable *var;      // ref of the variable value

  public:
    // constructor takes parent and variable pointer
    Terminal_Var(Node *, Variable *); 

    // the value function just returns the current variable value
    Val value(void) {return *var->var;};
    // this returns the value pointer (for copying)
    Variable *val_p(void) {return var;};
    // counter function is just 1 for this node
    int count(void) {return 1;};
    Node *find(int);            // finder function
    char *print(void);          // printer function
};