Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/gp/breed/MutatePromotePipeline.java @ 12912

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

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

File size: 8.9 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.breed;
9import ec.*;
10import ec.util.*;
11import ec.gp.*;
12
13/*
14 * MutatePromotePipeline.java
15 *
16 * Created: Wed Dec 15 21:41:30 1999
17 * By: Sean Luke
18 */
19
20/**
21 * MutatePromotePipeline works very similarly to the PromoteNode algorithm
22 * described in  Kumar Chellapilla,
23 * "A Preliminary Investigation into Evolving Modular Programs without Subtree
24 * Crossover", GP98, and is also similar to the "deletion" operator found in
25 * Una-May O'Reilly's thesis,
26 * <a href="http://www.ai.mit.edu/people/unamay/thesis.html">
27 * "An Analysis of Genetic Programming"</a>.
28 *
29 * <p>MutatePromotePipeline tries <i>tries</i> times to find a tree
30 * that has at least one promotable node.  It then picks randomly from
31 * all the promotable nodes in the tree, and promotes one.  If it cannot
32 * find a valid tree in <i>tries</i> times, it gives up and simply
33 * copies the individual.
34 *
35 * <p>"Promotion" means to take a node <i>n</i> whose parent is <i>m</i>,
36 * and replacing the subtree rooted at <i>m</i> with the subtree rooted at <i>n</i>.
37 *
38 * <p>A "Promotable" node means a node which is capable of promotion
39 * given the existing type constraints.  In general to promote a node <i>foo</i>,
40 * <i>foo</i> must have a parent node, and must be type-compatible with the
41 * child slot that its parent fills.
42 *
43
44 <p><b>Typical Number of Individuals Produced Per <tt>produce(...)</tt> call</b><br>
45 ...as many as the source produces
46
47 <p><b>Number of Sources</b><br>
48 1
49
50 <p><b>Parameters</b><br>
51 <table>
52 <tr><td valign=top><i>base</i>.<tt>tries</tt><br>
53 <font size=-1>int &gt;= 1</font></td>
54 <td valign=top>(number of times to try finding valid pairs of nodes)</td></tr>
55
56 <tr><td valign=top><i>base</i>.<tt>tree.0</tt><br>
57 <font size=-1>0 &lt; int &lt; (num trees in individuals), if exists</font></td>
58 <td valign=top>(tree chosen for mutation; if parameter doesn't exist, tree is picked at random)</td></tr>
59
60 </table>
61
62 <p><b>Default Base</b><br>
63 gp.breed.mutate-promote
64
65
66 * @author Sean Luke
67 * @version 1.0
68 */
69
70public class MutatePromotePipeline extends GPBreedingPipeline
71    {
72    public static final String P_MUTATEPROMOTE = "mutate-promote";
73    public static final String P_NUM_TRIES = "tries";
74    public static final int NUM_SOURCES = 1;
75   
76    /** Is our tree fixed?  If not, this is -1 */
77    int tree;
78
79    /** The number of times the pipeline tries to build a valid mutated
80        tree before it gives up and just passes on the original */
81    int numTries;
82
83
84    public Parameter defaultBase() { return GPBreedDefaults.base().push(P_MUTATEPROMOTE); }
85
86    public int numSources() { return NUM_SOURCES; }
87
88    public void setup(final EvolutionState state, final Parameter base)
89        {
90        super.setup(state,base);
91       
92        Parameter def = defaultBase();
93
94        numTries = state.parameters.getInt(base.push(P_NUM_TRIES),
95            def.push(P_NUM_TRIES),1);
96        if (numTries == 0)
97            state.output.fatal("MutatePromotePipeline has an invalid number of tries (it must be >= 1).",base.push(P_NUM_TRIES),def.push(P_NUM_TRIES));
98
99        tree = TREE_UNFIXED;
100        if (state.parameters.exists(base.push(P_TREE).push(""+0),
101                def.push(P_TREE).push(""+0)))
102            {
103            tree = state.parameters.getInt(base.push(P_TREE).push(""+0),
104                def.push(P_TREE).push(""+0),0);
105            if (tree==-1)
106                state.output.fatal("Tree fixed value, if defined, must be >= 0");
107            }
108        }
109
110    private boolean promotable(final GPInitializer initializer,
111        final GPNode node)
112        {
113        // A node is promotable if:
114        // 1: its parent is a GPNode
115        if (!(node.parent instanceof GPNode))
116            return false;
117        GPNode parent = (GPNode)(node.parent);
118
119        GPType t;
120        if (parent.parent instanceof GPNode)  // ugh, expensive
121            t = ((GPNode)(parent.parent)).constraints(initializer).childtypes[parent.argposition];
122        else
123            t = ((GPTree)(parent.parent)).constraints(initializer).treetype;
124
125        // 2: the node's returntype is type-compatible with its GRANDparent's return slot
126        return (node.constraints(initializer).returntype.compatibleWith(initializer,t));
127        }
128   
129   
130    private void promoteSomething(final GPNode node)
131        {
132        // the node's parent MUST be a GPNode -- we've checked that already
133        GPNode parent = (GPNode)(node.parent);
134
135        node.parent = parent.parent;
136        node.argposition = parent.argposition;
137       
138        if (parent.parent instanceof GPNode)
139            ((GPNode)(parent.parent)).children[parent.argposition] = node;
140        else ((GPTree)(parent.parent)).child = node;
141        return;
142        }
143
144    private int numPromotableNodes(final GPInitializer initializer,
145        final GPNode root, int soFar)
146        {
147        if (promotable(initializer,root)) soFar++;
148        for(int x=0;x<root.children.length;x++)
149            soFar = numPromotableNodes(initializer,root.children[x],soFar);
150        return soFar;
151        }
152
153
154    private GPNode promotableNode;
155
156    // sticks the node in
157    private int pickPromotableNode(final GPInitializer initializer,
158        final GPNode root, int num)
159        {
160        if (promotable(initializer,root))
161            {
162            num--;
163            if (num==-1)  // found it
164                {
165                promotableNode = root;
166                return num;
167                }
168            }
169        for(int x=0;x<root.children.length;x++)
170            {
171            num = pickPromotableNode(initializer,root.children[x],num);
172            if (num==-1) break;  // someone found it
173            }
174        return num;     
175        }
176   
177
178    public int produce(final int min,
179        final int max,
180        final int start,
181        final int subpopulation,
182        final Individual[] inds,
183        final EvolutionState state,
184        final int thread)
185        {
186        // grab n individuals from our source and stick 'em right into inds.
187        // we'll modify them from there
188        int n = sources[0].produce(min,max,start,subpopulation,inds,state,thread);
189
190
191        // should we bother?
192        if (!state.random[thread].nextBoolean(likelihood))
193            return reproduce(n, start, subpopulation, inds, state, thread, false);  // DON'T produce children from source -- we already did
194
195
196
197        GPInitializer initializer = ((GPInitializer)state.initializer);
198
199        // now let's mutate 'em
200        for(int q=start; q < n+start; q++)
201            {
202            GPIndividual i = (GPIndividual)inds[q];
203                   
204            if (tree!=TREE_UNFIXED && (tree<0 || tree >= i.trees.length))
205                // uh oh
206                state.output.fatal("MutatePromotePipeline attempted to fix tree.0 to a value which was out of bounds of the array of the individual's trees.  Check the pipeline's fixed tree values -- they may be negative or greater than the number of trees in an individual");
207
208            GPIndividual j;
209            if (sources[0] instanceof BreedingPipeline)
210                // it's already a copy, so just smash the tree in
211                {
212                j=i;
213                }
214            else // need to copy it
215                {
216                j = (GPIndividual)(i.lightClone());
217               
218                // Fill in various tree information that didn't get filled in there
219                j.trees = new GPTree[i.trees.length];
220               
221                for(int x=0;x<j.trees.length;x++)
222                    {
223                    j.trees[x] = (GPTree)(i.trees[x].lightClone());
224                    j.trees[x].owner = j;
225                    j.trees[x].child = (GPNode)(i.trees[x].child.clone());
226                    j.trees[x].child.parent = j.trees[x];
227                    j.trees[x].child.argposition = 0;
228                    }
229                }
230
231            for (int x=0;x<numTries;x++)
232                {
233                int t;
234                // pick random tree
235                if (tree==TREE_UNFIXED)
236                    if (i.trees.length>1) t = state.random[thread].nextInt(i.trees.length);
237                    else t = 0;
238                else t = tree;
239               
240                // is the tree promotable?
241                int numpromote = numPromotableNodes(initializer, j.trees[t].child,0);
242                if (numpromote==0) continue; // uh oh, try again
243               
244                // promote the node, or if we're unsuccessful, just leave it alone
245                pickPromotableNode(initializer, j.trees[t].child,state.random[thread].
246                    nextInt(numpromote));
247               
248                // promote it
249                promoteSomething(promotableNode );
250                j.evaluated = false;
251                break;
252                }
253
254           
255            // add the new individual, replacing its previous source
256            inds[q] = j;
257            }
258        return n;
259        }
260    }
Note: See TracBrowser for help on using the repository browser.