thanks for your fast response. Well, yeah I'd need the GPTree because I want to check if I can get a better result with optimizing a manually defined rule, rather than creating them from scratch and then optimizing. So I'd need to put the manually defined rules into my population of my GPIndividuum.
I've written an interpreter which creates a rule from a GPTree, but now I need it backwards and put the result into my population for optimization, so that even my automatically created rules are mixed with my manually written one.
Are there further things to do?
----- Ursprüngliche Mail -----
Von: "Sean Luke" <[log in to unmask]>
An: [log in to unmask]
Gesendet: Dienstag, 9. Juli 2013 11:27:51
Betreff: Re: Building a GPTree manually
On Jul 9, 2013, at 4:14 AM, Bojan Janisch wrote:
> what do I have to do, to build a complete GPTree and use it for evaluation?
> Background is that I have now successfully created my first rules from a GPTree.
> But I want to know if the results would be better if I use a rule that I manually
> wrote, as a GPIndividuum in my population.
If you just want to build a GPTree manually, you just need to allocate various GPNodes and hang them together. I'll presume you don't care about making a new GPIndividual, just constructing a GPTree and evaluating it.
To allocate GPNodes you might need your function set. Let's say that your GPTree was intended to fit into tree slot s of your GPIndividual (in most cases you just have one tree per individual, so s=0). You might do:
final EvolutionState state = ...
final Subpopulation subpop = ...
final GPInitializer init = (GPInitializer)(state.initializer);
final GPSpecies gps = (GPSpecies)(subpop.species);
final GPIndividual indproto = ((GPIndividual)(gps.i_prototype));
final GPTree gptproto = indproto.trees;
final GPTreeConstraints gptc = gptproto.constraints(init);
final GPFunctionSet gpfs = gptc.functionset;
Okay, now you have your function set. See GPFunctionSet to extract specific GPNodes. For example, you can make a node whose name is "+" like this:
GPNode plus = (GPNode)(gpfs.nodesByName.get("+").clone()); // ALWAYS clone
A GPNode has three critical variables that you will need to set.
public GPNodeParent parent;
public GPNode children;
public byte argposition;
Parent points to the parent GPNode of the node, or to a GPTree if the node is the root. You probably don't need to attach to a tree if you're just evaluating the tree, just let that value be null.
children is an array of the children nodes to the node. children can be null, or can be zero length, if the node is a leaf.
argposition is the index in the parent's children array in which this node is found. It says "I'm child number 4 of my parent", for example.
Let's say we're trying to create the tree: (+ (cos x) x)
I'd do this:
GPNode plus = (GPNode)(gpfs.nodesByName.get("+").clone());
GPNode cos = (GPNode)(gpfs.nodesByName.get("cos").clone());
GPNode x_one = (GPNode)(gpfs.nodesByName.get("+").clone());
GPNode x_two = (GPNode)(gpfs.nodesByName.get("+").clone());
plus.parent = null; // no GPTree :-(
plus.argposition = 0;
plus.children = cos;
plus.children = x_one;
cos.parent = plus;
cos.argposition = 0;
cos.children = x_two;
x_one.parent = plus;
x_one.argposition = 1;
x_one.children = null; // it's probably already null anyway
x_two.parent = cos;
x_two.argposition = 0;
x_two.children = null; // it's probably null already
Now you're ready to evaluate the node.
GPProblem prob = ...
GPData gpd = ...
int threadnum = ...
GPIndividual ind = null; // our GPNodes don't need the individual to evaluate
plus.eval(state, threadnum, gpd, new ADFStack(), ind, prob);
If you need the GPTree or the GPIndividual constructed as well, then there's a bit more to that.