Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/vector/VectorSpecies.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: 17.3 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.vector;
9
10import ec.util.*;
11import java.io.*;
12import ec.*;
13
14/*
15 * VectorSpecies.java
16 *
17 * Created: Thu Mar 22 17:44:00 2001
18 * By: Liviu Panait
19 */
20
21/**
22 * VectorSpecies is a species which can create VectorIndividuals.  Different
23 * VectorSpecies are used for different kinds of VectorIndividuals: a plain
24 * VectorSpecies is probably only applicable for BitVectorIndividuals.
25 *
26 * <p>VectorSpecies supports the following recombination methods:</p>
27 * <ul>
28 * <li><b>One-point crossover</b>.</li>
29 * <li><b>Two-point crossover</b>.</li>
30 * <li><b>Uniform crossover</b> - inaccurately called "any-point".</li>
31 * <li><b>Line recombination</b> - children are random points on a line between
32 *      the two parents.</li>
33 * <li><b>Intermediate recombination</b> - the value of each component of the
34 *      vector is between the values of that component of the parent vectors.
35 *      </li>
36 * </ul>
37 * <p>Note that for LongVectorIndividuals, there are certain values that will
38 * never be created by line and intermediate recombination, because the
39 * recombination is calculated using doubles and then rounded to the nearest
40 * long. For large enough values (but still smaller than the maximum long), the
41 * difference between one double and the next is greater than one.</p>
42 *
43 * <p>VectorSpecies has three wasy to determine the initial size of the individual:</p>
44 * <ul>
45 * <li><b>A fixed size</b>.</li>
46 * <li><b>Geometric distribution</b>.</li>
47 * <li><b>Uniform distribution</b></li>
48 * </ul>
49 *
50 * <p>If the algorithm used is the geometric distribution, the VectorSpecies starts at a
51 * minimum size and continues flipping a coin with a certain "resize probability",
52 * increasing the size each time, until the coin comes up tails (fails).  The chunk size
53 * must be 1 in this case.
54 *
55 * <p> If the algorithm used is the uniform distribution, the VectorSpecies picks a random
56 * size between a provided minimum and maximum size, inclusive.  The chunk size
57 * must be 1 in this case.
58 *
59 * <p>If the size is fixed, then you can also provide a "chunk size" which constrains the
60 * locations in which crossover can be performed (only along chunk boundaries).  The genome
61 * size must be a multiple of the chunk size in this case.
62 *
63 * <p>VectorSpecies also contains a number of parameters guiding how the individual
64 * crosses over and mutates.
65 
66 <p><b>Parameters</b><br>
67 <table>
68 <tr><td valign=top><i>base</i>.<tt>genome-size</tt><br>
69 <font size=-1>int &gt;= 1 or one of: geometric, uniform</font></td>
70 <td valign=top>(size of the genome, or if 'geometric' or 'uniform', the algorithm used to size the initial genome)</td></tr>
71
72 <tr><td valign=top><i>base</i>.<tt>chunk-size</tt><br>
73 <font size=-1>1 &lt;= int &lt;= genome-size (default=1)</font></td>
74 <td valign=top>(the chunk size for crossover (crossover will only occur on chunk boundaries))</td></tr>
75
76 <tr><td valign=top><i>base</i>.<tt>geometric-prob</tt><br>
77 <font size=-1>0.0 &lt;= float &lt; 1.0</font></td>
78 <td valign=top>(the coin-flip probability for increasing the initial size using the geometric distribution)</td></tr>
79
80 <tr><td valign=top><i>base</i>.<tt>min-initial-size</tt><br>
81 <font size=-1>int &gt;= 0</font></td>
82 <td valign=top>(the minimum initial size of the genome)</td></tr>
83
84 <tr><td valign=top><i>base</i>.<tt>max-initial-size</tt><br>
85 <font size=-1>int &gt;= min-initial-size</font></td>
86 <td valign=top>(the maximum initial size of the genome)</td></tr>
87
88 <tr><td valign=top><i>base</i>.<tt>crossover-type</tt><br>
89 <font size=-1>string, one of: one, two, any</font></td>
90 <td valign=top>(default crossover type (one-point, two-point, any-point (uniform), line, or intermediate)</td></tr>
91
92 <tr><td valign=top><i>base</i>.<tt>crossover-prob</tt><br>
93 <font size=-1>0.0 &gt;= float &gt;= 1.0 </font></td>
94 <td valign=top>(probability that a gene will get crossed over during any-point crossover)</td></tr>
95
96 <tr><td valign=top><i>base</i>.<tt>mutation-prob</tt><br>
97 <font size=-1>0.0 &lt;= float &lt;= 1.0 </font></td>
98 <td valign=top>(probability that a gene will get mutated over default mutation)</td></tr>
99
100 <tr><td valign=top><i>base</i>.<tt>line-extension</tt><br>
101 <font size=-1>float &gt;= 0.0 </font></td>
102 <td valign=top>(for line and intermediate recombination, how far along the line or outside of the hypercube children can be. If this value is zero, all children must be within the hypercube.)
103
104 </table>
105
106 <p><b>Default Base</b><br>
107 vector.species
108
109 * @author Sean Luke and Liviu Panait
110 * @version 1.0
111 */
112
113public class VectorSpecies extends Species
114    {
115    public static final String P_VECTORSPECIES = "species";
116
117    public final static String P_CROSSOVERTYPE = "crossover-type";
118    public final static String P_CHUNKSIZE = "chunk-size";
119    public final static String V_ONE_POINT = "one";
120    public final static String V_TWO_POINT = "two";
121    public final static String V_ANY_POINT = "any";
122    public final static String V_LINE_RECOMB = "line";
123    public final static String V_INTERMED_RECOMB = "intermediate";
124    public final static String V_SIMULATED_BINARY = "sbx";
125    public final static String P_CROSSOVER_DISTRIBUTION_INDEX = "crossover-distribution-index";
126    public final static String P_MUTATIONPROB = "mutation-prob";
127    public final static String P_CROSSOVERPROB = "crossover-prob";
128    public final static String P_GENOMESIZE = "genome-size";
129    public final static String P_LINEDISTANCE = "line-extension";
130    public final static String V_GEOMETRIC = "geometric";
131    public final static String P_GEOMETRIC_PROBABILITY = "geometric-prob";
132    public final static String V_UNIFORM = "uniform";
133    public final static String P_UNIFORM_MIN = "min-initial-size";
134    public final static String P_UNIFORM_MAX = "max-initial-size";
135
136    public final static int C_ONE_POINT = 0;
137    public final static int C_TWO_POINT = 1;
138    public final static int C_ANY_POINT = 128;
139    public final static int C_LINE_RECOMB = 256;
140    public final static int C_INTERMED_RECOMB = 512;
141    public final static int C_SIMULATED_BINARY = 1024;
142    public final static int C_NONE = 0;
143    public final static int C_GEOMETRIC = 1;
144    public final static int C_UNIFORM = 2;
145
146    /** Probability that a gene will mutate */
147    public float mutationProbability;
148    /** Probability that a gene will cross over -- ONLY used in V_ANY_POINT crossover */
149    public float crossoverProbability;
150    /** What kind of crossover do we have? */
151    public int crossoverType;
152    /** How big of a genome should we create on initialization? */
153    public int genomeSize;
154    /** What should the SBX distribution index be? */
155    public int crossoverDistributionIndex;
156    /** How should we reset the genome? */
157    public int genomeResizeAlgorithm;
158    /** What's the smallest legal genome? */
159    public int minInitialSize;
160    /** What's the largest legal genome? */
161    public int maxInitialSize;
162    /** With what probability would our genome be at least 1 larger than it is now during initialization? */
163    public float genomeIncreaseProbability;
164    /** How big of chunks should we define for crossover? */
165    public int chunksize;
166    /** How far along the long a child can be located for line or intermediate recombination */
167    public double lineDistance;
168    /** Was the initial size determined dynamically? */
169    public boolean dynamicInitialSize = false;
170
171    // we use warned here because it's quite a bit faster than calling warnOnce
172    protected boolean warned = false;
173    EvolutionState state;
174    protected void warnAboutGene(int gene)
175        {
176        state.output.warnOnce("Attempt to access maxGene or minGene from IntegerVectorSpecies beyond initial genomeSize.\n" +
177            "From now on, maxGene(a) = maxGene(maxGeneIndex) for a >= maxGeneIndex.  Likewise for minGene(...)");
178        warned = true;
179        }
180   
181    public Parameter defaultBase()
182        {
183        return VectorDefaults.base().push(P_VECTORSPECIES);
184        }
185
186    public void setup(final EvolutionState state, final Parameter base)
187        {
188        // setup constraints  FIRST so the individuals can see them when they're
189        // set up.
190       
191        Parameter def = defaultBase();
192       
193        this.state = state;
194       
195        String genomeSizeForm = state.parameters.getString(base.push(P_GENOMESIZE),def.push(P_GENOMESIZE));
196        if (genomeSizeForm == null) // clearly an error
197            {
198            state.output.fatal("No genome size specified.", base.push(P_GENOMESIZE),def.push(P_GENOMESIZE));
199            }
200        else if (genomeSizeForm.equals(V_GEOMETRIC))
201            {
202            dynamicInitialSize = true;
203            genomeSize = 1;
204            genomeResizeAlgorithm = C_GEOMETRIC;
205            chunksize = state.parameters.getIntWithDefault(base.push(P_CHUNKSIZE),def.push(P_CHUNKSIZE),1);
206            if (chunksize != 1)
207                state.output.fatal("To use Geometric size initialization, VectorSpecies must have a chunksize of 1",
208                    base.push(P_CHUNKSIZE),def.push(P_CHUNKSIZE));
209            minInitialSize = state.parameters.getInt(base.push(P_UNIFORM_MIN),def.push(P_UNIFORM_MIN), 0);
210            if (minInitialSize < 0)
211                {
212                state.output.warning("Gemoetric size initialization used, but no minimum initial size provided.  Assuming minimum is 0.");
213                minInitialSize = 0;
214                }
215            genomeIncreaseProbability = state.parameters.getFloatWithMax(base.push(P_GEOMETRIC_PROBABILITY),def.push(P_GEOMETRIC_PROBABILITY),0.0, 1.0);
216            if (genomeIncreaseProbability < 0.0 || genomeIncreaseProbability >= 1.0)  // note >=
217                state.output.fatal("To use Gemoetric size initialization, the genome increase probability must be >= 0.0 and < 1.0",
218                    base.push(P_GEOMETRIC_PROBABILITY),def.push(P_GEOMETRIC_PROBABILITY));
219            }
220        else if (genomeSizeForm.equals(V_UNIFORM))
221            {
222            dynamicInitialSize = true;
223            genomeSize = 1;
224            genomeResizeAlgorithm = C_UNIFORM;
225            chunksize = state.parameters.getIntWithDefault(base.push(P_CHUNKSIZE),def.push(P_CHUNKSIZE),1);
226            if (chunksize != 1)
227                state.output.fatal("To use Uniform size initialization, VectorSpecies must have a chunksize of 1",
228                    base.push(P_CHUNKSIZE),def.push(P_CHUNKSIZE));
229            minInitialSize = state.parameters.getInt(base.push(P_UNIFORM_MIN),def.push(P_UNIFORM_MIN),0);
230            if (minInitialSize < 0)
231                state.output.fatal("To use Uniform size initialization, you must set a minimum initial size >= 0",
232                    base.push(P_UNIFORM_MIN),def.push(P_UNIFORM_MIN));
233            maxInitialSize = state.parameters.getInt(base.push(P_UNIFORM_MAX),def.push(P_UNIFORM_MAX),0);
234            if (maxInitialSize < 0)
235                state.output.fatal("To use Uniform size initialization, you must set a maximum initial size >= 0",
236                    base.push(P_UNIFORM_MAX),def.push(P_UNIFORM_MAX));
237            if (maxInitialSize < minInitialSize)
238                state.output.fatal("To use Uniform size initialization, you must set a maximum initial size >= the minimum initial size",
239                    base.push(P_UNIFORM_MAX),def.push(P_UNIFORM_MAX));
240            }
241        else  // it's a number
242            {
243            genomeSize = state.parameters.getInt(base.push(P_GENOMESIZE),def.push(P_GENOMESIZE),1);
244            if (genomeSize==0)
245                state.output.error("VectorSpecies must have a genome size > 0",
246                    base.push(P_GENOMESIZE),def.push(P_GENOMESIZE));
247                       
248            genomeResizeAlgorithm = C_NONE;
249
250            chunksize = state.parameters.getIntWithDefault(base.push(P_CHUNKSIZE),def.push(P_CHUNKSIZE),1);
251            if (chunksize <= 0 || chunksize > genomeSize)
252                state.output.fatal("VectorSpecies must have a chunksize which is > 0 and < genomeSize",
253                    base.push(P_CHUNKSIZE),def.push(P_CHUNKSIZE));
254            if (genomeSize % chunksize != 0)
255                state.output.fatal("VectorSpecies must have a genomeSize which is a multiple of chunksize",
256                    base.push(P_CHUNKSIZE),def.push(P_CHUNKSIZE));
257            }
258                               
259        mutationProbability = state.parameters.getFloatWithMax(
260            base.push(P_MUTATIONPROB),def.push(P_MUTATIONPROB),0.0,1.0);
261        if (mutationProbability==-1.0)
262            state.output.error("VectorSpecies must have a mutation probability between 0.0 and 1.0 inclusive",
263                base.push(P_MUTATIONPROB),def.push(P_MUTATIONPROB));
264   
265        String ctype = state.parameters.getStringWithDefault(base.push(P_CROSSOVERTYPE), def.push(P_CROSSOVERTYPE), null);
266        crossoverType = C_ONE_POINT;
267        if (ctype==null)
268            state.output.warning("No crossover type given for VectorSpecies, assuming one-point crossover",
269                base.push(P_CROSSOVERTYPE),def.push(P_CROSSOVERTYPE));
270        else if (ctype.equalsIgnoreCase(V_ONE_POINT))
271            crossoverType=C_ONE_POINT;  // redundant
272        else if (ctype.equalsIgnoreCase(V_TWO_POINT))
273            crossoverType=C_TWO_POINT;
274        else if (ctype.equalsIgnoreCase(V_ANY_POINT))
275            crossoverType=C_ANY_POINT;
276        else if (ctype.equalsIgnoreCase(V_LINE_RECOMB))
277            crossoverType=C_LINE_RECOMB;
278        else if (ctype.equalsIgnoreCase(V_INTERMED_RECOMB))
279            crossoverType=C_INTERMED_RECOMB;
280        else if (ctype.equalsIgnoreCase(V_SIMULATED_BINARY))
281            crossoverType=C_SIMULATED_BINARY;
282        else state.output.error("VectorSpecies given a bad crossover type: " + ctype,
283            base.push(P_CROSSOVERTYPE),def.push(P_CROSSOVERTYPE));
284   
285        if (crossoverType==C_LINE_RECOMB || crossoverType==C_INTERMED_RECOMB)
286            {
287            if (!(this instanceof IntegerVectorSpecies) && !(this instanceof FloatVectorSpecies))
288                state.output.error("Line and intermediate recombinations are only supported by IntegerVectorSpecies and FloatVectorSpecies", base.push(P_CROSSOVERTYPE), def.push(P_CROSSOVERTYPE));
289            lineDistance = state.parameters.getDouble(
290                base.push(P_LINEDISTANCE), def.push(P_LINEDISTANCE), 0.0);
291            if (lineDistance==-1.0)
292                state.output.error("If it's going to use line or intermediate recombination, VectorSpecies needs a line extension >= 0.0  (0.25 is common)", base.push(P_LINEDISTANCE), def.push(P_LINEDISTANCE));
293            }
294        else lineDistance = 0.0;
295
296        if (crossoverType==C_ANY_POINT)
297            {
298            crossoverProbability = state.parameters.getFloatWithMax(
299                base.push(P_CROSSOVERPROB),def.push(P_CROSSOVERPROB),0.0,0.5);
300            if (crossoverProbability==-1.0)
301                state.output.error("If it's going to use any-point crossover, VectorSpecies must have a crossover probability between 0.0 and 0.5 inclusive",
302                    base.push(P_CROSSOVERPROB),def.push(P_CROSSOVERPROB));
303            }
304        else crossoverProbability = 0.0f;
305
306        if (crossoverType==C_SIMULATED_BINARY)
307            {
308            if (!(this instanceof FloatVectorSpecies))
309                state.output.error("Simulated binary crossover (SBX) is only supported by FloatVectorSpecies", base.push(P_CROSSOVERTYPE), def.push(P_CROSSOVERTYPE));
310            crossoverDistributionIndex = state.parameters.getInt(base.push(P_CROSSOVER_DISTRIBUTION_INDEX), def.push(P_CROSSOVER_DISTRIBUTION_INDEX), 0);
311            if (crossoverDistributionIndex < 0)
312                state.output.fatal("If FloatVectorSpecies is going to use simulated binary crossover (SBX), the distribution index must be defined and >= 0.",
313                    base.push(P_CROSSOVER_DISTRIBUTION_INDEX), def.push(P_CROSSOVER_DISTRIBUTION_INDEX));
314            }
315        else crossoverProbability = 0.0f;
316
317        state.output.exitIfErrors();
318               
319        if (crossoverType != C_ANY_POINT && state.parameters.exists(base.push(P_CROSSOVERPROB),def.push(P_CROSSOVERPROB)))
320            state.output.warning("The 'crossover-prob' parameter may only be used with any-point crossover.  It states the probability that a particular gene will be crossed over.  If you were looking for the probability of crossover happening at *all*, look at the 'likelihood' parameter.",
321                base.push(P_CROSSOVERPROB),def.push(P_CROSSOVERPROB));
322       
323        // NOW call super.setup(...), which will in turn set up the prototypical individual
324        super.setup(state,base);
325        }
326
327    public Individual newIndividual(final EvolutionState state, int thread)
328       
329        {
330        VectorIndividual newind = (VectorIndividual)(super.newIndividual(state, thread));
331
332        if (genomeResizeAlgorithm == C_NONE)
333            newind.reset( state, thread );
334        else if (genomeResizeAlgorithm == C_UNIFORM)
335            {
336            int size = state.random[thread].nextInt(maxInitialSize - minInitialSize + 1) + minInitialSize;
337            newind.reset(state, thread, size);
338            }
339        else if (genomeResizeAlgorithm == C_GEOMETRIC)
340            {
341            int size = minInitialSize;
342            while(state.random[thread].nextBoolean(genomeIncreaseProbability)) size++;
343            newind.reset(state, thread, size);
344            }
345                       
346        return newind;
347        }
348    }
349
350
Note: See TracBrowser for help on using the repository browser.