KickJava   Java API By Example, From Geeks To Geeks.

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


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 java.util.*;
13 import org.jgap.*;
14
15 /**
16  * ATTENTION: This class is preliminary and subject of future adaptations! Use
17  * with care or wait for a more mature version we are working on.
18  * <p>
19  * Creates a gene instance in which individual alleles have both a label (key)
20  * and a value with a distinct meaning. For example, IntegerGene only allows
21  * for values having a continuous range, and does not have a function where it
22  * is possible to specify setValue...
23  *
24  * @author Johnathan Kool (RSMAS, University of Miami)
25  * @since 2.4
26  */

27 public class SetGene
28     extends BaseGene implements IPersistentRepresentation {
29   /** String containing the CVS revision. Read out via reflection!*/
30   private final static String JavaDoc CVS_REVISION = "$Revision: 1.15 $";
31
32   private HashSet m_geneSet = new HashSet();
33
34   private Object JavaDoc m_value;
35
36   /**
37    * Default constructor.<p>
38    * Attention: The configuration used is the one set with the static method
39    * Genotype.setConfiguration.
40    * @throws InvalidConfigurationException
41    */

42   public SetGene()
43       throws InvalidConfigurationException {
44     this(Genotype.getStaticConfiguration());
45   }
46
47   /**
48    * @param a_conf the configuration to use
49    * @throws InvalidConfigurationException
50    *
51    * @author Klaus Meffert
52    * @since 3.0
53    */

54   public SetGene(final Configuration a_conf)
55       throws InvalidConfigurationException {
56     super(a_conf);
57   }
58
59   protected Gene newGeneInternal() {
60     try {
61       return new SetGene(getConfiguration());
62     }
63     catch (InvalidConfigurationException iex) {
64       throw new IllegalStateException JavaDoc(iex.getMessage());
65     }
66   }
67
68   /**
69    * Adds a potential allele value to the collection.
70    *
71    * @param a_value the Integer value to be added
72    */

73   public void addAllele(final Object JavaDoc a_value) {
74     m_geneSet.add(a_value);
75   }
76
77   /**
78    * Add a set of potential allele values to the collection
79    *
80    * @param a_alleles the set of alleles to be added
81    */

82   public void addAlleles(final Collection a_alleles) {
83     m_geneSet.addAll(a_alleles);
84   }
85
86   /**
87    * Removes a potential allele or set of alleles from the collection.
88    *
89    * @param a_key the unique value(s) of the object(s) to be removed
90    */

91   public void removeAlleles(final Object JavaDoc a_key) {
92     m_geneSet.remove(a_key);
93   }
94
95   /**
96    * Sets the allele value to be a random value using a defined random number
97    * generator.
98    *
99    * @author Johnathan Kool
100    *
101    * @param a_numberGenerator RandomGenerator
102    */

103   public void setToRandomValue(final RandomGenerator a_numberGenerator) {
104     /**@todo make faster*/
105     m_value = m_geneSet.toArray()[a_numberGenerator.nextInt(
106         m_geneSet.size())];
107   }
108
109   /**
110    * See interface Gene for description of applyMutation.
111    *
112    * For this kind of gene, providing an index and a magnitude have no
113    * significance because the individual allele forms are independent
114    * of one another. In mutating, they can only cange from one form to
115    * another. It may be possible to weight the likelihood of mutation
116    * to different forms, but that will not be implemented here.
117    *
118    * @param a_index ignored here
119    * @param a_percentage ignored here
120    *
121    * @author Klaus Meffert
122    * @author Johnathan Kool
123    * @since 2.4
124    */

125   public void applyMutation(final int a_index, final double a_percentage) {
126     RandomGenerator rn;
127     if (getConfiguration() != null) {
128       rn = getConfiguration().getRandomGenerator();
129     }
130     else {
131       rn = getConfiguration().getJGAPFactory().createRandomGenerator();
132     }
133     setToRandomValue(rn);
134   }
135
136   /**
137    * Sets the value and internal state of this Gene from the string
138    * representation returned by a previous invocation of the
139    * getPersistentRepresentation() method. This is an optional method but,
140    * if not implemented, XML persistence and possibly other features will not
141    * be available. An UnsupportedOperationException should be thrown if no
142    * implementation is provided.
143    *
144    * @param a_representation the string representation retrieved from a
145    * prior call to the getPersistentRepresentation() method
146    * @throws UnsupportedRepresentationException if this Gene implementation
147    * does not support the given string representation
148    *
149    * @author Neil Rostan
150    * @since 1.0
151    */

152   public void setValueFromPersistentRepresentation(String JavaDoc a_representation)
153       throws UnsupportedRepresentationException {
154     if (a_representation != null) {
155       StringTokenizer tokenizer =
156           new StringTokenizer(a_representation,
157                               PERSISTENT_FIELD_DELIMITER);
158       // Make sure the representation contains the correct number of
159
// fields. If not, throw an exception.
160
// -----------------------------------------------------------
161
if (tokenizer.countTokens() < 3) {
162         throw new UnsupportedRepresentationException(
163             "The format of the given persistent representation " +
164             "is not recognized: it must contain at least three tokens.");
165       }
166       String JavaDoc valueRepresentation = tokenizer.nextToken();
167       // First parse and set the representation of the value.
168

169       // ----------------------------------------------------
170
if (valueRepresentation.equals("null")) {
171         m_value = null;
172       }
173       else {
174         try {
175           m_value =
176               new Integer JavaDoc(Integer.parseInt(valueRepresentation));
177         }
178         catch (NumberFormatException JavaDoc e) {
179           throw new UnsupportedRepresentationException(
180               "The format of the given persistent representation " +
181               "is not recognized: field 1 does not appear to be " +
182               "an integer value.");
183         }
184       }
185       // Parse the potential categories.
186
// -------------------------------
187
Integer JavaDoc allele;
188       while (tokenizer.hasMoreTokens()) {
189         try {
190           allele = new Integer JavaDoc(Integer.parseInt(tokenizer.nextToken()));
191           m_geneSet.add(allele);
192         }
193         catch (NumberFormatException JavaDoc e) {
194           throw new UnsupportedRepresentationException(
195               "The format of the given persistent representation "
196               + "is not recognized: a member of the list of eligible values "
197               + "does not appear to be an integer value.");
198         }
199       }
200     }
201   }
202
203   /**
204    * Retrieves a string representation of this Gene that includes any
205    * information required to reconstruct it at a later time, such as its
206    * value and internal state. This string will be used to represent this
207    * Gene in XML persistence. This is an optional method but, if not
208    * implemented, XML persistence and possibly other features will not be
209    * available. An UnsupportedOperationException should be thrown if no
210    * implementation is provided.
211    *
212    * @return a string representation of this Gene's current state
213    * @throws UnsupportedOperationException to indicate that no implementation
214    * is provided for this method
215    *
216    * @author Neil Rostan
217    * @since 1.0
218    */

219   public String JavaDoc getPersistentRepresentation()
220       throws
221       UnsupportedOperationException JavaDoc {
222     // The persistent representation includes the value, lower bound,
223
// and upper bound. Each is separated by a colon.
224
// --------------------------------------------------------------
225
Iterator it = m_geneSet.iterator();
226     StringBuffer JavaDoc strbf = new StringBuffer JavaDoc();
227     while (it.hasNext()) {
228       strbf.append(PERSISTENT_FIELD_DELIMITER);
229       strbf.append(it.next().toString());
230     }
231     return m_value.toString() + strbf.toString();
232   }
233
234   /**
235    * Sets the value (allele) of this Gene to the new given value. This class
236    * expects the value to be an instance of current type (e.g. Integer).
237    *
238    * @param a_newValue the new value of this Gene instance.
239    *
240    * @author Johnathan Kool
241    */

242   public void setAllele(Object JavaDoc a_newValue) {
243     if (m_geneSet.contains(a_newValue)) {
244       m_value = a_newValue;
245     }
246     else {
247       throw new IllegalArgumentException JavaDoc("Allele value being set is not an "
248                                          + "element of the set of permitted"
249                                          + " values.");
250     }
251   }
252
253   /**
254    * Compares this NumberGene with the specified object (which must also
255    * be a NumberGene) for order, which is determined by the number
256    * value of this Gene compared to the one provided for comparison.
257    *
258    * @param other the NumberGene to be compared to this NumberGene
259    * @return a negative integer, zero, or a positive integer as this object
260    * is less than, equal to, or greater than the object provided for comparison
261    *
262    * @throws ClassCastException if the specified object's type prevents it
263    * from being compared to this NumberGene
264    *
265    * @author Klaus Meffert
266    * @author Johnathan Kool
267    * @since 2.4
268    */

269   public int compareTo(Object JavaDoc other) {
270     SetGene otherGene = (SetGene) other;
271     // First, if the other gene (or its value) is null, then this is
272
// the greater allele. Otherwise, just use the overridden compareToNative
273
// method to perform the comparison.
274
// ---------------------------------------------------------------
275
if (otherGene == null) {
276       return 1;
277     }
278     else if (otherGene.m_value == null) {
279       // If our value is also null, then we're the same. Otherwise,
280
// this is the greater gene.
281
// ----------------------------------------------------------
282
return m_value == null ? 0 : 1;
283     }
284     else {
285       ICompareToHandler handler = getConfiguration().getJGAPFactory().
286           getCompareToHandlerFor(m_value, m_value.getClass());
287       if (handler != null) {
288         try {
289           return ( (Integer JavaDoc) handler.perform(m_value, null, otherGene.m_value)).
290               intValue();
291         }
292         catch (Exception JavaDoc ex) {
293           throw new Error JavaDoc(ex);
294         }
295       }
296       else {
297         return 0;
298       }
299     }
300   }
301
302   /**
303    * @return the internal value of the gene
304    * @since 2.4
305    */

306   protected Object JavaDoc getInternalValue() {
307     return m_value;
308   }
309
310   /**
311    * Modified hashCode() function to return different hashcodes for differently
312    * ordered genes in a chromosome
313    * @return -67 if no allele set, otherwise value return by BaseGene.hashCode()
314    *
315    * @author Klaus Meffert
316    * @since 2.4
317    */

318   public int hashCode() {
319     if (getInternalValue() == null) {
320       return -67;
321     }
322     else {
323       return super.hashCode();
324     }
325   }
326 }
327
Popular Tags