Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/vector/FloatVectorSpecies.java @ 6152

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

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

File size: 37.3 KB
Line 
1package ec.vector;
2
3import ec.*;
4import ec.util.*;
5
6/*
7 * FloatVectorSpecies.java
8 *
9 * Created: Tue Feb 20 13:26:00 2001
10 * By: Sean Luke
11 */
12
13/**
14 * FloatVectorSpecies is a subclass of VectorSpecies with special
15 * constraints for floating-point vectors, namely FloatVectorIndividual and
16 * DoubleVectorIndividual.
17 *
18 * <p>FloatVectorSpecies can specify min/max numeric constraints on gene values
19 * in three different ways.
20 *
21 * <ol>
22 * <li> You may provide a default min and max value.
23 *      This is done by specifying:
24 *      <p><i>base</i>.<tt>min-gene</tt>
25 *      <br><i>base</i>.<tt>max-gene</tt>
26 *      <p><i>Note:</i> you <b>must</b> provide these values even if you don't use them,
27 *      as they're used as defaults by #2 and #3 below.
28 *<p>
29 * <li> You may provide min and max values for genes in segments (regions) along
30 *      the genome.  This is done by specifying:
31 *      <p><i>base</i>.<tt>num-segments</tt>
32 *      The segments may be defined by either start or end indices of genes.
33 *      This is controlled by specifying the value of:
34 *      <p><i>base</i>.<tt>segment-type</tt>
35 *      which can assume the value of start or end, with start being the default.
36 *      The indices are defined using Java array style, i.e. the first gene has the index of 0,
37 *      and the last gene has the index of genome-size - 1.
38 *      <p>Using this method, each segment is specified by<i>j</i>...
39 *      <p><i>base</i>.<tt>segment.</tt><i>j</i><tt>.start</tt>
40 *      <br><i>base</i>.<tt>segment.</tt><i>j</i><tt>.min-gene</tt>
41 *      <br><i>base</i>.<tt>segment.</tt><i>j</i><tt>.max-gene</tt>
42 *      if segment-type value was chosen as start or by:
43 *      <p><i>base</i>.<tt>segment.</tt><i>j</i><tt>.end</tt>
44 *      <br><i>base</i>.<tt>segment.</tt><i>j</i><tt>.min-gene</tt>
45 *      <br><i>base</i>.<tt>segment.</tt><i>j</i><tt>.max-gene</tt>
46 *      if segment-type value is equal to end.
47 *<p>
48 * <li> You may provide min and max values for each separate gene. 
49 *      This is done by specifying (for each gene location <i>i</i> you wish to specify)
50 *      <p><i>base</i>.<tt>min-gene</tt>.<i>i</i>
51 *      <br><i>basn</i>.<tt>max-gene</tt>.<i>i</i>
52 * </ol>
53 *
54 * <p>Any settings for #3 override #2, and both override #1.
55 *
56 * <p>
57 * FloatVectorSpecies provides support for three ways of mutating a gene:
58 * <ul>
59 * <li>replacing the gene's value with a value uniformly-drawn from the gene's
60 * range (the default behavior, legacy from the previous versions).</li>
61 * <li>perturbing the gene's value with gaussian noise; if the gene-by-gene range
62 * is used, than the standard deviation is scaled to reflect each gene's range.
63 * If the gaussian mutation's standard deviation is too large for the range,
64 * than there's a large probability the mutated value will land outside range.
65 * We will try again a number of times (100) before giving up and using the
66 * previous mutation method.</li>
67 * <li>perturbing the gene's value with noise chosen from a <i>polynomial distribution</i>,
68 * similar to the gaussian distribution.  The polynomial distribution was popularized
69 * by Kalyanmoy Deb and is found in many of his publications (see http://www.iitk.ac.in/kangal/deb.shtml).
70 * The polynomial distribution has two options.  First, there is the <i>index</i>.  This
71 * variable defines the shape of the distribution and is in some sense the equivalent of the
72 * standard deviation in the gaussian distribution.  The index is an integer.  If it is zero,
73 * the polynomial distribution is simply the uniform distribution from [1,-1].  If it is 1, the
74 * polynomial distribution is basically a triangular distribution from [1,-1] peaking at 0.  If
75 * it is 2, the polynomial distribution follows a squared function, again peaking at 0.  Larger
76 * values result in even more peaking and narrowness.  The default values used in nearly all of
77 * the NSGA-II and Deb work is 20.  Second, there is whether or not the value is intended for
78 * <i>bounded</i> genes.  The default polynomial distribution is used when we assume the gene can
79 * take on literally any value, even beyond the min and max values.  For genes which are restricted
80 * to be between min and max, there is an alternative version of the polynomial distribution, used by
81 * Deb's team but not discussed much in the literature, desiged for that situation.  We assume boundedness
82 * by default, and have found it to be somewhat better for NSGA-II and SPEA2 problems.  For a description
83 * of this alternative version, see "A Niched-Penalty Approach for Constraint Handling in Genetic Algorithms"
84 * by Kalyanmoy Deb and Samir Agrawal.  Deb's default implementation bounds the result to min or max;
85 * instead ECJ's implementation of the polynomial distribution retries until it finds a legal value.  This
86 * will be just fine for ranges like [0,1], but for smaller ranges you may be waiting a long time.
87 * </ul>
88 *
89 *
90 * <p>
91 * <b>Parameters</b><br>
92 * <table>
93 * <tr>
94 * <td valign=top><i>base</i>.<tt>min-gene</tt><br>
95 * <font size=-1>double (default=0.0)</font></td>
96 * <td valign=top>(the minimum gene value)</td>
97 * </tr>
98 *
99 * <tr>
100 * <td valign=top><i>base</i>.<tt>max-gene</tt><br>
101 * <font size=-1>double &gt;= <i>base</i>.min-gene</font></td>
102 * <td valign=top>(the maximum gene value)</td>
103 * </tr>
104 *
105 * <tr>
106 * <td valign=top><i>base</i>.<tt>min-gene</tt>.<i>i</i><br>
107 * <font size=-1>double (default=<i>base</i>.<tt>min-gene</tt>)</font></td>
108 * <td valign=top>(the minimum gene value for gene <i>i</i>)</td>
109 * </tr>
110 *
111 * <tr>
112 * <td valign=top><i>base</i>.<tt>max-gene</tt>.<i>i</i><br>
113 * <font size=-1>double &gt;= <i>base</i>.min-gene.<i>i</i> (default=<i>base</i>.<tt>max-gene</tt>)</font></td>
114 * <td valign=top>(the maximum gene value for gene <i>i</i>)</td>
115 * </tr>
116 *
117 * <tr><td valign=top><i>base.</i>.<tt>num-segments</tt><br>
118 * <font size=-1>int &gt;= 1 (default=no segments used)</font></td>
119 * <td valign=top>(the number of gene segments defined)</td>
120 * </tr>
121 *
122 * <tr><td valign=top><i>base.</i>.<tt>segment-type</tt><br>
123 * <font size=-1>start (default) or end</font></td>
124 * <td valign=top>(defines the way in which segments are defined: either by providing start indices (segment-type=start) or by providing end indices (segment-type=end)</td>
125 * </tr>
126 *
127 * <tr><td valign=top><i>base.</i>.<tt>segment</tt>.<i>j</i>.<tt>start</tt><br>
128 * <font size=-1>0 &lt;= int &lt; genome length</font></td>
129 * <td valign=top>(the start index of gene segment <i>j</i> -- the end of a segment is before the start of the next segment)</td>
130 * <td valign=top>(used when the value of segment-type parameter is equal to start)</td>
131 * </tr>
132 *
133 * <tr><td valign=top><i>base.</i>.<tt>segment</tt>.<i>j</i>.<tt>end</tt><br>
134 * <font size=-1>0 &lt;= int &lt; genome length</font></td>
135 * <td valign=top>(the end of gene segment <i>j</i> -- the start of a segment is after the end of the previous segment)</td>
136 * <td valign=top>(used when the value of segment-type parameter is equal to end)</td>
137 * </tr>
138 *
139 * <tr><td valign=top><i>base.</i>.<tt>segment</tt>.<i>j</i>.<tt>min-gene</tt><br>
140 * <font size=-1>double (default=0.0)</font></td>
141 * <td valign=top>(the minimum gene value for segment <i>j</i>)</td>
142 * </tr>
143 *
144 * <tr><td valign=top><i>base.</i>.<tt>segment</tt>.<i>j</i>.<tt>max-gene</tt><br>
145 * <font size=-1>double &gt;= <i>base.</i>.<tt>segment</tt>.<i>j</i>.<tt>min-gene</tt></td>
146 * <td valign=top>(the maximum gene value for segment <i>j</i>)</td>
147 * </tr>
148 *
149 * <tr>
150 * <td valign=top><i>base</i>.<tt>mutation-type</tt><br>
151 * <font size=-1><tt>reset</tt>, <tt>gauss</tt>, or <tt>polynomial</tt> (default=<tt>reset</tt>)</font></td>
152 * <td valign=top>(the mutation type)</td>
153 * </tr>
154 *
155 * <tr>
156 * <td valign=top><i>base</i>.<tt>mutation-stdev</tt><br>
157 * <font size=-1>double &ge; 0</font></td>
158 * <td valign=top>(the standard deviation or the gauss perturbation)</td>
159 * </tr>
160 *
161 * <tr>
162 * <td valign=top><i>base</i>.<tt>out-of-bounds-retries</tt><br>
163 *  <font size=-1>int &ge; 0 (default=100)</font></td>
164 *  <td valign=top>(number of times the gaussian mutation got the gene out of range
165 *  before we give up and reset the gene's value; 0 means "never give up")</td>
166 * </tr>
167 *
168 * <tr>
169 * <td valign=top><i>base</i>.<tt>distribution-index</tt><br>
170 * <font size=-1>int &ge; 0</font></td>
171 * <td valign=top>(the mutation distribution index for the polynomial mutation distribution)</td>
172 * </tr>
173 *
174 * <tr>
175 * <td valign=top><i>base</i>.<tt>alternative-polynomial-version</tt><br>
176 *  <font size=-1>boolean (default=true)</font></td>
177 *  <td valign=top>(whether to use the "bounded" variation of the polynomial mutation or the standard ("unbounded") version)</td>
178 * </tr>
179 *
180 * <tr>
181 * <td valign=top><i>base</i>.<tt>mutation-bounded</tt><br>
182 *  <font size=-1>boolean (default=true)</font></td>
183 *  <td valign=top>(whether mutation is restricted to only being within the min/max gene values.  Does not apply to SimulatedBinaryCrossover (which is always bounded))</td>
184 * </tr>
185 *
186 * </table>
187 * @author Sean Luke, Gabriel Balan, Rafal Kicinger
188 * @version 2.0
189 */
190public class FloatVectorSpecies extends VectorSpecies
191    {
192    public final static String P_MINGENE = "min-gene";
193
194    public final static String P_MAXGENE = "max-gene";
195
196    public final static String P_MUTATIONTYPE = "mutation-type";
197
198    public final static String P_STDEV = "mutation-stdev";
199
200    public final static String P_MUTATION_DISTRIBUTION_INDEX = "mutation-distribution-index";
201
202    public final static String P_POLYNOMIAL_ALTERNATIVE = "alternative-polynomial-version";
203
204    public final static String V_RESET_MUTATION = "reset";
205
206    public final static String V_GAUSS_MUTATION = "gauss";
207
208    public final static String V_POLYNOMIAL_MUTATION = "polynomial";
209
210    public final static String P_OUTOFBOUNDS_RETRIES = "out-of-bounds-retries";
211
212    public final static String P_NUM_SEGMENTS = "num-segments";
213       
214    public final static String P_SEGMENT_TYPE = "segment-type";
215
216    public final static String P_SEGMENT_START = "start";
217       
218    public final static String P_SEGMENT_END = "end";
219
220    public final static String P_SEGMENT = "segment";
221
222    public final static String P_MUTATION_BOUNDED = "mutation-bounded";
223
224    public final static int C_RESET_MUTATION = 0;
225
226    public final static int C_GAUSS_MUTATION = 1;
227
228    public final static int C_POLYNOMIAL_MUTATION = 2;
229
230    public double[] minGenes;
231    public double[] maxGenes;
232
233    /** What kind of mutation do we have? */
234    public int mutationType;
235       
236    public double gaussMutationStdev;
237    public boolean mutationIsBounded;
238
239    public int outOfBoundsRetries=100;
240       
241    public int mutationDistributionIndex;
242    public boolean polynomialIsAlternative;
243
244    static final double SIMULATED_BINARY_CROSSOVER_EPS = 1.0e-14;   
245
246    private boolean outOfBoundsRetriesWarningPrinted = false;
247    public void outOfRangeRetryLimitReached(EvolutionState state)
248        {
249        if(!outOfBoundsRetriesWarningPrinted)
250            {
251            outOfBoundsRetriesWarningPrinted=true;
252            state.output.warning(
253                "The limit of 'out-of-range' retries for gaussian mutation was reached.");
254            }
255        }
256   
257    public double maxGene(int gene)
258        {
259        double[] m = maxGenes;
260        if (m.length <= gene)
261            {
262            if (!dynamicInitialSize && !warned) warnAboutGene(gene);
263            gene = m.length - 1;
264            }
265        return m[gene];
266        }
267
268    public double minGene(int gene)
269        {
270        double[] m = minGenes;
271        if (m.length <= gene)
272            {
273            if (!dynamicInitialSize && !warned) warnAboutGene(gene);
274            gene = m.length - 1;
275            }
276        return m[gene];
277        }
278
279    public boolean inNumericalTypeRange(double geneVal)
280        {
281        if (i_prototype instanceof FloatVectorIndividual)
282            return (geneVal <= Float.MAX_VALUE && geneVal >= -Float.MAX_VALUE);
283        else if (i_prototype instanceof DoubleVectorIndividual)
284            return true; // geneVal is valid for all double
285        else
286            return false; // dunno what the individual is...
287        }
288
289    public void setup(final EvolutionState state, final Parameter base)
290        {
291        super.setup(state, base);
292
293        Parameter def = defaultBase();
294
295        // create the arrays
296        minGenes = new double[genomeSize];
297        maxGenes = new double[genomeSize];
298
299
300
301        // LOADING GLOBAL MIN/MAX GENES
302        double minGene = state.parameters.getDoubleWithDefault(base.push(P_MINGENE), def.push(P_MINGENE), 0);
303        double maxGene = state.parameters.getDouble(base.push(P_MAXGENE), def.push(P_MAXGENE), minGene);
304        if (maxGene < minGene)
305            state.output.fatal("FloatVectorSpecies must have a default min-gene which is <= the default max-gene",
306                base.push(P_MAXGENE), def.push(P_MAXGENE));
307       
308        for (int x = 0; x < genomeSize; x++)
309            {
310            minGenes[x] = minGene;
311            maxGenes[x] = maxGene;
312            }
313
314       
315        // LOADING SEGMENTS
316       
317       
318        //Set number of segments to 0 by default
319        int numSegments = 0;
320        // Now check to see if segments of genes (genes having the same min and
321        // max values) exist
322        if (state.parameters.exists(base.push(P_NUM_SEGMENTS), def.push(P_NUM_SEGMENTS)))
323            {
324            if (dynamicInitialSize)
325                state.output.warnOnce("Using dynamic initial sizing, but per-segment min/max gene declarations.  This is probably wrong.  You probably want to use global min/max declarations.",
326                    base.push(P_NUM_SEGMENTS), def.push(P_NUM_SEGMENTS));
327                       
328            numSegments = state.parameters.getIntWithDefault(base.push(P_NUM_SEGMENTS),
329                def.push(P_NUM_SEGMENTS), 0);
330                       
331            if(numSegments == 0)
332                state.output.warning(
333                    "The number of genome segments has been defined to be equal to 0.\n"
334                    + "Hence, no genome segments will be defined.",
335                    base.push(P_NUM_SEGMENTS),
336                    def.push(P_NUM_SEGMENTS));
337            else if(numSegments < 0)
338                state.output.fatal(
339                    "Invalid number of genome segments: " + numSegments
340                    + "\nIt must be a nonnegative value.",
341                    base.push(P_NUM_SEGMENTS),
342                    def.push(P_NUM_SEGMENTS));
343                                                       
344            //read the type of segment definition using the default start value
345            String segmentType = state.parameters.getStringWithDefault(base.push(P_SEGMENT_TYPE),
346                def.push(P_SEGMENT_TYPE), P_SEGMENT_START);
347                       
348            if(segmentType.equalsIgnoreCase(P_SEGMENT_START))
349                initializeGenomeSegmentsByStartIndices(state, base, def, numSegments, minGene, maxGene);
350            else if(segmentType.equalsIgnoreCase(P_SEGMENT_END))
351                initializeGenomeSegmentsByEndIndices(state, base, def, numSegments, minGene, maxGene);
352            else
353                state.output.fatal(
354                    "Invalid specification of genome segment type: " + segmentType
355                    + "\nThe " + P_SEGMENT_TYPE + " parameter must have the value of " + P_SEGMENT_START + " or " + P_SEGMENT_END,
356                    base.push(P_SEGMENT_TYPE),
357                    def.push(P_SEGMENT_TYPE));
358
359
360            }
361           
362           
363           
364        // LOADING PER-GENE VALUES
365
366        boolean foundStuff = false;
367        boolean warnedMin = false;
368        boolean warnedMax = false;
369        for (int x = 0; x < genomeSize; x++)
370            {
371            if (!state.parameters.exists(base.push(P_MINGENE).push("" + x), def.push(P_MINGENE).push("" + x)))
372                {
373                if (foundStuff && !warnedMin)
374                    {
375                    state.output.warning(
376                        "FloatVectorSpecies has missing min-gene values for some genes.\n"
377                        + "The first one is gene #" + x + ".",
378                        base.push(P_MINGENE).push("" + x), def.push(P_MINGENE).push("" + x));
379                    warnedMin = true;
380                    }
381                }
382            else
383                {
384                if (dynamicInitialSize)
385                    state.output.warnOnce("Using dynamic initial sizing, but per-gene min/max gene declarations.  This is probably wrong.  You probably want to use global min/max declarations.",
386                        base.push(P_MINGENE).push(""+x),base.push(P_MINGENE).push(""+x));
387
388                minGenes[x] = state.parameters.getDoubleWithDefault(base.push(P_MINGENE).push("" + x),
389                    def.push(P_MINGENE).push("" + x), minGene);
390                foundStuff = true;
391                }
392
393            if (!state.parameters.exists(base.push(P_MAXGENE).push("" + x), def.push(P_MAXGENE).push("" + x)))
394                {
395                if (foundStuff && !warnedMax)
396                    {
397                    state.output.warning(
398                        "FloatVectorSpecies has missing max-gene values for some genes.\n"
399                        + "The first one is gene #" + x + ".",
400                        base.push(P_MAXGENE).push("" + x), def.push(P_MAXGENE).push("" + x));
401                    warnedMax = true;
402                    }
403                }
404            else
405                {
406                if (dynamicInitialSize)
407                    state.output.warnOnce("Using dynamic initial sizing, but per-gene min/max gene declarations.  This is probably wrong.  You probably want to use global min/max declarations.",
408                        base.push(P_MINGENE).push(""+x),base.push(P_MINGENE).push(""+x));
409
410                maxGenes[x] = state.parameters.getDoubleWithDefault(base.push(P_MAXGENE).push("" + x),
411                    def.push(P_MAXGENE).push("" + x), maxGene);
412                foundStuff = true;
413                }
414            }
415                   
416           
417           
418
419
420           
421        // VERIFY
422        for(int x=0 ; x < genomeSize; x++)
423            {
424            if (maxGenes[x] != maxGenes[x])  // uh oh, NaN
425                state.output.fatal("FloatVectorSpecies found that max-gene[" + x + "] is NaN");
426
427            if (minGenes[x] != minGenes[x])  // uh oh, NaN
428                state.output.fatal("FloatVectorSpecies found that min-gene[" + x + "] is NaN");
429
430            if (maxGenes[x] < minGenes[x])
431                state.output.fatal("FloatVectorSpecies must have a min-gene[" + x + "] which is <= the max-gene[" + x + "]");
432
433            // check to see if these longs are within the data type of the particular individual
434            if (!inNumericalTypeRange(minGenes[x]))
435                state.output.fatal("This FloatvectorSpecies has a prototype of the kind: "
436                    + i_prototype.getClass().getName()
437                    + ", but doesn't have a min-gene["
438                    + x
439                    + "] value within the range of this prototype's genome's data types");
440            if (!inNumericalTypeRange(maxGenes[x]))
441                state.output.fatal("This FloatvectorSpecies has a prototype of the kind: "
442                    + i_prototype.getClass().getName()
443                    + ", but doesn't have a max-gene["
444                    + x
445                    + "] value within the range of this prototype's genome's data types");
446            }
447
448       
449       
450       
451       
452        /// MUTATION
453       
454
455        mutationIsBounded = state.parameters.getBoolean(base.push(P_MUTATION_BOUNDED), def.push(P_MUTATION_BOUNDED), true);
456        String mtype = state.parameters.getStringWithDefault(base.push(P_MUTATIONTYPE), def.push(P_MUTATIONTYPE), null);
457        mutationType = C_RESET_MUTATION;
458        if (mtype == null)
459            state.output.warning("No mutation type given for FloatVectorSpecies, assuming 'reset' mutation",
460                base.push(P_MUTATIONTYPE), def.push(P_MUTATIONTYPE));
461        else if (mtype.equalsIgnoreCase(V_RESET_MUTATION))
462            mutationType = C_RESET_MUTATION; // redundant
463        else if (mtype.equalsIgnoreCase(V_POLYNOMIAL_MUTATION))
464            mutationType = C_POLYNOMIAL_MUTATION; // redundant
465        else if (mtype.equalsIgnoreCase(V_GAUSS_MUTATION))
466            mutationType = C_GAUSS_MUTATION;
467        else
468            state.output.fatal("FloatVectorSpecies given a bad mutation type: "
469                + mtype, base.push(P_MUTATIONTYPE), def.push(P_MUTATIONTYPE));
470
471        if (mutationType == C_POLYNOMIAL_MUTATION)
472            {
473            mutationDistributionIndex = state.parameters.getInt(base.push(P_MUTATION_DISTRIBUTION_INDEX), def.push(P_MUTATION_DISTRIBUTION_INDEX), 0);
474            if (mutationDistributionIndex < 0)
475                state.output.fatal("If FloatVectorSpecies is going to use polynomial mutation, the distribution index must be defined and >= 0.",
476                    base.push(P_MUTATION_DISTRIBUTION_INDEX), def.push(P_MUTATION_DISTRIBUTION_INDEX));
477            polynomialIsAlternative = state.parameters.getBoolean(base.push(P_POLYNOMIAL_ALTERNATIVE), def.push(P_POLYNOMIAL_ALTERNATIVE), true);
478
479            outOfBoundsRetries = state.parameters.getIntWithDefault(base.push(P_OUTOFBOUNDS_RETRIES), def.push(P_OUTOFBOUNDS_RETRIES), outOfBoundsRetries);
480            if(outOfBoundsRetries<0)
481                {
482                state.output.fatal(
483                    "If it's going to use polynomial mutation, FloatvectorSpecies must have a positive number of out-of-bounds retries or 0 (for don't give up).  " +
484                    "This is even the case if doing so-called \"bounded\" polynomial mutation, which auto-bounds anyway, or if the mutation is unbounded.  " +
485                    "In either case, just provide an arbitrary value, which will be ignored.",
486                    base.push(P_OUTOFBOUNDS_RETRIES), def.push(P_OUTOFBOUNDS_RETRIES));
487                }
488            }
489               
490        if (mutationType == C_GAUSS_MUTATION)
491            {
492            gaussMutationStdev = state.parameters.getDouble(base.push(P_STDEV),def.push(P_STDEV), 0);
493            if (gaussMutationStdev <= 0)
494                state.output.fatal("If it's going to use gaussian mutation, FloatvectorSpecies must have a strictly positive standard deviation",
495                    base.push(P_STDEV), def.push(P_STDEV));
496                       
497            outOfBoundsRetries = state.parameters.getIntWithDefault(base.push(P_OUTOFBOUNDS_RETRIES), def.push(P_OUTOFBOUNDS_RETRIES), outOfBoundsRetries);
498            if(outOfBoundsRetries<0)
499                {
500                state.output.fatal(
501                    "If it's going to use gaussian mutation, FloatvectorSpecies must have a positive number of out-of-bounds retries or 0 (for don't give up).  " +
502                    "This is even the case if the mutation is unbounded.  In that case, just provide an arbitrary value, which will be ignored.",
503                    base.push(P_OUTOFBOUNDS_RETRIES), def.push(P_OUTOFBOUNDS_RETRIES));
504                }
505            }           
506        /*
507        //Debugging
508        for(int i = 0; i < minGenes.length; i++)
509        System.out.println("Min: " + minGenes[i] + ", Max: " + maxGenes[i]);
510        */
511        }
512       
513       
514    private void initializeGenomeSegmentsByStartIndices(final EvolutionState state,
515        final Parameter base,
516        final Parameter def,
517        int numSegments,
518        double minGene, double maxGene)
519        {
520        boolean warnedMin = false;
521        boolean warnedMax = false;
522        double currentSegmentMinGeneValue = Double.MAX_VALUE;
523        double currentSegmentMaxGeneValue = Double.MIN_VALUE;
524               
525        //loop in reverse order
526        int previousSegmentEnd = genomeSize;
527        int currentSegmentEnd = 0;
528               
529        for (int i = numSegments - 1; i >= 0; i--)
530            {
531            //check if the segment data exist
532            if (state.parameters.exists(base.push(P_SEGMENT).push(""+i).push(P_SEGMENT_START),
533                    def.push(P_SEGMENT).push(""+i).push(P_SEGMENT_START)))
534                {
535                //Read the index of the end gene specifying current segment
536                currentSegmentEnd = state.parameters.getInt(base.push(P_SEGMENT).push(""+i).push(P_SEGMENT_START),
537                    def.push(P_SEGMENT).push(""+i).push(P_SEGMENT_START));
538                               
539                }
540            else
541                {
542                state.output.fatal("Genome segment " + i + " has not been defined!" +
543                    "\nYou must specify start indices for " + numSegments + " segment(s)",
544                    base.push(P_SEGMENT).push(""+i).push(P_SEGMENT_START),
545                    base.push(P_SEGMENT).push(""+i).push(P_SEGMENT_START));
546                }
547                       
548            //check if the start index is valid
549            if(currentSegmentEnd >= previousSegmentEnd || currentSegmentEnd < 0)
550                state.output.fatal(
551                    "Invalid start index value for segment " + i + ": " + currentSegmentEnd
552                    +  "\nThe value must be smaller than " + previousSegmentEnd +
553                    " and greater than or equal to  " + 0);
554                       
555            //check if the index of the first segment is equal to 0
556            if(i == 0 && currentSegmentEnd != 0)
557                state.output.fatal(
558                    "Invalid start index value for the first segment " + i + ": " + currentSegmentEnd
559                    +  "\nThe value must be equal to " + 0);
560                       
561                       
562            //get min and max values of genes in this segment
563            if (!state.parameters.exists(base.push(P_SEGMENT).push(""+i).push(P_MINGENE),
564                    base.push(P_SEGMENT).push(""+i).push(P_MINGENE)))
565                {
566                if (!warnedMin)
567                    {
568                    state.output.warning(
569                        "IntegerVectorSpecies has missing min-gene values for some segments.\n"
570                        + "The first segment is #" + i + ".",
571                        base.push(P_SEGMENT).push(""+i),
572                        base.push(P_SEGMENT).push(""+i));
573                    warnedMin = true;
574                    }
575                               
576                //the min-gene value has not been defined for this segment so assume the global min value
577                currentSegmentMinGeneValue = minGene;
578                }
579            else  //get the min value for this segment
580                {
581                currentSegmentMinGeneValue = state.parameters.getDoubleWithDefault(
582                    base.push(P_SEGMENT).push(""+i).push(P_MINGENE),
583                    base.push(P_SEGMENT).push(""+i).push(P_MINGENE),
584                    minGene);
585                               
586                //check if the value is in range
587                if (!inNumericalTypeRange(currentSegmentMinGeneValue))
588                    state.output
589                        .error(
590                            "This IntegerVectorSpecies has a prototype of the kind: "
591                            + i_prototype.getClass()
592                            .getName()
593                            + ", but doesn't have a min-gene "
594                            + " value for segment " + i
595                            + " within the range of this prototype's genome's data types",
596                            base.push(P_SEGMENT).push(""+i).push(P_MINGENE),
597                            base.push(P_SEGMENT).push(""+i).push(P_MINGENE));
598                               
599                }
600                       
601            if (!state.parameters.exists(base.push(P_SEGMENT).push(""+i).push(P_MAXGENE),
602                    base.push(P_SEGMENT).push(""+i).push(P_MAXGENE)))
603                {
604                if (!warnedMax)
605                    {
606                    state.output.warning(
607                        "IntegerVectorSpecies has missing max-gene values for some segments.\n"
608                        + "The first segment is #" + i + ".",
609                        base.push(P_SEGMENT).push(""+i),
610                        base.push(P_SEGMENT).push(""+i));
611                    warnedMax = true;
612                    }
613                               
614                //the max-gen value has not been defined for this segment so assume the global max value
615                currentSegmentMaxGeneValue = maxGene;
616                               
617                }
618            else   //get the max value for this segment
619                {
620                currentSegmentMaxGeneValue = state.parameters.getDoubleWithDefault(
621                    base.push(P_SEGMENT).push(""+i).push(P_MAXGENE),
622                    base.push(P_SEGMENT).push(""+i).push(P_MAXGENE),
623                    maxGene);
624                               
625                //check if the value is in range
626                if (!inNumericalTypeRange(currentSegmentMaxGeneValue))
627                    state.output
628                        .fatal(
629                            "This IntegerVectorSpecies has a prototype of the kind: "
630                            + i_prototype.getClass()
631                            .getName()
632                            + ", but doesn't have a max-gene "
633                            + " value for segment " + i
634                            + " within the range of this prototype's genome's data types",
635                            base.push(P_SEGMENT).push(""+i).push(P_MAXGENE),
636                            base.push(P_SEGMENT).push(""+i).push(P_MAXGENE));
637                }
638
639            //check is min is smaller than or equal to max
640            if (currentSegmentMaxGeneValue < currentSegmentMinGeneValue)
641                state.output.fatal(
642                    "IntegerVectorSpecies must have a min-gene value for segment "
643                    + i + " which is <= the max-gene value",
644                    base.push(P_SEGMENT).push(""+i).push(P_MAXGENE),
645                    base.push(P_SEGMENT).push(""+i).push(P_MAXGENE));
646
647                       
648            //and assign min and max values for all genes in this segment
649            for(int j = previousSegmentEnd-1; j >= currentSegmentEnd; j--)
650                {
651                minGenes[j] = currentSegmentMinGeneValue;
652                maxGenes[j] = currentSegmentMaxGeneValue;
653                }
654                       
655            previousSegmentEnd = currentSegmentEnd;
656                       
657            }
658               
659        }
660       
661    private void initializeGenomeSegmentsByEndIndices(final EvolutionState state,
662        final Parameter base,
663        final Parameter def,
664        int numSegments,
665        double minGene, double maxGene)
666        {
667        boolean warnedMin = false;
668        boolean warnedMax = false;
669        double currentSegmentMinGeneValue = Double.MAX_VALUE;
670        double currentSegmentMaxGeneValue = Double.MIN_VALUE;
671               
672        int previousSegmentEnd = -1; 
673        int currentSegmentEnd = 0;
674        // iterate over segments and set genes values for each segment
675        for (int i = 0; i < numSegments; i++)
676            {
677            //check if the segment data exist
678            if (state.parameters.exists(base.push(P_SEGMENT).push(""+i).push(P_SEGMENT_END), def.push(P_SEGMENT).push(""+i).push(P_SEGMENT_END)))
679                {
680                //Read the index of the end gene specifying current segment
681                currentSegmentEnd = state.parameters.getInt(base.push(P_SEGMENT).push(""+i).push(P_SEGMENT_END),
682                    def.push(P_SEGMENT).push(""+i).push(P_SEGMENT_END));
683                               
684                }
685            else
686                {
687                state.output.fatal("Genome segment " + i + " has not been defined!" +
688                    "\nYou must specify end indices for " + numSegments + " segment(s)",
689                    base.push(P_SEGMENT).push(""+i).push(P_SEGMENT_END),
690                    base.push(P_SEGMENT).push(""+i).push(P_SEGMENT_END));
691                }
692                       
693            //check if the end index is valid
694            if(currentSegmentEnd <= previousSegmentEnd || currentSegmentEnd >= genomeSize)
695                state.output.fatal(
696                    "Invalid end index value for segment " + i + ": " + currentSegmentEnd
697                    +  "\nThe value must be greater than " + previousSegmentEnd +
698                    " and smaller than " + genomeSize);
699                       
700            //check if the index of the final segment is equal to the genomeSize
701            if(i == numSegments - 1 && currentSegmentEnd != (genomeSize-1))
702                state.output.fatal(
703                    "Invalid end index value for the last segment " + i + ": " + currentSegmentEnd
704                    +  "\nThe value must be equal to the index of the last gene in the genome:  " + (genomeSize-1));
705                       
706                       
707            //get min and max values of genes in this segment
708            if (!state.parameters.exists(base.push(P_SEGMENT).push(""+i).push(P_MINGENE),
709                    base.push(P_SEGMENT).push(""+i).push(P_MINGENE)))
710                {
711                if (!warnedMin)
712                    {
713                    state.output.warning(
714                        "IntegerVectorSpecies has missing min-gene values for some segments.\n"
715                        + "The first segment is #" + i + ".",
716                        base.push(P_SEGMENT).push(""+i),
717                        base.push(P_SEGMENT).push(""+i));
718                    warnedMin = true;
719                    }
720                               
721                //the min-gene value has not been defined for this segment so assume the global min value
722                currentSegmentMinGeneValue = minGene;
723                }
724            else  //get the min value for this segment
725                {
726                currentSegmentMinGeneValue = state.parameters.getDoubleWithDefault(
727                    base.push(P_SEGMENT).push(""+i).push(P_MINGENE),
728                    base.push(P_SEGMENT).push(""+i).push(P_MINGENE),
729                    minGene);
730                               
731                //check if the value is in range
732                if (!inNumericalTypeRange(currentSegmentMinGeneValue))
733                    state.output
734                        .error(
735                            "This IntegerVectorSpecies has a prototype of the kind: "
736                            + i_prototype.getClass()
737                            .getName()
738                            + ", but doesn't have a min-gene "
739                            + " value for segment " + i
740                            + " within the range of this prototype's genome's data types",
741                            base.push(P_SEGMENT).push(""+i).push(P_MINGENE),
742                            base.push(P_SEGMENT).push(""+i).push(P_MINGENE));
743                               
744                }
745                       
746            if (!state.parameters.exists(base.push(P_SEGMENT).push(""+i).push(P_MAXGENE),
747                    base.push(P_SEGMENT).push(""+i).push(P_MAXGENE)))
748                {
749                if (!warnedMax)
750                    {
751                    state.output.warning(
752                        "IntegerVectorSpecies has missing max-gene values for some segments.\n"
753                        + "The first segment is #" + i + ".",
754                        base.push(P_SEGMENT).push(""+i),
755                        base.push(P_SEGMENT).push(""+i));
756                    warnedMax = true;
757                    }
758                               
759                //the max-gen value has not been defined for this segment so assume the global max value
760                currentSegmentMaxGeneValue = maxGene;
761                               
762                }
763            else   //get the max value for this segment
764                {
765                currentSegmentMaxGeneValue = state.parameters.getDoubleWithDefault(
766                    base.push(P_SEGMENT).push(""+i).push(P_MAXGENE),
767                    base.push(P_SEGMENT).push(""+i).push(P_MAXGENE),
768                    maxGene);
769                               
770                //check if the value is in range
771                if (!inNumericalTypeRange(currentSegmentMaxGeneValue))
772                    state.output
773                        .fatal(
774                            "This IntegerVectorSpecies has a prototype of the kind: "
775                            + i_prototype.getClass()
776                            .getName()
777                            + ", but doesn't have a max-gene "
778                            + " value for segment " + i
779                            + " within the range of this prototype's genome's data types",
780                            base.push(P_SEGMENT).push(""+i).push(P_MAXGENE),
781                            base.push(P_SEGMENT).push(""+i).push(P_MAXGENE));
782                }
783
784            //check is min is smaller than or equal to max
785            if (currentSegmentMaxGeneValue < currentSegmentMinGeneValue)
786                state.output.fatal(
787                    "IntegerVectorSpecies must have a min-gene value for segment "
788                    + i + " which is <= the max-gene value",
789                    base.push(P_SEGMENT).push(""+i).push(P_MAXGENE),
790                    base.push(P_SEGMENT).push(""+i).push(P_MAXGENE));
791
792                       
793            //and assign min and max values for all genes in this segment
794            for(int j = previousSegmentEnd+1; j <= currentSegmentEnd; j++)
795                {
796                minGenes[j] = currentSegmentMinGeneValue;
797                maxGenes[j] = currentSegmentMaxGeneValue;
798                }
799                       
800            previousSegmentEnd = currentSegmentEnd;
801                       
802            }
803        }
804    }
Note: See TracBrowser for help on using the repository browser.