Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/parsimony/BucketTournamentSelection.java @ 10501

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

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

File size: 9.7 KB
Line 
1/*
2  Copyright 2006 by Sean Luke and George Mason University
3  Licensed under the Academic Free License version 3.0
4  See the file "LICENSE" for more information
5*/
6
7
8package ec.parsimony;
9
10import ec.*;
11import ec.util.*;
12import ec.steadystate.*;
13import ec.select.*;
14
15/*
16 * BucketTournamentSelection.java
17 *
18 * Created: Mon Apr 09 17:02:30 2001
19 * By: Liviu Panait
20 */
21
22/**
23 *
24 * Does a tournament selection, limited to the subpopulation it's
25 * working in at the time.
26 *
27 * <p>Bucket Lexicographic Tournament selection works like as follows. There is a
28 * number of buckets (<i>num-buckets</i>) specified beforehand, and each is
29 * assigned a rank from 1 to <i>num-buckets</i>.  The population, of size <i>pop-size</i>,
30 * is sorted by fitness.  The bottom <i>pop-size</i>/<i>num-buckets</i> individuals are
31 * placed in the worst ranked bucket, plus any individuals remaining in the population with
32 * the same fitness as the best individual in the bucket.  Then the second worst
33 * <i>pop-size</i>/<i>num-buckets</i> individuals are placed in the second worst ranked bucket,
34 * plus any individuals in the population equal in fitness to the best individual in that bucket.
35 * This continues until there are no individuals in the population.  Note that the topmost bucket
36 * with individuals can hold fewer than <i>pop-size</i>/<i>num-buckets</i> individuals, if
37 * <i>pop-size</i> is not a multiple of <i>num-buckets</i>. Depending on the number of
38 * equal-fitness individuals in the population, there can be some top buckets that are never
39 * filled. The fitness of each individual in a bucket is set to the rank of the bucket holding
40 * it.  Direct bucketing has the effect of trading off fitness differences for size. Thus the
41 * larger the bucket, the stronger the emphasis on size as a secondary objective.
42 *
43 * After ranking the individuals, <i>size</i> individuals are chosen at random from the
44 * population. Of those individuals, the one with the highest rank is selected. If the two
45 * individuals are in the same rank, meaning that they have similar fitness, the one
46 * with the smallest size is selected.
47 *
48 * <p>Bucket Lexicographic Tournament selection is so simple that it doesn't
49 * need to maintain a cache of any form, so many of the SelectionMethod methods
50 * just don't do anything at all.
51 *
52
53 <p><b>Typical Number of Individuals Produced Per <tt>produce(...)</tt> call</b><br>
54 Always 1.
55
56 <p><b>Parameters</b><br>
57 <table>
58 <tr><td valign=top><i>base.</i><tt>size</tt><br>
59 <font size=-1>int &gt;= 1 (default 7)</font></td>
60 <td valign=top>(the tournament size)</td></tr>
61
62 <tr><td valign=top><i>base.</i><tt>pick-worst</tt><br>
63 <font size=-1> bool = <tt>true</tt> or <tt>false</tt> (default)</font></td>
64 <td valign=top>(should we pick the <i>worst</i> individual in the tournament instead of the <i>best</i>?)</td></tr>
65
66 <tr><td valign=top><i>base.</i><tt>num-buckets</tt><br>
67 <font size=-1>int &gt;= 1 (default 10)</font></td>
68 <td valign=top>(the number of buckets)</td></tr>
69 </table>
70
71 <p><b>Default Base</b><br>
72 select.bucket-tournament
73
74 *
75 * @author Liviu Panait
76 * @version 1.0
77 */
78
79public class BucketTournamentSelection extends SelectionMethod implements SteadyStateBSourceForm
80    {
81    /** Default base */
82    public static final String P_TOURNAMENT = "bucket-tournament";
83
84    /** If the worst individual should be picked in the tournament */
85    public static final String P_PICKWORST = "pick-worst";
86
87    /** Tournament size parameter */
88    public static final String P_SIZE = "size";
89
90    /** Default size */
91    public static final int DEFAULT_SIZE = 7;
92
93    /** The number of buckets */
94    public static final String P_BUCKETS = "num-buckets";
95
96    /** Default number of buckets */
97    public static final int N_BUCKETS_DEFAULT = 10;
98
99    /** Size of the tournament*/
100    public int size;
101
102    /** Do we pick the worst instead of the best? */
103    public boolean pickWorst;
104
105    // the number of buckets
106    int nBuckets;
107
108    // the indexes of the buckets where the individuals should go (will be used instead of fitness)
109    int[] bucketValues;
110 
111    public Parameter defaultBase()
112        {
113        return SelectDefaults.base().push(P_TOURNAMENT);
114        }
115   
116    public void setup(final EvolutionState state, final Parameter base)
117        {
118        super.setup(state,base);
119       
120        Parameter def = defaultBase();
121
122        size = state.parameters.getInt(base.push(P_SIZE),def.push(P_SIZE),1);
123        if (size < 1)
124            state.output.fatal("Tournament size must be >= 1.",base.push(P_SIZE),def.push(P_SIZE));
125
126        if( state.parameters.exists( base.push(P_BUCKETS), def.push(P_BUCKETS)))
127            {
128            nBuckets = state.parameters.getInt(base.push(P_BUCKETS),def.push(P_BUCKETS),1);
129            if (nBuckets < 1)
130                {
131                state.output.fatal("The number of buckets size must be >= 1.",base.push(P_BUCKETS),def.push(P_BUCKETS));
132                }
133            }
134        else
135            {
136            nBuckets = N_BUCKETS_DEFAULT;
137            }
138
139        pickWorst = state.parameters.getBoolean(base.push(P_PICKWORST),def.push(P_PICKWORST),false);
140        }
141
142    /** Prepare to produce: create the buckets!!!! */
143    public void prepareToProduce(final EvolutionState state, final int subpopulation, final int thread)
144        {
145        bucketValues = new int[ state.population.subpops[subpopulation].individuals.length ];
146
147        // correct?
148        java.util.Arrays.sort(state.population.subpops[subpopulation].individuals,
149            new java.util.Comparator()
150                {
151                public int compare(Object o1, Object o2)
152                    {
153                    Individual a = (Individual) o1;
154                    Individual b = (Individual) o2;
155                    if (a.fitness.betterThan(b.fitness))
156                        return 1;
157                    if (b.fitness.betterThan(a.fitness))
158                        return -1;
159                    return 0;
160                    }
161                });
162
163
164        // how many individuals in current bucket
165        int nInd;
166
167        float averageBuck = ((float)state.population.subpops[subpopulation].individuals.length)/
168            ((float)nBuckets);
169
170        // first individual goes into first bucket
171        bucketValues[0] = 0;
172
173        // now there is one individual in the first bucket
174        nInd = 1;
175
176        for( int i = 1 ; i < state.population.subpops[subpopulation].individuals.length ; i++ )
177            {
178            // if there is still some place left in the current bucket, throw the current individual there too
179            if( nInd < averageBuck )
180                {
181                bucketValues[i] = bucketValues[i-1];
182                nInd++;
183                }
184            else // check if it has the same fitness as last individual
185                {
186                if( ((Individual)state.population.subpops[subpopulation].individuals[i]).fitness.equivalentTo(
187                        ((Individual)state.population.subpops[subpopulation].individuals[i-1]).fitness ) )
188                    {
189                    // now the individual has exactly the same fitness as previous one,
190                    // so we just put it in the same bucket as the previous one(s)
191                    bucketValues[i] = bucketValues[i-1];
192                    nInd++;
193                    }
194                else
195                    {
196                    // if there are buckets left
197                    if( bucketValues[i-1]+1 < nBuckets )
198                        {
199                        // new bucket!!!!
200                        bucketValues[i] = bucketValues[i-1] - 1;
201                        // with only one individual
202                        nInd = 1;
203                        }
204                    else // no more buckets left, just stick everything in the last bucket
205                        {
206                        bucketValues[i] = bucketValues[i-1];
207                        nInd++;
208                        }
209                    }
210                }
211            }
212        }
213
214    public int produce(final int subpopulation,
215        final EvolutionState state,
216        final int thread)
217        {
218        // pick size random individuals, then pick the best.
219        Individual[] oldinds = (state.population.subpops[subpopulation].individuals);
220        int i = state.random[thread].nextInt(oldinds.length);
221        long si = 0;
222
223        for (int x=1;x<size;x++)
224            {
225            int j = state.random[thread].nextInt(oldinds.length);
226            if (pickWorst)
227                {
228                if( bucketValues[j]>bucketValues[i] ) { i = j; si = 0; }
229                else if( bucketValues[i]>bucketValues[j] ) { } // do nothing
230                else
231                    {
232                    if (si==0)
233                        si = oldinds[i].size();
234                    long sj = oldinds[j].size();
235
236                    if (sj >= si) // sj's got worse lookin' trees
237                        { i = j; si = sj; }
238                    }
239                }
240            else
241                {
242                if( bucketValues[j]<bucketValues[i] ) { i = j; si = 0; }
243                else if( bucketValues[i]<bucketValues[j] ) { } // do nothing
244                else
245                    {
246                    if (si==0)
247                        si = oldinds[i].size();
248                    long sj = oldinds[j].size();
249
250                    if (sj < si) // sj's got better lookin' trees
251                        { i = j; si = sj; }
252                    }
253                }
254            }
255        return i;
256        }
257
258    public void individualReplaced(final SteadyStateEvolutionState state,
259        final int subpopulation,
260        final int thread,
261        final int individual)
262        { return; }
263   
264    public void sourcesAreProperForm(final SteadyStateEvolutionState state)
265        { return; }
266   
267    }
Note: See TracBrowser for help on using the repository browser.