KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jgap > BaseGene


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;
11
12 /**
13  * Abstract base class for all genes. Provides default implementations.
14  *
15  * @author Klaus Meffert
16  * @since 2.2
17  */

18 public abstract class BaseGene
19     implements Gene {
20   /** String containing the CVS revision. Read out via reflection!*/
21   private final static String JavaDoc CVS_REVISION = "$Revision: 1.22 $";
22
23   /**
24    * Delta, useful for comparing doubles and floats.
25    */

26   public static final double DELTA = 0.0000001;
27
28   /** Energy of a gene, see RFE 1102206*/
29   private double m_energy;
30
31   /**
32    * Application-specific data that is attached to the Gene. This data may
33    * assist the application in labelling this Gene.
34    * JGAP ignores the data, aside from allowing it to be set and
35    * retrieved and considering it in clone() and compareTo().
36    *
37    * @since 2.4
38    */

39   private Object JavaDoc m_applicationData;
40
41   /**
42    * Method compareTo(): Should we also consider the application data when
43    * comparing? Default is "false" as "true" means a Gene's losing its
44    * identity when application data is set differently!
45    *
46    * @since 2.4
47    */

48   private boolean m_compareAppData;
49
50   private
51   /*transient*/ Configuration m_configuration;
52
53   /**
54    * Constants for toString()
55    */

56   public final static String JavaDoc S_APPLICATION_DATA = "Application data";
57
58   /**
59    *
60    * @param a_configuration the configuration to use
61    * @throws InvalidConfigurationException
62    *
63    * @author Klaus Meffert
64    * @since 3.0
65    */

66   public BaseGene(Configuration a_configuration)
67       throws InvalidConfigurationException {
68     if (a_configuration == null) {
69       throw new InvalidConfigurationException("Configuration must not be null!");
70     }
71     m_configuration = a_configuration;
72   }
73
74   /**
75    * Retrieves the allele value represented by this Gene.
76    *
77    * @return the allele value of this Gene
78    * @since 1.0
79    */

80   public Object JavaDoc getAllele() {
81     return getInternalValue();
82   }
83
84   /**
85    * Retrieves the hash code value for a Gene.
86    * Override if another hashCode() implementation is necessary or more
87    * appropriate than this default implementation.
88    *
89    * @return this Gene's hash code
90    *
91    * @author Neil Rotstan
92    * @author Klaus Meffert
93    * @since 1.0
94    */

95   public int hashCode() {
96     // If our internal value is null, then return zero. Otherwise,
97
// just return the hash code of the allele Object.
98
// -----------------------------------------------------------
99
if (getInternalValue() == null) {
100       return -79;
101     }
102     else {
103       return getInternalValue().hashCode();
104     }
105   }
106
107   /**
108    * Executed by the genetic engine when this Gene instance is no
109    * longer needed and should perform any necessary resource cleanup.
110    * If you need a special cleanup, override this method.
111    *
112    * @author Klaus Meffert
113    * @since 1.0
114    */

115   public void cleanup() {
116     // No specific cleanup is necessary by default.
117
// --------------------------------------------
118
}
119
120   /**
121    * Retrieves a string representation of this Gene's value that
122    * may be useful for display purposes.
123    *
124    * @return a string representation of this Gene's value
125    *
126    * @author Klaus Meffert
127    * @since 1.0
128    */

129   public String JavaDoc toString() {
130     String JavaDoc representation;
131     if (getInternalValue() == null) {
132       representation = "null";
133     }
134     else {
135       representation = getInternalValue().toString();
136     }
137     String JavaDoc appData;
138     if (getApplicationData() != null) {
139       appData = getApplicationData().toString();
140     }
141     else {
142       appData = "null";
143     }
144     representation += ", " + S_APPLICATION_DATA + ":" + appData;
145     return representation;
146   }
147
148   /**
149    * @return the size of the gene, i.e the number of atomic elements. Always 1
150    * for non-composed Gene types. Override for composed Gene types
151    *
152    * @author Neil Rotstan
153    * @since 1.0
154    */

155   public int size() {
156     return 1;
157   }
158
159   /**
160    * Compares this Gene with the given object and returns true if the other
161    * object is a Gene of the same type and has the same value (allele) as
162    * this Gene. Otherwise it returns false.
163    *
164    * @param a_other the object to compare to this Gene for equality
165    * @return true if this Gene is equal to the given object, false otherwise
166    *
167    * @author Klaus Meffert
168    * @since 1.1
169    */

170   public boolean equals(final Object JavaDoc a_other) {
171     try {
172       int result = compareTo(a_other);
173       if (result == 0) {
174         if (isCompareApplicationData()) {
175           Gene otherGene = (Gene) a_other;
176           int resultAppData = compareApplicationData(getApplicationData(),
177               otherGene.getApplicationData());
178           return resultAppData == 0;
179         }
180         else {
181           return true;
182         }
183       }
184       else {
185         return false;
186       }
187     } catch (ClassCastException JavaDoc e) {
188       // If the other object isn't an Gene of current type
189
// (like IntegerGene for IntegerGene's), then we're not equal.
190
// -----------------------------------------------------------
191
return false;
192     }
193   }
194
195   /**
196    * Each Gene implementation holds its own m_value object keeping the allele
197    * value. In your Gene implementation, just return it with this method
198    * (see {@link org.jgap.impl.BooleanGene} for example)
199    * @return the m_value object
200    *
201    * @author Klaus Meffert
202    * @since 2.2
203    */

204   protected abstract Object JavaDoc getInternalValue();
205
206   /**
207    * @return energy of the gene
208    *
209    * @author Klaus Meffert
210    * @since 2.3
211    */

212   public double getEnergy() {
213     return m_energy;
214   }
215
216   /**
217    * Sets the energy of the gene
218    * @param a_energy the energy to set
219    *
220    * @author Klaus Meffert
221    * @since 2.3
222    */

223   public void setEnergy(final double a_energy) {
224     m_energy = a_energy;
225   }
226
227   /**
228    * This sets the application-specific data that is attached to this Gene.
229    * Attaching application-specific data may be useful for
230    * some applications when it comes time to distinguish a Gene from another.
231    * JGAP ignores this data functionally.
232    *
233    * @param a_newData the new application-specific data to attach to this
234    * Gene
235    *
236    * @author Klaus Meffert
237    * @since 2.4
238    */

239   public void setApplicationData(final Object JavaDoc a_newData) {
240     m_applicationData = a_newData;
241   }
242
243   /**
244    * Retrieves the application-specific data that is attached to this Gene.
245    * Attaching application-specific data may be useful for
246    * some applications when it comes time to distinguish a Gene from another.
247    * JGAP ignores this data functionally.
248    *
249    * @return the application-specific data previously attached to this Gene,
250    * or null if there is no data attached
251    *
252    * @author Klaus Meffert
253    * @since 2.4
254    */

255   public Object JavaDoc getApplicationData() {
256     return m_applicationData;
257   }
258
259   /**
260    * Should we also consider the application data when comparing? Default is
261    * "false" as "true" means a Gene is losing its identity when
262    * application data is set differently!
263    *
264    * @param a_doCompare true: consider application data in method compareTo
265    *
266    * @author Klaus Meffert
267    * @since 2.4
268    */

269   public void setCompareApplicationData(final boolean a_doCompare) {
270     m_compareAppData = a_doCompare;
271   }
272
273   /*
274    * @return should we also consider the application data when comparing?
275    *
276    * @author Klaus Meffert
277    * @since 2.4
278    */

279   public boolean isCompareApplicationData() {
280     return m_compareAppData;
281   }
282
283   protected int compareApplicationData(final Object JavaDoc a_appdata1,
284                                        final Object JavaDoc a_appdata2) {
285     // Compare application data.
286
// -------------------------
287
if (a_appdata1 == null) {
288       if (a_appdata2 != null) {
289         return -1;
290       }
291       else {
292         return 0;
293       }
294     }
295     else if (a_appdata2 == null) {
296       return 1;
297     }
298     else {
299       // The above code is contained in the following, but for performance
300
// issues we keep it here redundantly.
301
// -----------------------------------------------------------------
302
ICompareToHandler handler = getConfiguration().getJGAPFactory().
303           getCompareToHandlerFor(a_appdata1, a_appdata2.getClass());
304       if (handler != null) {
305         try {
306           return ( (Integer JavaDoc) handler.perform(a_appdata1, null, a_appdata2)).
307               intValue();
308         } catch (Exception JavaDoc ex) {
309           throw new Error JavaDoc(ex);
310         }
311       }
312       else {
313         return 0;
314       }
315     }
316   }
317
318   /**
319    * Optional helper class for checking if a given allele value to be set
320    * for a given gene is valid. If not, the allele value may not be set for the
321    * gene or the gene type (e.g. IntegerGene) is not allowed in general!
322    *
323    * @since 2.5 (moved from CompositeGene, where it was since 2.0)
324    */

325   private IGeneConstraintChecker m_geneAlleleChecker;
326
327   /**
328    * Sets the constraint checker to be used for this gene whenever method
329    * setAllele(Object) is called.
330    * @param a_constraintChecker the constraint checker to be set
331    *
332    * @author Klaus Meffert
333    * @since 2.5 (moved from CompositeGene, where it was since 2.0)
334    */

335   public void setConstraintChecker(
336       final IGeneConstraintChecker a_constraintChecker) {
337     m_geneAlleleChecker = a_constraintChecker;
338   }
339
340   /**
341    * @return IGeneConstraintChecker the constraint checker to be used whenever
342    * method setAllele(Object) is called.
343    *
344    * @author Klaus Meffert
345    * @since 2.5 (moved from CompositeGene, where it was since 2.0)
346    */

347   public IGeneConstraintChecker getConstraintChecker() {
348     return m_geneAlleleChecker;
349   }
350
351   /**
352    * Provides implementation-independent means for creating new Gene
353    * instances. The new instance that is created and returned should be
354    * setup with any implementation-dependent configuration that this Gene
355    * instance is setup with (aside from the actual value, of course). For
356    * example, if this Gene were setup with bounds on its value, then the
357    * Gene instance returned from this method should also be setup with
358    * those same bounds. This is important, as the JGAP core will invoke this
359    * method on each Gene in the sample Chromosome in order to create each
360    * new Gene in the same respective gene position for a new Chromosome.
361    *
362    * @return a new Gene instance of the same type and with the same setup as
363    * this concrete Gene
364    *
365    * @author Neil Rostan
366    * @author Klaus Meffert
367    * @since 2.6 (since 1.0 in IntegerGene)
368    */

369   public Gene newGene() {
370     Gene result = newGeneInternal();
371     result.setConstraintChecker(getConstraintChecker());
372     result.setEnergy(getEnergy());
373     return result;
374   }
375
376   protected abstract Gene newGeneInternal();
377
378   /**
379    * @return the configuration set
380    *
381    * @author Klaus Meffert
382    * @since 3.0
383    */

384   public Configuration getConfiguration() {
385     return m_configuration;
386   }
387 }
388
Popular Tags