KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jgap > impl > BooleanGene


1 /*
2  * This file is part of JGAP.
3  *
4  * JGAP offers a dual license model containing the LGPL as well as the MPL.
5  *
6  * For licencing information please see the file license.txt included with JGAP
7  * or have a look at the top of class org.jgap.Chromosome which representatively
8  * includes the JGAP license policy applicable for any file delivered with JGAP.
9  */

10 package org.jgap.impl;
11
12 import org.jgap.*;
13
14 /**
15  * A Gene implementation that supports two possible values (alleles) for each
16  * gene: true and false.
17  * <p>
18  * NOTE: Since this Gene implementation only supports two different
19  * values (true and false), there's only a 50% chance that invocation
20  * of the setToRandomValue() method will actually change the value of
21  * this Gene (if it has a value). As a result, it may be desirable to
22  * use a higher overall mutation rate when this Gene implementation
23  * is in use.
24  *
25  * @author Neil Rotstan
26  * @author Klaus Meffert
27  * @since 1.0
28  */

29 public class BooleanGene
30     extends BaseGene implements IPersistentRepresentation {
31   /** String containing the CVS revision. Read out via reflection!*/
32   private final static String JavaDoc CVS_REVISION = "$Revision: 1.30 $";
33
34   /**
35    * Shared constant representing the "true" boolean value. Shared constants
36    * are used to save memory so that a new Boolean object doesn't have to
37    * be constructed each time.
38    */

39   protected static final Boolean JavaDoc TRUE_BOOLEAN = Boolean.valueOf(true);
40
41   /**
42    * Shared constant representing the "false" boolean value. Shared constants
43    * are used to save memory so that a new Boolean object doesn't have to
44    * be constructed each time.
45    */

46   protected static final Boolean JavaDoc FALSE_BOOLEAN = Boolean.valueOf(false);
47
48   /**
49    * References the internal boolean value of this Gene.
50    */

51   private Boolean JavaDoc m_value;
52
53   /**
54    * Default constructor.<p>
55    * Attention: The configuration used is the one set with the static method
56    * Genotype.setConfiguration.
57    * @throws InvalidConfigurationException
58    *
59    * @author Klaus Meffert
60    * @since 2.4
61    */

62   public BooleanGene()
63       throws InvalidConfigurationException {
64     this(Genotype.getStaticConfiguration());
65   }
66
67   /**
68    * @param a_config the configuration to use
69    * @throws InvalidConfigurationException
70    *
71    * @author Klaus Meffert
72    * @since 3.0
73    */

74   public BooleanGene(final Configuration a_config)
75       throws InvalidConfigurationException {
76     super(a_config);
77   }
78
79   /**
80    * @param a_config the configuration to use
81    * @param a_value allele value to setup the gene with
82    * @throws InvalidConfigurationException
83    *
84    * @author Klaus Meffert
85    * @since 2.4
86    */

87   public BooleanGene(final Configuration a_config, final boolean a_value)
88       throws InvalidConfigurationException {
89     super(a_config);
90     m_value = new Boolean JavaDoc(a_value);
91   }
92
93   /**
94    * @param a_config the configuration to use
95    * @param a_value allele value to setup the gene with
96    * @throws InvalidConfigurationException
97    *
98    * @author Klaus Meffert
99    * @since 2.4
100    */

101   public BooleanGene(final Configuration a_config, final Boolean JavaDoc a_value)
102       throws InvalidConfigurationException {
103     super(a_config);
104     if (a_value == null) {
105       throw new IllegalArgumentException JavaDoc("Allele value may not be null. Use"
106                                          + " no argument constructor if you"
107                                          + " need to set allele to null"
108                                          + " initially.");
109     }
110     else {
111       m_value = a_value;
112     }
113   }
114
115   /**
116    * Provides an implementation-independent means for creating new Gene
117    * instances.
118    *
119    * @return a new Gene instance of the same type and with the same setup as
120    * this concrete Gene
121    *
122    * @author Neil Rotstan
123    * @author Klaus Meffert
124    */

125   protected Gene newGeneInternal() {
126     try {
127       return new BooleanGene(getConfiguration());
128     }
129     catch (InvalidConfigurationException iex) {
130       throw new IllegalStateException JavaDoc(iex.getMessage());
131     }
132   }
133
134   /**
135    * Sets the value of this Gene to the new given value. This class
136    * expects the value to be a Boolean instance.
137    *
138    * @param a_newValue the new value of this Gene instance
139    */

140   public void setAllele(final Object JavaDoc a_newValue) {
141     m_value = (Boolean JavaDoc) a_newValue;
142   }
143
144   /**
145    * Retrieves a string representation of this Gene that includes any
146    * information required to reconstruct it at a later time, such as its
147    * value and internal state. This string will be used to represent this
148    * Gene in XML persistence. This is an optional method but, if not
149    * implemented, XML persistence and possibly other features will not be
150    * available. An UnsupportedOperationException should be thrown if no
151    * implementation is provided.
152    *
153    * @return a string representation of this Gene's current state
154    *
155    * @author Neil Rotstan
156    * @author Klaus Meffert
157    */

158   public String JavaDoc getPersistentRepresentation() {
159     String JavaDoc s;
160     if (getInternalValue() == null) {
161       s = "null";
162     }
163     else {
164       s = getInternalValue().toString();
165     }
166     return s;
167   }
168
169   /**
170    * Sets the value and internal state of this Gene from the string
171    * representation returned by a previous invocation of the
172    * getPersistentRepresentation() method. This is an optional method but,
173    * if not implemented, XML persistence and possibly other features will not
174    * be available. An UnsupportedOperationException should be thrown if no
175    * implementation is provided.
176    *
177    * @param a_representation the string representation retrieved from a
178    * prior call to the getPersistentRepresentation() method.
179    *
180    * @throws UnsupportedOperationException to indicate that no implementation
181    * is provided for this method.
182    * @throws UnsupportedRepresentationException if this Gene implementation
183    * does not support the given string representation.
184    *
185    * @author Neil Rotstan
186    * @author Klaus Meffert
187    * @since 1.0
188    */

189   public void setValueFromPersistentRepresentation(String JavaDoc a_representation)
190       throws UnsupportedRepresentationException {
191     if (a_representation != null) {
192       if (a_representation.equals("null")) {
193         m_value = null;
194       }
195       else if (a_representation.equals("true")) {
196         m_value = TRUE_BOOLEAN;
197       }
198       else if (a_representation.equals("false")) {
199         m_value = FALSE_BOOLEAN;
200       }
201       else {
202         throw new UnsupportedRepresentationException(
203             "Unknown boolean gene representation: " +
204             a_representation);
205       }
206     }
207     else {
208       throw new UnsupportedRepresentationException(
209           "The input parameter must not be null!");
210     }
211   }
212
213   /**
214    * Retrieves the boolean value of this Gene. This may be more convenient
215    * in some cases than the more general getAllele() method.
216    *
217    * @return the boolean value of this Gene
218    */

219   public boolean booleanValue() {
220     return m_value.booleanValue();
221   }
222
223   /**
224    * Sets the value (allele) of this Gene to a random legal value. This
225    * method exists for the benefit of mutation and other operations that
226    * simply desire to randomize the value of a gene.
227    * <p>
228    * NOTE: Since this Gene implementation only supports two different
229    * values (true and false), there's only a 50% chance that invocation
230    * of this method will actually change the value of this Gene (if
231    * it has a value). As a result, it may be desirable to use a higher
232    * overall mutation rate when this Gene implementation is in use.
233    *
234    * @param a_numberGenerator The random number generator that should be
235    * used to create any random values. It's important to use this generator to
236    * maintain the user's flexibility to configure the genetic engine to use the
237    * random number generator of their choice
238    */

239   public void setToRandomValue(RandomGenerator a_numberGenerator) {
240     if (a_numberGenerator.nextBoolean() == true) {
241       m_value = TRUE_BOOLEAN;
242     }
243     else {
244       m_value = FALSE_BOOLEAN;
245     }
246   }
247
248   /**
249    * Compares this BooleanGene with the specified object for order. A
250    * false value is considered to be less than a true value. A null value
251    * is considered to be less than any non-null value.
252    *
253    * @param a_other the BooleanGene to be compared
254    * @return a negative integer, zero, or a positive integer as this object
255    * is less than, equal to, or greater than the specified object
256    *
257    * @throws ClassCastException if the specified object's type prevents it
258    * from being compared to this BooleanGene
259    *
260    * @author Neil Rotstan
261    * @author Klaus Meffert
262    * @since 1.0
263    */

264   public int compareTo(Object JavaDoc a_other) {
265     BooleanGene otherBooleanGene = (BooleanGene) a_other;
266     // First, if the other gene is null, then this is the greater gene.
267
// ----------------------------------------------------------------
268
if (otherBooleanGene == null) {
269       return 1;
270     }
271     else if (otherBooleanGene.m_value == null) {
272       // If our value is also null, then we're possibly the same. Otherwise,
273
// we're the greater gene.
274
// -------------------------------------------------------------------
275
if (m_value != null) {
276         return 1;
277       }
278       else {
279         if (isCompareApplicationData()) {
280           return compareApplicationData(getApplicationData(),
281                                         otherBooleanGene.getApplicationData());
282         }
283         else {
284           return 0;
285         }
286       }
287     }
288     if (m_value == null) {
289       if (otherBooleanGene.m_value == null) {
290         if (isCompareApplicationData()) {
291           return compareApplicationData(getApplicationData(),
292                                         otherBooleanGene.getApplicationData());
293         }
294         else {
295           return 0;
296         }
297       }
298       else {
299         return -1;
300       }
301     }
302     // The Boolean class doesn't implement the Comparable interface, so
303
// we have to do the comparison ourselves.
304
// ----------------------------------------------------------------
305
if (m_value.booleanValue() == false) {
306       if (otherBooleanGene.m_value.booleanValue() == false) {
307         // Both are false and therefore the same. Compare application data.
308
// ----------------------------------------------------------------
309
if (isCompareApplicationData()) {
310           return compareApplicationData(getApplicationData(),
311                                         otherBooleanGene.getApplicationData());
312         }
313         else {
314           return 0;
315         }
316       }
317       else {
318         // This allele is false, but the other one is true. This
319
// allele is the lesser.
320
// -----------------------------------------------------
321
return -1;
322       }
323     }
324     else if (otherBooleanGene.m_value.booleanValue() == true) {
325       // Both alleles are true and therefore the same. Compare application data.
326
// -----------------------------------------------------------------------
327
if (isCompareApplicationData()) {
328         return compareApplicationData(getApplicationData(),
329                                       otherBooleanGene.getApplicationData());
330       }
331       else {
332         return 0;
333       }
334     }
335     else {
336       // This allele is true, but the other is false. This allele is
337
// the greater.
338
// -----------------------------------------------------------
339
return 1;
340     }
341   }
342
343   /**
344    * Applies a mutation of a given intensity (percentage) onto the atomic
345    * element at given index
346    * @param a_index not used here
347    * @param a_percentage percentage of mutation (greater than -1 and smaller
348    * than 1).
349    *
350    * @author Klaus Meffert
351    * @since 1.1
352    */

353   public void applyMutation(int a_index, double a_percentage) {
354     if (m_value == null) {
355       m_value = Boolean.valueOf(false);
356     }
357     else if (a_percentage > 0) {
358       // change to TRUE
359
// ---------------
360
if (!m_value.booleanValue()) {
361         m_value = Boolean.valueOf(true);
362       }
363     }
364     else if (a_percentage < 0) {
365       // change to FALSE
366
// ---------------
367
if (m_value.booleanValue()) {
368         m_value = Boolean.valueOf(false);
369       }
370     }
371   }
372
373   protected Object JavaDoc getInternalValue() {
374     return m_value;
375   }
376
377   /**
378    * Modified hashCode() function to return different hashcodes for differently
379    * ordered genes in a chromosome
380    * @return -2 if no allele set, otherwise value return by BaseGene.hashCode()
381    *
382    * @author Klaus Meffert
383    * @since 2.2
384    */

385   public int hashCode() {
386     if (getInternalValue() == null) {
387       return -2;
388     }
389     else {
390       return super.hashCode();
391     }
392   }
393
394   /**
395    * @return string representation of this Gene's value that may be useful for
396    * display purposes.
397    *
398    * @author Klaus Meffert
399    * @since 2.4
400    */

401   public String JavaDoc toString() {
402     String JavaDoc s = "BooleanGene"
403         + "=";
404     if (getInternalValue() == null) {
405       s += "null";
406     }
407     else {
408       s += getInternalValue().toString();
409     }
410     return s;
411   }
412 }
413
Popular Tags