Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/gp/build/Uniform.java @ 11194

Last change on this file since 11194 was 6152, checked in by bfarka, 14 years ago

added ecj and custom statistics to communicate with the okb services #1441

File size: 27.6 KB
Line 
1/*
2  Copyright 2006 by Sean Luke
3  Licensed under the Academic Free License version 3.0
4  See the file "LICENSE" for more information
5*/
6
7
8package ec.gp.build;
9import ec.gp.*;
10import java.util.*;
11import java.math.*;
12import ec.util.*;
13import ec.*;
14import java.io.*;
15
16/*
17 * Uniform.java
18 *
19 * Created Fri Jan 26 14:02:08 EST 2001
20 * By: Sean Luke
21 */
22
23/**
24   Uniform implements the algorithm described in
25
26   <p>Bohm, Walter and Andreas Geyer-Schulz. 1996. "Exact Uniform Initialization for Genetic Programming".  In <i>Foundations of Genetic Algorithms IV,</i> Richard Belew and Michael Vose, eds.  Morgan Kaufmann.  379-407. (ISBN 1-55860-460-X)
27
28   <p> The user-provided requested tree size is either provided directly to the Uniform algorithm, or if the size is NOSIZEGIVEN, then Uniform will pick one at random from the GPNodeBuilder probability distribution system (using either max-depth and min-depth, or using num-sizes). 
29
30   <p>Further, if the user sets the <tt>true-dist</tt> parameter, the Uniform will ignore the user's specified probability distribution and instead pick from a distribution between the minimum size and the maximum size the user specified, where the sizes are distributed according to the <i>actual</i> number of trees that can be created with that size.  Since many more trees of size 10 than size 3 can be created, for example, size 10 will be picked that much more often.
31
32   <p>Uniform also prints out the actual number of trees that exist for a given size, return type, and function set.  As if this were useful to you.  :-)
33
34   <p> The algorithm, which is quite complex, is described in pseudocode below.  Basically what the algorithm does is this:
35
36   <ol>
37   <li> For each function set and return type, determine the number of trees of each size which exist for that function set and tree type.  Also determine all the permutations of tree sizes among children of a given node.  All this can be done with dynamic programming.  Do this just once offline, after the function sets are loaded.
38   <li> Using these tables, construct distributions of choices of tree size, child tree size permutations, etc.
39   <li> When you need to create a tree, pick a size, then use the distriutions to recursively create the tree (top-down).
40   </ol>
41
42   <p> <b>Dealing with Zero Distributions</b>
43   <p> Some domains have NO tree of a certain size.  For example,
44   Artificial Ant's function set can make NO trees of size 2.
45   What happens when we're asked to make a tree of (invalid) size 2 in
46   Artificial Ant then?  Uniform presently handles it as follows:
47   <ol><li> If the system specifically requests a given size that's invalid, Uniform will
48   look for the next larger size which is valid.  If it can't find any,
49   it will then look for the next smaller size which is valid.
50   <li> If a random choice yields a given size that's invalid,
51   Uniform will pick again.
52   <li> If there is *no* valid size for a given return type, which probably indicates
53   an error, Uniform will halt and complain.
54   </ol>
55       
56   <h3>Pseudocode:</h3>
57
58   <pre>
59
60   *    Func NumTreesOfType(type,size)
61   *        If NUMTREESOFTYPE[type,size] not defined,       // memoize
62   *            N[type] = all nodes compatible with type
63   *            NUMTREESOFTYPE[type,size] = Sum(n in N[type], NumTreesRootedByNode(n,size))
64   *            return NUMTREESOFTYPE[type,size]
65   *
66   *    Func NumTreesRootedByNode(node,size)
67   *        If NUMTREESROOTEDBYNODE[node,size] not defined,   // memoize
68   *            count = 0
69   *            left = size - 1
70   *            If node.children.length = 0 and left = 0  // a valid terminal
71   *                count = 1
72   *            Else if node.children.length <= left  // a valid nonterminal
73   *                For s is 1 to left inclusive  // yeah, that allows some illegal stuff, it gets set to 0
74   *                    count += NumChildPermutations(node,s,left,0)
75   *            NUMTREESROOTEDBYNODE[node,size] = count
76   *        return NUMTREESROOTEBYNODE[node,size]
77   *
78   *
79   *    Func NumChildPermutations(parent,size,outof,pickchild)
80   *    // parent is our parent node
81   *    // size is the size of pickchild's tree that we're considering
82   *    // pickchild is the child we're considering
83   *    // outof is the total number of remaining nodes (including size) yet to fill
84   *        If NUMCHILDPERMUTATIONS[parent,size,outof,pickchild] is not defined,        // memoize
85   *            count = 0
86   *            if pickchild = parent.children.length - 1        and outof==size        // our last child, outof must be size
87   *                count = NumTreesOfType(parent.children[pickchild].type,size)
88   *            else if pickchild < parent.children.length - 1 and
89   *                                outof-size >= (parent.children.length - pickchild-1)    // maybe we can fill with terminals
90   *                cval = NumTreesOfType(parent.children[pickchild].type,size)
91   *                tot = 0
92   *                For s is 1 to outof-size // some illegal stuff, it gets set to 0
93   *                    tot += NumChildPermutations(parent,s,outof-size,pickchild+1)
94   *                count = cval * tot
95   *            NUMCHILDPERMUTATIONS [parent,size,outof,pickchild] = count           
96   *        return NUMCHILDPERMUTATIONS[parent,size,outof,pickchild]
97   *
98   *
99   *    For each type type, size size
100   *        ROOT_D[type,size] = probability distribution of nodes of type and size, derived from
101   *                            NUMTREESOFTYPE[type,size], our node list, and NUMTREESROOTEDBYNODE[node,size]
102   *
103   *    For each parent,outof,pickchild
104   *        CHILD_D[parent,outof,pickchild] = probability distribution of tree sizes, derived from
105   *                            NUMCHILDPERMUTATIONS[parent,size,outof,pickchild]
106   *
107   *    Func FillNodeWithChildren(parent,pickchild,outof)
108   *        If pickchild = parent.children.length - 1               // last child
109   *            Fill parent.children[pickchild] with CreateTreeOfType(parent.children[pickchild].type,outof)
110   *        Else choose size from CHILD_D[parent,outof,pickchild]
111   *            Fill parent.pickchildren[pickchild] with CreateTreeOfType(parent.children[pickchild].type,size)
112   *            FillNodeWithChildren(parent,pickchild+1,outof-size)
113   *        return
114   </pre>
115
116   Func CreateTreeOfType(type,size)
117   Choose node from ROOT_D[type,size]
118   If size > 1
119   FillNodeWithChildren(node,0,size-1)
120   return node
121
122
123   <p><b>Parameters</b><br>
124   <table>
125   <tr><td valign=top><i>base</i>.<tt>true-dist</tt><br>
126   <font size=-1>bool= true or false (default)</font></td>
127   <td valign=top>(should we use the true numbers of trees for each size as the distribution for picking trees, as opposed to the user-specified distribution?)</td></tr>
128   </table>
129
130   <p><b>Default Base</b><br>
131   gp.breed.uniform
132
133*/
134
135
136
137public class Uniform extends GPNodeBuilder
138    {
139    public static final String P_UNIFORM = "uniform";
140    public static final String P_TRUEDISTRIBUTION = "true-dist";
141   
142    public Parameter defaultBase()
143        {
144        return GPBuildDefaults.base().push(P_UNIFORM);
145        }
146
147    // Mapping of integers to function sets
148    public GPFunctionSet[] functionsets;
149   
150    // Mapping of function sets to Integers
151    public Hashtable _functionsets;
152   
153    // Mapping of GPNodes to Integers (thus to ints)
154    public Hashtable funcnodes;
155   
156    // number of nodes
157    public int numfuncnodes;
158   
159    // max arity of any node
160    public int maxarity;
161   
162    // maximum size of nodes computed
163    public int maxtreesize;
164   
165    // true size distributions
166    public BigInteger[/*functionset*/][/*type*/][/*size*/] _truesizes;
167    public double[/*functionset*/][/*type*/][/*size*/] truesizes;
168   
169    // do we use the true distributions to pick tree sizes?
170    public boolean useTrueDistribution;
171   
172    // Sun in its infinite wisdom (what idiots) decided to make
173    // BigInteger IMMUTABLE.  There is a MutableBigInteger, but it's not
174    // public!  And Sun only caches the first 16 positive and 16 negative
175    // integer constants, not exactly that useful for us.  As a result, we'll
176    // be making a dang lot of BigIntegers here.  Garbage-collection hell.  :-(
177    // ...well, it's not all that slow really.
178    public BigInteger NUMTREESOFTYPE[/*FunctionSet*/][/*type*/][/*size*/];
179    public BigInteger NUMTREESROOTEDBYNODE[/*FunctionSet*/][/*nodenum*/][/*size*/];
180    public BigInteger NUMCHILDPERMUTATIONS[/*FunctionSet*/][/*parentnodenum*/][/*size*/][/*outof*/][/*pickchild*/];
181   
182   
183   
184    // tables derived from the previous ones through some massaging
185   
186    // [/*the nodes*/] is an array of <node,probability> pairs for all possible nodes rooting
187    // trees of the desired size and compatible with the given return type.  It says that if you
188    // were to pick a tree, this would be the probability that this node would be the root of it.
189    public UniformGPNodeStorage ROOT_D[/*FunctionSet*/][/*type*/][/*size*/][/*the nodes*/];
190   
191    // True if ROOT_D all zero for all possible nodes in [/*the nodes*/] above.
192    public boolean ROOT_D_ZERO[/*FunctionSet*/][/*type*/][/*size*/];
193   
194    public double CHILD_D[/*FunctionSet*/][/*type*/][/*outof*/][/*pickchild*/][/* the nodes*/];
195   
196   
197    public void setup(final EvolutionState state, final Parameter base)
198        {
199        super.setup(state,base);
200       
201        Parameter def = defaultBase();
202       
203        // use true distributions? false is default
204        useTrueDistribution = state.parameters.getBoolean(
205            base.push(P_TRUEDISTRIBUTION), def.push(P_TRUEDISTRIBUTION),false);
206       
207        if (minSize>0)  // we're using maxSize and minSize
208            maxtreesize=maxSize;
209        else if (sizeDistribution != null)
210            maxtreesize = sizeDistribution.length;
211        else state.output.fatal("Uniform is used for the GP node builder, but no distribution was specified." +
212            "  You must specify either a min/max size, or a full size distribution.",
213            base.push(P_MINSIZE), def.push(P_MINSIZE));
214        // preprocess offline
215        preprocess(state,maxtreesize);
216        }
217       
218    public int pickSize(final EvolutionState state, final int thread,
219        final int functionset, final int type)
220        {
221        if (useTrueDistribution)
222            return RandomChoice.pickFromDistribution(
223                truesizes[functionset][type],state.random[thread].nextDouble());
224        else return super.pickSize(state,thread);
225        }
226   
227    public void preprocess(final EvolutionState state, final int _maxtreesize)
228        {
229        state.output.message("Determining Tree Sizes");
230       
231        maxtreesize = _maxtreesize;
232       
233        Hashtable functionSetRepository = ((GPInitializer)state.initializer).functionSetRepository;
234       
235        // Put each function set into the arrays
236        functionsets = new GPFunctionSet[functionSetRepository.size()];
237        _functionsets = new Hashtable();
238        Enumeration e = functionSetRepository.elements();
239        int count=0;
240        while(e.hasMoreElements())
241            {
242            GPFunctionSet set = (GPFunctionSet)(e.nextElement());
243            _functionsets.put(set,new Integer(count));
244            functionsets[count++] = set;
245            }
246       
247        // For each function set, assign each GPNode to a unique integer
248        // so we can keep track of it (ick, this will be inefficient!)
249        funcnodes = new Hashtable();
250        Hashtable t_nodes = new Hashtable();
251        count = 0;
252        maxarity=0;
253        GPNode n;
254        for(int x=0;x<functionsets.length;x++)
255            {
256            // hash all the nodes so we can remove duplicates
257            for(int typ=0;typ<functionsets[x].nodes.length;typ++)
258                for(int nod=0;nod<functionsets[x].nodes[typ].length;nod++)
259                    t_nodes.put(n=functionsets[x].nodes[typ][nod],n);
260            // rehash with Integers, yuck
261            e = t_nodes.elements();
262            GPNode tmpn;
263            while(e.hasMoreElements())
264                {
265                tmpn = (GPNode)(e.nextElement());
266                if (maxarity < tmpn.children.length)
267                    maxarity = tmpn.children.length;
268                if (!funcnodes.containsKey(tmpn))  // don't remap the node; it'd make holes
269                    funcnodes.put(tmpn,new Integer(count++));
270                }
271            }
272       
273        numfuncnodes = funcnodes.size();
274       
275        GPInitializer initializer = ((GPInitializer)state.initializer);
276        int numAtomicTypes = initializer.numAtomicTypes;
277        int numSetTypes = initializer.numSetTypes;
278       
279        // set up the arrays
280        NUMTREESOFTYPE = new BigInteger[functionsets.length][numAtomicTypes+numSetTypes][maxtreesize+1];
281        NUMTREESROOTEDBYNODE = new BigInteger[functionsets.length][numfuncnodes][maxtreesize+1];
282        NUMCHILDPERMUTATIONS = new BigInteger[functionsets.length][numfuncnodes][maxtreesize+1][maxtreesize+1][maxarity];
283        ROOT_D = new UniformGPNodeStorage[functionsets.length][numAtomicTypes+numSetTypes][maxtreesize+1][];
284        ROOT_D_ZERO = new boolean[functionsets.length][numAtomicTypes+numSetTypes][maxtreesize+1];
285        CHILD_D = new double[functionsets.length][numfuncnodes][maxtreesize+1][maxtreesize+1][];
286
287        GPType[] types = ((GPInitializer)(state.initializer)).types;
288        // Go through each function set and determine numbers
289        // (this will take quite a while!  Thankfully it's offline)
290        _truesizes = new BigInteger[functionsets.length][numAtomicTypes+numSetTypes][maxtreesize+1];
291        for(int x=0;x<functionsets.length;x++)
292            for(int y=0;y<numAtomicTypes+numSetTypes;y++)
293                for(int z=1;z<=maxtreesize;z++)
294                    state.output.message("FunctionSet: " + functionsets[x].name + ", Type: " + types[y].name + ", Size: " + z + " num: " +
295                        (_truesizes[x][y][z] = numTreesOfType(initializer,x,y,z)));
296
297        state.output.message("Compiling Distributions");
298
299        // convert to doubles and organize distribution
300        truesizes = new double[functionsets.length][numAtomicTypes+numSetTypes][maxtreesize+1];
301        for(int x=0;x<functionsets.length;x++)
302            for(int y=0;y<numAtomicTypes+numSetTypes;y++)
303                {
304                for(int z=1;z<=maxtreesize;z++)
305                    truesizes[x][y][z] = _truesizes[x][y][z].doubleValue();
306                // and if this is all zero (a possibility) we should be forgiving (hence the 'true') -- I *think*
307                RandomChoice.organizeDistribution(truesizes[x][y],true);
308                }
309       
310        // compute our percentages
311        computePercentages();
312        }
313   
314    // hopefully this will get inlined
315    public final int intForNode(GPNode node)
316        {
317        return ((Integer)(funcnodes.get(node))).intValue();
318        }
319   
320   
321    public BigInteger numTreesOfType(final GPInitializer initializer,
322        final int functionset, final int type, final int size)
323        {
324        if (NUMTREESOFTYPE[functionset][type][size]==null)
325            {
326            GPNode[] nodes = functionsets[functionset].nodes[type];
327            BigInteger count = BigInteger.valueOf(0);
328            for(int x=0;x<nodes.length;x++)
329                count = count.add(numTreesRootedByNode(initializer,functionset,nodes[x],size));
330            NUMTREESOFTYPE[functionset][type][size] = count;
331            }
332        return NUMTREESOFTYPE[functionset][type][size];
333        }
334   
335    public BigInteger numTreesRootedByNode(final GPInitializer initializer,
336        final int functionset, final GPNode node, final int size)
337        {
338        if (NUMTREESROOTEDBYNODE[functionset][intForNode(node)][size]==null)
339            {
340            BigInteger one = BigInteger.valueOf(1);
341            BigInteger count = BigInteger.valueOf(0);
342            int outof = size-1;
343            if (node.children.length == 0 && outof == 0) // a valid terminal
344                count = one;
345            else if (node.children.length <= outof)  // a valid nonterminal
346                for (int s=1;s<=outof;s++)
347                    count = count.add(numChildPermutations(initializer,functionset,node,s,outof,0));
348            //System.out.println("Node: " + node + " Size: " + size + " Count: " +count);
349            NUMTREESROOTEDBYNODE[functionset][intForNode(node)][size] = count;
350            }
351        return NUMTREESROOTEDBYNODE[functionset][intForNode(node)][size];
352        }
353   
354    public BigInteger numChildPermutations( final GPInitializer initializer,
355        final int functionset, final GPNode parent, final int size,
356        final int outof, final int pickchild)
357        {
358        if (NUMCHILDPERMUTATIONS[functionset][intForNode(parent)][size][outof][pickchild]==null)
359            {
360            BigInteger count = BigInteger.valueOf(0);
361            if (pickchild == parent.children.length - 1 && size==outof)
362                count = numTreesOfType(initializer,functionset,parent.constraints(initializer).childtypes[pickchild].type,size);
363            else if (pickchild < parent.children.length - 1 &&
364                outof-size >= (parent.children.length - pickchild-1))
365                {
366                BigInteger cval = numTreesOfType(initializer,functionset,parent.constraints(initializer).childtypes[pickchild].type,size);
367                BigInteger tot = BigInteger.valueOf(0);
368                for (int s=1; s<=outof-size; s++)
369                    tot = tot.add(numChildPermutations(initializer,functionset,parent,s,outof-size,pickchild+1));
370                count = cval.multiply(tot);
371                }
372            // System.out.println("Parent: " + parent + " Size: " + size + " OutOf: " + outof +
373            //       " PickChild: " + pickchild + " Count: " +count);
374            NUMCHILDPERMUTATIONS[functionset][intForNode(parent)][size][outof][pickchild] = count;
375            }
376        return NUMCHILDPERMUTATIONS[functionset][intForNode(parent)][size][outof][pickchild];
377        }
378   
379    private final double getProb(final BigInteger i)
380        {
381        if (i==null) return 0.0f;
382        else return i.doubleValue();
383        }
384       
385    public void computePercentages()
386        {
387        // load ROOT_D
388        for(int f = 0;f<NUMTREESOFTYPE.length;f++)
389            for(int t=0;t<NUMTREESOFTYPE[f].length;t++)
390                for(int s=0;s<NUMTREESOFTYPE[f][t].length;s++)
391                    {
392                    ROOT_D[f][t][s] = new UniformGPNodeStorage[functionsets[f].nodes[t].length];
393                    for(int x=0;x<ROOT_D[f][t][s].length;x++)
394                        {
395                        ROOT_D[f][t][s][x] = new UniformGPNodeStorage();
396                        ROOT_D[f][t][s][x].node = functionsets[f].nodes[t][x];
397                        ROOT_D[f][t][s][x].prob = getProb(NUMTREESROOTEDBYNODE[f][intForNode(ROOT_D[f][t][s][x].node)][s]);
398                        }
399                    // organize the distribution
400                    //System.out.println("Organizing " + f + " " + t + " " + s);
401                    // check to see if it's all zeros
402                    for(int x=0;x<ROOT_D[f][t][s].length;x++)
403                        if (ROOT_D[f][t][s][x].prob != 0.0)
404                            {
405                            // don't need to check for negatives here I believe
406                            RandomChoice.organizeDistribution(ROOT_D[f][t][s],ROOT_D[f][t][s][0]);
407                            ROOT_D_ZERO[f][t][s] = false;
408                            break;
409                            }
410                        else
411                            {
412                            ROOT_D_ZERO[f][t][s] = true;
413                            }
414                    }
415
416        // load CHILD_D
417        for(int f = 0;f<NUMCHILDPERMUTATIONS.length;f++)
418            for(int p=0;p<NUMCHILDPERMUTATIONS[f].length;p++)
419                for(int o=0;o<maxtreesize+1;o++)
420                    for(int c=0;c<maxarity;c++)
421                        {
422                        CHILD_D[f][p][o][c] = new double[o+1];
423                        for(int s=0;s<CHILD_D[f][p][o][c].length;s++)
424                            CHILD_D[f][p][o][c][s] = getProb(NUMCHILDPERMUTATIONS[f][p][s][o][c]);
425                        // organize the distribution
426                        //System.out.println("Organizing " + f + " " + p + " " + o + " " + c);
427                        // check to see if it's all zeros
428                        for(int x=0;x<CHILD_D[f][p][o][c].length;x++)
429                            if (CHILD_D[f][p][o][c][x] != 0.0)
430                                {
431                                // don't need to check for negatives here I believe
432                                RandomChoice.organizeDistribution(CHILD_D[f][p][o][c]);
433                                break;
434                                }
435                        }
436        }
437       
438    GPNode createTreeOfType(final EvolutionState state, final int thread, final GPInitializer initializer,
439        final int functionset, final int type, final int size, final MersenneTwisterFast mt)
440       
441        {
442        //System.out.println("" + functionset + " " + type + " " + size);
443        int choice = RandomChoice.pickFromDistribution(
444            ROOT_D[functionset][type][size],ROOT_D[functionset][type][size][0],
445            mt.nextDouble());
446        GPNode node = (GPNode)(ROOT_D[functionset][type][size][choice].node.lightClone());
447        node.resetNode(state,thread);  // give ERCs a chance to randomize
448        //System.out.println("Size: " + size + "Rooted: " + node);
449        if (node.children.length == 0 && size !=1) // uh oh
450            {
451            System.out.println("Size: " + size + " Node: " + node);
452            for(int x=0;x<ROOT_D[functionset][type][size].length;x++)
453                System.out.println("" + x + (GPNode)(ROOT_D[functionset][type][size][x].node) + " " + ROOT_D[functionset][type][size][x].prob );
454            }
455        if (size > 1)  // nonterminal
456            fillNodeWithChildren(state,thread,initializer,functionset,node,ROOT_D[functionset][type][size][choice].node,0,size-1,mt);
457        return node;
458        }
459       
460    void fillNodeWithChildren(final EvolutionState state, final int thread, final GPInitializer initializer,
461        final int functionset, final GPNode parent, final GPNode parentc,
462        final int pickchild, final int outof, final MersenneTwisterFast mt)
463       
464        {
465        if (pickchild == parent.children.length - 1)
466            {
467            parent.children[pickchild] =
468                createTreeOfType(state,thread,initializer,functionset,parent.constraints(initializer).childtypes[pickchild].type,outof, mt);
469            }
470        else
471            {
472            int size = RandomChoice.pickFromDistribution(
473                CHILD_D[functionset][intForNode(parentc)][outof][pickchild],
474                mt.nextDouble());
475            parent.children[pickchild] =
476                createTreeOfType(state,thread,initializer,functionset,parent.constraints(initializer).childtypes[pickchild].type,size,mt);
477            fillNodeWithChildren(state,thread,initializer,functionset,parent,parentc,pickchild+1,outof-size,mt);
478            }
479        parent.children[pickchild].parent = parent;
480        parent.children[pickchild].argposition = (byte)pickchild;           
481        }
482       
483
484    public GPNode newRootedTree(final EvolutionState state,
485        final GPType type,
486        final int thread,
487        final GPNodeParent parent,
488        final GPFunctionSet set,
489        final int argposition,
490        final int requestedSize)
491        {
492        GPInitializer initializer = ((GPInitializer)state.initializer);
493       
494        if (requestedSize == NOSIZEGIVEN)  // pick from the distribution
495            {
496            final int BOUNDARY = 20;  // if we try 20 times and fail, check to see if it's possible to succeed
497            int bound=0;
498               
499            int fset = ((Integer)(_functionsets.get(set))).intValue();
500            int siz = pickSize(state,thread,fset,type.type);
501            int typ = type.type;
502           
503            // this code is confusing.  The idea is:
504            // if the number of trees of our arbitrarily-picked size is zero, we try BOUNDARY
505            // number of times to find a tree which will work, picking new sizes each
506            // time.  If we still haven't found anything, we will continue to search
507            // for a working tree only if we know for sure that one exists in the distribution.
508           
509            boolean checked = false;
510            while(ROOT_D_ZERO[fset][typ][siz])
511                {
512                if (++bound == BOUNDARY)
513                    {
514                    check:
515                    if (!checked)
516                        {
517                        checked = true;
518                        for(int x=0;x<ROOT_D_ZERO[fset][typ].length;x++)
519                            if (!ROOT_D_ZERO[fset][typ][x])
520                                break check;  // found a non-zero
521                        // uh oh, we're all zeroes
522                        state.output.fatal("ec.gp.build.Uniform was asked to build a tree with functionset " + set + " rooted with type " + type + ", but cannot because for some reason there are no trees of any valid size (within the specified size range) which exist for this function set and type.");       
523                        }   
524                    }
525                siz = pickSize(state,thread,fset,typ);
526                }
527                   
528            // okay, now we have a valid size.
529            GPNode n = createTreeOfType(state,thread,initializer,fset,typ,siz,state.random[thread]);
530            n.parent = parent;
531            n.argposition = (byte)argposition;
532            return n;
533            }
534        else if (requestedSize<1)
535            {
536            state.output.fatal("ec.gp.build.Uniform requested to build a tree, but a requested size was given that is < 1.");
537            return null;  // never happens
538            }
539        else
540            {
541            int fset = ((Integer)(_functionsets.get(set))).intValue();
542            int typ = type.type;
543            int siz = requestedSize;
544           
545            // if the number of trees of the requested size is zero, we first march up until we
546            // find a tree size with non-zero numbers of trees.  Failing that, we march down to
547            // find one.  If that still fails, we issue an error.  Otherwise we use the size
548            // we discovered.
549           
550            determineSize:
551            if (ROOT_D_ZERO[fset][typ][siz])
552                {
553                // march up
554                for(int x=siz+1;x<ROOT_D_ZERO[fset][typ].length;x++)
555                    if (ROOT_D_ZERO[fset][typ][siz])
556                        { siz=x; break determineSize; }
557                // march down
558                for(int x=siz-1;x>=0;x--)
559                    if (ROOT_D_ZERO[fset][typ][siz])
560                        { siz=x; break determineSize; }
561                // issue an error
562                state.output.fatal("ec.gp.build.Uniform was asked to build a tree with functionset " + set + " rooted with type " + type + ", and of size " + requestedSize + ", but cannot because for some reason there are no trees of any valid size (within the specified size range) which exist for this function set and type.");
563                }
564               
565            GPNode n = createTreeOfType(state,thread,initializer,fset,typ,siz,state.random[thread]);
566            n.parent = parent;
567            n.argposition = (byte)argposition;
568            return n;
569            }
570        }
571       
572    }
573   
574   
575class UniformGPNodeStorage implements RandomChoiceChooserD, Serializable
576    {
577    public GPNode node;
578    public double prob;
579    public double getProbability(final Object obj)
580        { return (((UniformGPNodeStorage)obj).prob); }
581    public void setProbability(final Object obj, final double _prob)
582        { ((UniformGPNodeStorage)obj).prob = _prob; }
583    }
584
585   
586   
587   
588   
589   
590   
591
592   
593   
594   
595   
596   
597   
598   
599   
Note: See TracBrowser for help on using the repository browser.