Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/gp/build/PTC1.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: 8.1 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.*;
10import ec.gp.*;
11import ec.util.*;
12
13/*
14 * PTC1.java
15 *
16 * Created: Tue Jan 25 21:36:02 2000
17 * By: Sean Luke
18 */
19
20/**
21 * PTC1 implements the "Strongly-typed Probabilistic Tree Creation 1 (PTC1)" algorithm described in
22 *
23 * <p>Luke, Sean. 2000. <i>Issues in Scaling Genetic Programming: Breeding Strategies, Tree Generation, and Code Bloat.</i> Ph.D. Dissertation, Department of Computer Science, University of Maryland, College Park, Maryland.
24 *
25 * <p> ...and also in
26 *
27 * <p>Luke, Sean. 2000. Two fast tree-creation algorithms for genetic programming. In <i>IEEE Transactions on Evolutionary Computation</i> 4:3 (September 2000), 274-283. IEEE.
28 *
29 * <p> Both can be found at <a href="http://www.cs.gmu.edu/~sean/papers/">http://www.cs.gmu.edu/~sean/papers/</a>
30 *
31 * <p> PTC1 requires that your function set to implement PTCFunctionSetForm.  The
32 * provided function set, PTCFunctionSet, does exactly this.
33 *
34 * <p>The Strongly-typed PTC1 algorithm is a derivative of the GROW algorithm
35 * used in ec.gp.koza.GrowBuilder.  The primary differences are:
36 *
37 <ul>
38 <li> PTC1 guarantees that trees generated will have an <i>expected</i> (mean) tree size, provided by the user.  There is no guarantee on variance.  This is different from GROW, which doesn't give any user control at all.
39 <li> PTC1 does not have a min-depth value.  In essence, PTC1's min-depth value is always set to 1.
40 <li> PTC1's max-depth value should really only be used to enforce a large memory restriction.  Unlike GROW, where it's used to keep GROW from going nuts.
41 <li> PTC1 has provisions for picking nonterminals with various probabilities over other nonterminals (and likewise for terminals).  To use this, tweak the PTCFunctionSetForm object.
42 </ul>
43 *
44 * PTC1 assumes that the requested size passed to newRootedTree(...) is the <i>expected</i> size.   If the value is NOSIZEGIVEN, then PTC1 will use the expected size defined by the <tt>expected-size</tt> parameter.
45
46 <p><b>Parameters</b><br>
47 <table>
48 <tr><td valign=top><i>base</i>.<tt>expected-size</tt><br>
49 <font size=-1>int &gt;= 1</font></td>
50 <td valign=top>default expected tree size</td></tr>
51 <tr><td valign=top><i>base</i>.<tt>max-depth</tt><br>
52 <font size=-1>int &gt;= 1</font></td>
53 <td valign=top>maximum allowable tree depth (usually a big value)</td></tr>
54 </table>
55
56 <p><b>Default Base</b><br>
57 gp.build.ptc1
58
59
60 * @author Sean Luke
61 * @version 1.0
62 */
63
64public class PTC1 extends GPNodeBuilder
65    {
66    public static final String P_PTC1 = "ptc1";
67    public static final String P_EXPECTED = "expected-size";
68    public static final String P_MAXDEPTH = "max-depth";
69
70    /** The largest maximum tree depth PTC1 can specify -- should be big. */
71    public int maxDepth;
72
73    /** The default expected tree size for PTC1 */
74    public int expectedSize;
75
76    public Parameter defaultBase()
77        {
78        return GPBuildDefaults.base().push(P_PTC1);
79        }
80
81    public void setup(final EvolutionState state, final Parameter base)
82        {
83        super.setup(state,base);
84
85        Parameter def = defaultBase();
86
87        expectedSize = state.parameters.getInt(base.push(P_EXPECTED),
88            def.push(P_EXPECTED),1);
89        if (expectedSize < 1)
90            state.output.fatal("Default expected size must be >= 1",
91                base.push(P_EXPECTED),
92                def.push(P_EXPECTED));
93
94        maxDepth = state.parameters.getInt(base.push(P_MAXDEPTH),
95            def.push(P_MAXDEPTH),1);
96        if (maxDepth < 1)
97            state.output.fatal("Maximum depth must be >= 1",
98                base.push(P_MAXDEPTH),
99                def.push(P_MAXDEPTH));
100       
101        }
102
103
104    public GPNode newRootedTree(final EvolutionState state,
105        final GPType type,
106        final int thread,
107        final GPNodeParent parent,
108        final GPFunctionSet set,
109        final int argposition,
110        final int requestedSize)
111        {
112        if (!(set instanceof PTCFunctionSetForm))
113            state.output.fatal("Set " + set.name + " is not of the form ec.gp.build.PTCFunctionSetForm, and so cannot be used with PTC Nodebuilders.");
114
115        // build the tree
116        if (requestedSize == NOSIZEGIVEN)  // use the default
117            {
118            return ptc1(state,0,type,thread,parent,argposition,
119                set,(PTCFunctionSetForm)set,
120                ((PTCFunctionSetForm)set).nonterminalSelectionProbabilities(expectedSize));
121            }
122        if (requestedSize < 1)
123            state.output.fatal("etc.gp.build.PTC1 was requested to build a tree, but a requested size was given that is < 1.");
124        return ptc1(state,0,type,thread,parent,argposition,
125            set,(PTCFunctionSetForm)set,
126            ((PTCFunctionSetForm)set).nonterminalSelectionProbabilities(requestedSize));
127        }
128
129   
130
131    /** A private function which recursively returns a GROW tree to newRootedTree(...) */
132    private GPNode ptc1(final EvolutionState state,
133        final int current,
134        final GPType type,
135        final int thread,
136        final GPNodeParent parent,
137        final int argposition,
138        final GPFunctionSet set,
139        final PTCFunctionSetForm pset, // same as set
140        final float[] nonterminalSelectionProbabilities)
141       
142        {
143        // ptc1 can mess up if there are no available terminals for a given type.  If this occurs,
144        // and we find ourselves unable to pick a terminal when we want to do so, we will issue a warning,
145        // and pick a nonterminal, violating the PTC1 size and depth contracts.  This can lead to pathological situations
146        // where the system will continue to go on and on unable to stop because it can't pick a terminal,
147        // resulting in running out of memory or some such.  But there are cases where we'd want to let
148        // this work itself out.
149        boolean triedTerminals = false;
150               
151        int t = type.type;
152        GPNode[] terminals = set.terminals[t];
153        GPNode[] nonterminals = set.nonterminals[t];
154        GPNode[] nodes = set.nodes[t];         
155
156        if (nodes.length == 0)
157            errorAboutNoNodeWithType(type, state);   // total failure
158
159        if ((  (current+1 >= maxDepth) ||                                                    // Now pick if we're at max depth
160                !(state.random[thread].nextBoolean(nonterminalSelectionProbabilities[t])) ||  // OR if we're below p_y
161                warnAboutNonterminal(nonterminals.length==0, type, false, state)) &&         // OR if there are NO nonterminals!
162            (triedTerminals = true) &&                                                       // [first set triedTerminals]
163            terminals.length != 0)                                                           // AND if there are available terminals
164            {
165            GPNode n = (GPNode)
166                terminals[RandomChoice.pickFromDistribution(
167                    pset.terminalProbabilities(t),
168                    state.random[thread].nextFloat())].lightClone();
169            n.resetNode(state,thread);  // give ERCs a chance to randomize
170            n.argposition = (byte)argposition;
171            n.parent = parent;
172            return n;
173            }
174        else  // above p_y, pick a nonterminal by q_ny probabilities
175            {
176            if (triedTerminals) warnAboutNoTerminalWithType(type, false, state);        // we tried terminals and we're here because there were none!
177
178            GPNode n = (GPNode)
179                nonterminals[RandomChoice.pickFromDistribution(
180                    pset.nonterminalProbabilities(t),
181                    state.random[thread].nextFloat())].lightClone();
182            n.resetNode(state,thread);  // give ERCs a chance to randomize
183            n.argposition = (byte)argposition;
184            n.parent = parent;
185
186            // Populate the node...
187            GPType[] childtypes = n.constraints(((GPInitializer)state.initializer)).childtypes;
188            for(int x=0;x<childtypes.length;x++)
189                n.children[x] = ptc1(state,current+1,childtypes[x],thread,n,x,set,pset,nonterminalSelectionProbabilities);
190            return n;       
191            }
192        }
193    }
Note: See TracBrowser for help on using the repository browser.