Print

Print


Hello,

I'm new to GP and am using this great tool that is ECJ. I have a question
regarding terminals (functions with arity 0).

I'm programming the AI for the game Connect4 aka 4-in-a-row.

As functions I have things like "or", "and", "if" and "not" together with
other functions like "hasThreeInARow" etc. Maybe I'll add a few more later
when the need arises. The thing is, the first set of functions works on
booleans but should return values after evaluation. For example this could
be a small part of an individual:
if ( hasThreeInARow ) then X
else Y

with X and Y a tree on its own. Depending whether "hasThreeInARow" is true
or not the ValueData.bool is true or not and this influences the value for
ValueData.value. ValueData is my GPData class (see below).


-->Is it OK for me to keep two variables in my GPData class? Here's my
GPData class:
public class ValueData extends GPData
    {
    public double value;    // return value
    public boolean bool; // testing value

    public GPData copyTo(final GPData gpd)   // copy my stuff to another
ValueData
        { ((ValueData)gpd).value = value; ((ValueData)gpd).bool = bool;
return gpd; }
    }


-->Now I'll give an example of a function (if):
public class If extends GPNode
    {
    public String toString() { return "if3"; }

    public void checkConstraints(final EvolutionState state,
                                 final int tree,
                                 final GPIndividual typicalIndividual,
                                 final Parameter individualBase)
        {
        super.checkConstraints(state,tree,typicalIndividual,individualBase);
        if (children.length!=3)
            state.output.error("Incorrect number of children for node " + 
                               toStringForError() + " at " +
                               individualBase);
        }

    public void eval(final EvolutionState state,
                     final int thread,
                     final GPData input,
                     final ADFStack stack,
                     final GPIndividual individual,
                     final Problem problem)
        {
     ValueData bd = ((ValueData)(input));
     
     boolean result = bd.bool;
     
        children[0].eval(state,thread,input,stack,individual,problem);
        if(result){
         children[1].eval(state,thread,input,stack,individual,problem);
        } else children[2].eval(state,thread,input,stack,individual,problem);
         
        }
    }


-->I'll give a second example (and):
public class And extends GPNode
    {
    public String toString() { return "and"; }

    public void checkConstraints(final EvolutionState state,
                                 final int tree,
                                 final GPIndividual typicalIndividual,
                                 final Parameter individualBase)
        {
        super.checkConstraints(state,tree,typicalIndividual,individualBase);
        if (children.length!=2)
            state.output.error("Incorrect number of children for node " + 
                               toStringForError() + " at " +
                               individualBase);
        }

    public void eval(final EvolutionState state,
                     final int thread,
                     final GPData input,
                     final ADFStack stack,
                     final GPIndividual individual,
                     final Problem problem)
        {
     ValueData bd = ((ValueData)(input));
        children[0].eval(state,thread,input,stack,individual,problem);
        
        boolean bool_result = bd.bool;
        double value_result = bd.value;
        
        children[1].eval(state,thread,input,stack,individual,problem);
        bd.bool = bd.bool && bool_result;
        if(bd.bool) bd.value = bd.value + value_result;
        else bd.value = 0;
        }
    }


Sorry for the long post. I'll summarize everything:
-Is it OK to keep and work with 2 different types of variables inside a
single GPData class?
-Do I understand it well that I can use the ValueData.bool as a test and I
can use ValueData.value as the result?


I hope everything is clear. It's not easy to explain my problem though.