Clover coverage report - JGAP 3.1
Coverage timestamp: Mo Dez 11 2006 21:16:18 CET
file stats: LOC: 412   Methods: 15
NCLOC: 187   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
BooleanGene.java 92,3% 93,2% 100% 93,6%
coverage coverage
 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 {
 31    /** String containing the CVS revision. Read out via reflection!*/
 32    private final static String CVS_REVISION = "$Revision: 1.29 $";
 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 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 FALSE_BOOLEAN = Boolean.valueOf(false);
 47   
 48    /**
 49    * References the internal boolean value of this Gene.
 50    */
 51    private Boolean 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  1 public BooleanGene()
 63    throws InvalidConfigurationException {
 64  1 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  9235 public BooleanGene(final Configuration a_config)
 75    throws InvalidConfigurationException {
 76  9235 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  3 public BooleanGene(final Configuration a_config, final boolean a_value)
 88    throws InvalidConfigurationException {
 89  3 super(a_config);
 90  3 m_value = new Boolean(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  3 public BooleanGene(final Configuration a_config, final Boolean a_value)
 102    throws InvalidConfigurationException {
 103  3 super(a_config);
 104  3 if (a_value == null) {
 105  1 throw new IllegalArgumentException("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  2 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  3541 protected Gene newGeneInternal() {
 126  3541 try {
 127  3541 return new BooleanGene(getConfiguration());
 128    }
 129    catch (InvalidConfigurationException iex) {
 130  0 throw new IllegalStateException(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  2660 public void setAllele(final Object a_newValue) {
 141  2660 m_value = (Boolean) 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  100 public String getPersistentRepresentation() {
 159  100 String s;
 160  100 if (getInternalValue() == null) {
 161  2 s = "null";
 162    }
 163    else {
 164  98 s = getInternalValue().toString();
 165    }
 166  100 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  104 public void setValueFromPersistentRepresentation(String a_representation)
 190    throws UnsupportedRepresentationException {
 191  104 if (a_representation != null) {
 192  103 if (a_representation.equals("null")) {
 193  2 m_value = null;
 194    }
 195  101 else if (a_representation.equals("true")) {
 196  56 m_value = TRUE_BOOLEAN;
 197    }
 198  45 else if (a_representation.equals("false")) {
 199  39 m_value = FALSE_BOOLEAN;
 200    }
 201    else {
 202  6 throw new UnsupportedRepresentationException(
 203    "Unknown boolean gene representation: " +
 204    a_representation);
 205    }
 206    }
 207    else {
 208  1 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  39 public boolean booleanValue() {
 220  39 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  226 public void setToRandomValue(RandomGenerator a_numberGenerator) {
 240  226 if (a_numberGenerator.nextBoolean() == true) {
 241  118 m_value = TRUE_BOOLEAN;
 242    }
 243    else {
 244  108 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  11120 public int compareTo(Object a_other) {
 265  11120 BooleanGene otherBooleanGene = (BooleanGene) a_other;
 266    // First, if the other gene is null, then this is the greater gene.
 267    // ----------------------------------------------------------------
 268  4881 if (otherBooleanGene == null) {
 269  2 return 1;
 270    }
 271  4879 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  4112 if (m_value != null) {
 276  2 return 1;
 277    }
 278    else {
 279  4110 if (isCompareApplicationData()) {
 280  1 return compareApplicationData(getApplicationData(),
 281    otherBooleanGene.getApplicationData());
 282    }
 283    else {
 284  4109 return 0;
 285    }
 286    }
 287    }
 288  767 if (m_value == null) {
 289  2 if (otherBooleanGene.m_value == null) {
 290  0 if (isCompareApplicationData()) {
 291  0 return compareApplicationData(getApplicationData(),
 292    otherBooleanGene.getApplicationData());
 293    }
 294    else {
 295  0 return 0;
 296    }
 297    }
 298    else {
 299  2 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  765 if (m_value.booleanValue() == false) {
 306  447 if (otherBooleanGene.m_value.booleanValue() == false) {
 307    // Both are false and therefore the same. Compare application data.
 308    // ----------------------------------------------------------------
 309  299 if (isCompareApplicationData()) {
 310  2 return compareApplicationData(getApplicationData(),
 311    otherBooleanGene.getApplicationData());
 312    }
 313    else {
 314  297 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  148 return -1;
 322    }
 323    }
 324  318 else if (otherBooleanGene.m_value.booleanValue() == true) {
 325    // Both alleles are true and therefore the same. Compare application data.
 326    // -----------------------------------------------------------------------
 327  159 if (isCompareApplicationData()) {
 328  0 return compareApplicationData(getApplicationData(),
 329    otherBooleanGene.getApplicationData());
 330    }
 331    else {
 332  159 return 0;
 333    }
 334    }
 335    else {
 336    // This allele is true, but the other is false. This allele is
 337    // the greater.
 338    // -----------------------------------------------------------
 339  159 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  77 public void applyMutation(int a_index, double a_percentage) {
 354  77 if (m_value == null) {
 355  12 m_value = Boolean.valueOf(false);
 356    }
 357  65 else if (a_percentage > 0) {
 358    // change to TRUE
 359    // ---------------
 360  21 if (!m_value.booleanValue()) {
 361  12 m_value = Boolean.valueOf(true);
 362    }
 363    }
 364  44 else if (a_percentage < 0) {
 365    // change to FALSE
 366    // ---------------
 367  43 if (m_value.booleanValue()) {
 368  23 m_value = Boolean.valueOf(false);
 369    }
 370    }
 371    }
 372   
 373  12943 protected Object getInternalValue() {
 374  12943 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  10175 public int hashCode() {
 386  10175 if (getInternalValue() == null) {
 387  10165 return -2;
 388    }
 389    else {
 390  10 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  9 public String toString() {
 402  9 String s = "BooleanGene"
 403    + "=";
 404  9 if (getInternalValue() == null) {
 405  6 s += "null";
 406    }
 407    else {
 408  3 s += getInternalValue().toString();
 409    }
 410  9 return s;
 411    }
 412    }