Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/select/GreedyOverselection.java @ 9598

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

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

File size: 7.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.select;
9import ec.*;
10import ec.util.*;
11
12/*
13 * GreedyOverselection.java
14 *
15 * Created: Thu Feb 10 17:39:03 2000
16 * By: Sean Luke
17 */
18
19/**
20 * GreedyOverselection is a SelectionMethod which implements Koza-style
21 * fitness-proportionate greedy overselection.  Not appropriate for
22 * multiobjective fitnesses.
23 *
24 * <p> This selection method first
25 * divides individuals in a population into two groups: the "good"
26 * ("top") group, and the "bad" ("bottom") group.  The best <i>top</i>
27 * percent of individuals in the population go into the good group.
28 * The rest go into the "bad" group.  With a certain probability (determined
29 * by the <i>gets</i> setting), an individual will be picked out of the
30 * "good" group.  Once we have determined which group the individual
31 * will be selected from, the individual is picked using fitness proportionate
32 * selection in that group, that is, the likelihood he is picked is
33 * proportionate to his fitness relative to the fitnesses of others in his
34 * group.
35 *
36 * <p> All this is expensive to
37 * set up and bring down, so it's not appropriate for steady-state evolution.
38 * If you're not familiar with the relative advantages of
39 * selection methods and just want a good one,
40 * use TournamentSelection instead.
41 *
42 * <p><b><font color=red>
43 * Note: Fitnesses must be non-negative.  0 is assumed to be the worst fitness.
44 * </font></b>
45
46 <p><b>Typical Number of Individuals Produced Per <tt>produce(...)</tt> call</b><br>
47 Always 1.
48
49 <p><b>Parameters</b><br>
50 <table>
51 <tr><td valign=top><i>base.</i><tt>top</tt><br>
52 <font size=-1>0.0 &lt;= float &lt;= 1.0</font></td>
53 <td valign=top>(the percentage of the population going into the "good" (top) group)</td></tr>
54 <tr><td valign=top><i>base.</i><tt>gets</tt><br>
55 <font size=-1>0.0 &lt;= float &lt;= 1.0</font></td>
56 <td valign=top>(the likelihood that an individual will be picked from the "good" group)</td></tr>
57 </table>
58
59 <p><b>Default Base</b><br>
60 select.greedy
61 * @author Sean Luke
62 * @version 1.0
63 */
64
65public class GreedyOverselection extends SelectionMethod
66    {
67    public float[] sortedFitOver;
68    public float[] sortedFitUnder;
69    /** Sorted population -- since I *have* to use an int-sized
70        individual (short gives me only 16K),
71        I might as well just have pointers to the
72        population itself.  :-( */
73    public int[] sortedPop;
74
75    public static final String P_GREEDY = "greedy";
76    public static final String P_TOP = "top";
77    public static final String P_GETS = "gets";
78
79    public float top_n_percent;
80    public float gets_n_percent;
81
82    public Parameter defaultBase()
83        {
84        return SelectDefaults.base().push(P_GREEDY);
85        }
86
87    public void setup(final EvolutionState state, final Parameter base)
88        {
89        super.setup(state,base);
90       
91        Parameter def = defaultBase();
92       
93        top_n_percent =
94            state.parameters.getFloatWithMax(base.push(P_TOP),def.push(P_TOP),0.0,1.0);
95        if (top_n_percent < 0.0)
96            state.output.fatal("Top-n-percent must be between 0.0 and 1.0", base.push(P_TOP),def.push(P_TOP));
97       
98        gets_n_percent =
99            state.parameters.getFloatWithMax(base.push(P_GETS),def.push(P_GETS),0.0,1.0);
100        if (gets_n_percent < 0.0)
101            state.output.fatal("Gets-n-percent must be between 0.0 and 1.0", base.push(P_GETS),def.push(P_GETS));
102       
103        }
104   
105   
106    // don't need clone etc. -- I'll never clone with my arrays intact
107   
108    public void prepareToProduce(final EvolutionState s,
109        final int subpopulation,
110        final int thread)
111        {
112        // load sortedPop integers
113        final Individual[] i = s.population.subpops[subpopulation].individuals;
114
115        sortedPop = new int[i.length];
116        for(int x=0;x<sortedPop.length;x++) sortedPop[x] = x;
117       
118        // sort sortedPop in increasing fitness order
119        QuickSort.qsort(sortedPop,
120            new SortComparatorL()
121                {
122                public boolean lt(long a, long b)
123                    {
124                    return ((Individual)(i[(int)b])).fitness.betterThan(
125                        ((Individual)(i[(int)a])).fitness);
126                    }
127
128                public boolean gt(long a, long b)
129                    {
130                    return ((Individual)(i[(int)a])).fitness.betterThan(
131                        ((Individual)(i[(int)b])).fitness);
132                    }
133                });
134       
135        // determine my boundary -- must be at least 1 and must leave 1 over
136        int boundary = (int)(sortedPop.length * top_n_percent);
137        if (boundary == 0) boundary = 1;
138        if (boundary == sortedPop.length) boundary = sortedPop.length-1;
139        if (boundary == 0) // uh oh
140            s.output.fatal("Greedy Overselection can only be done with a population of size 2 or more (offending subpopulation #" + subpopulation + ")");
141       
142        // load sortedFitOver
143        sortedFitOver = new float[boundary];
144        int y=0;
145        for(int x=sortedPop.length-boundary;x<sortedPop.length;x++)
146            {
147            sortedFitOver[y] = (i[sortedPop[x]]).fitness.fitness();
148            if (sortedFitOver[y] < 0) // uh oh
149                s.output.fatal("Discovered a negative fitness value.  Greedy Overselection requires that all fitness values be non-negative (offending subpopulation #" + subpopulation + ")");
150            y++;
151            }
152       
153        // load sortedFitUnder
154        sortedFitUnder = new float[sortedPop.length-boundary];
155        y=0;
156        for(int x=0;x<sortedPop.length-boundary;x++)
157            {
158            sortedFitUnder[y] = (i[sortedPop[x]]).fitness.fitness();
159            if (sortedFitUnder[y] < 0) // uh oh
160                s.output.fatal("Discovered a negative fitness value.  Greedy Overselection requires that all fitness values be non-negative (offending subpopulation #" + subpopulation + ")");
161            y++;
162            }
163
164        // organize the distributions.  All zeros in fitness is fine
165        RandomChoice.organizeDistribution(sortedFitUnder, true);
166        RandomChoice.organizeDistribution(sortedFitOver, true);
167        }
168
169    public int produce(final int subpopulation,
170        final EvolutionState state,
171        final int thread)
172        {
173        // pick a coin toss
174        if (state.random[thread].nextBoolean(gets_n_percent))
175            // over -- sortedFitUnder.length to sortedPop.length
176            return sortedPop[
177                sortedFitUnder.length + RandomChoice.pickFromDistribution(
178                    sortedFitOver,state.random[thread].nextFloat())];
179        else
180            // under -- 0 to sortedFitUnder.length
181            return sortedPop[RandomChoice.pickFromDistribution(
182                    sortedFitUnder,state.random[thread].nextFloat())];
183        }
184
185    public void finishProducing(final EvolutionState s,
186        final int subpopulation,
187        final int thread)
188        {
189        // release the distributions so we can quickly
190        // garbage-collect them if necessary
191        sortedFitUnder = null;
192        sortedFitOver = null;
193        sortedPop = null;
194        }
195    }
Note: See TracBrowser for help on using the repository browser.