KickJava   Java API By Example, From Geeks To Geeks.

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


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  * Implementation of a NaturalSelector that takes the top n chromosomes into
17  * the next generation. n can be specified. Which chromosomes are the best is
18  * decided by evaluating their fitness value.
19  *
20  * @author Klaus Meffert
21  * @since 1.1
22  */

23 public class BestChromosomesSelector
24     extends NaturalSelector {
25   /** String containing the CVS revision. Read out via reflection!*/
26   private final static String JavaDoc CVS_REVISION = "$Revision: 1.41 $";
27
28   /**
29    * Stores the chromosomes to be taken into account for selection
30    */

31   private Population m_chromosomes;
32
33   /**
34    * Allows or disallows doublette chromosomes to be added to the selector
35    */

36   private boolean m_doublettesAllowed;
37
38   /**
39    * Indicated whether the list of added chromosomes needs sorting
40    */

41   private boolean m_needsSorting;
42
43   /**
44    * Comparator that is only concerned about fitness values
45    */

46   private FitnessValueComparator m_fitnessValueComparator;
47
48   private BestChromosomesSelectorConfig m_config = new
49       BestChromosomesSelectorConfig();
50
51   /**
52    * Default constructor.<p>
53    * Attention: The configuration used is the one set with the static method
54    * Genotype.setConfiguration.
55    * @throws InvalidConfigurationException
56    *
57    * @author Klaus Meffert
58    * @since 1.1
59    */

60   public BestChromosomesSelector()
61       throws InvalidConfigurationException {
62     this(Genotype.getStaticConfiguration());
63   }
64
65   /**
66    * Using original rate of 1.0
67    * @param a_config the configuration to use
68    * @throws InvalidConfigurationException
69    *
70    * @author Klaus Meffert
71    * @since 3.0
72    */

73   public BestChromosomesSelector(final Configuration a_config)
74       throws InvalidConfigurationException {
75     this(a_config, 1.0d);
76   }
77
78   public BestChromosomesSelector(final Configuration a_config,
79                                  final double a_originalRate)
80       throws InvalidConfigurationException {
81     super(a_config);
82     m_chromosomes = new Population(a_config);
83     m_needsSorting = false;
84     m_doublettesAllowed = false;
85     setOriginalRate(a_originalRate);
86     m_fitnessValueComparator = new FitnessValueComparator();
87   }
88
89   /**
90    * Add a Chromosome instance to this selector's working pool of Chromosomes.
91    * @param a_chromosomeToAdd the specimen to add to the pool
92    *
93    * @author Klaus Meffert
94    * @since 1.1
95    */

96   protected void add(final IChromosome a_chromosomeToAdd) {
97     // If opted-in: Check if chromosome already added
98
// This speeds up the process by orders of magnitude but could lower the
99
// quality of evolved results because of fewer Chromosome's used!!!
100
if (!getDoubletteChromosomesAllowed()
101         && m_chromosomes.getChromosomes().contains(a_chromosomeToAdd)) {
102       return;
103     }
104     // New chromosome, insert it into the sorted collection of chromosomes
105
a_chromosomeToAdd.setIsSelectedForNextGeneration(false);
106     m_chromosomes.addChromosome(a_chromosomeToAdd);
107     // Indicate that the list of chromosomes to add needs sorting.
108
// -----------------------------------------------------------
109
m_needsSorting = true;
110   }
111
112   /**
113    * Selects a given number of Chromosomes from the pool that will move on
114    * to the next generation population. This selection will be guided by the
115    * fitness values. The chromosomes with the best fitness value win.
116    *
117    * @param a_from_pop the population the Chromosomes will be selected from
118    * @param a_to_pop the population the Chromosomes will be added to
119    * @param a_howManyToSelect the number of Chromosomes to select
120    *
121    * @author Klaus Meffert
122    * @since 1.1
123    */

124   public void select(final int a_howManyToSelect,
125                                   final Population a_from_pop,
126                                   final Population a_to_pop) {
127     if (a_from_pop != null) {
128       int popSize = a_from_pop.size();
129       for (int i = 0; i < popSize; i++) {
130         add(a_from_pop.getChromosome(i));
131       }
132     }
133     int canBeSelected;
134     int chromsSize = m_chromosomes.size();
135     if (a_howManyToSelect > chromsSize) {
136       canBeSelected = chromsSize;
137     }
138     else {
139       canBeSelected = a_howManyToSelect;
140     }
141     int neededSize = a_howManyToSelect;
142     double origRate;
143     origRate = m_config.m_originalRate;
144     if (origRate < 1.0d) {
145       canBeSelected = (int) Math.round( (double) canBeSelected *
146                                        origRate);
147       if (canBeSelected < 1) {
148         canBeSelected = 1;
149       }
150     }
151     // Sort the collection of chromosomes previously added for evaluation.
152
// Only do this if necessary.
153
// -------------------------------------------------------------------
154
if (m_needsSorting) {
155       Collections.sort(m_chromosomes.getChromosomes(),
156                        m_fitnessValueComparator);
157       m_needsSorting = false;
158     }
159     // To select a chromosome, we just go thru the sorted list.
160
// --------------------------------------------------------
161
IChromosome selectedChromosome;
162     for (int i = 0; i < canBeSelected; i++) {
163       selectedChromosome = m_chromosomes.getChromosome(i);
164       selectedChromosome.setIsSelectedForNextGeneration(true);
165       a_to_pop.addChromosome(selectedChromosome);
166     }
167     if (getDoubletteChromosomesAllowed()) {
168       int toAdd;
169       toAdd = neededSize - a_to_pop.size();
170       // Add existing Chromosome's to fill up the return
171
// result to contain the desired number of Chromosome's.
172
// -----------------------------------------------------
173
for (int i = 0; i < toAdd; i++) {
174         /**@todo add ramdomization*/
175         selectedChromosome = m_chromosomes.getChromosome(i % chromsSize);
176         selectedChromosome.setIsSelectedForNextGeneration(true);
177         a_to_pop.addChromosome(selectedChromosome);
178       }
179     }
180   }
181
182   /**
183    * Empties out the working pool of Chromosomes.
184    *
185    * @author Klaus Meffert
186    * @since 1.1
187    */

188   public void empty() {
189     // clear the list of chromosomes
190
// -----------------------------
191
m_chromosomes.getChromosomes().clear();
192     m_needsSorting = false;
193   }
194
195   /**
196    * Determines whether doublette chromosomes may be added to the selector or
197    * will be ignored.
198    * @param a_doublettesAllowed true: doublette chromosomes allowed to be
199    * added to the selector. FALSE: doublettes will be ignored and not added
200    *
201    * @author Klaus Meffert
202    * @since 2.0
203    */

204   public void setDoubletteChromosomesAllowed(
205       final boolean a_doublettesAllowed) {
206     m_doublettesAllowed = a_doublettesAllowed;
207   }
208
209   /**
210    * @return true: doublette chromosomes allowed to be added to the selector
211    *
212    * @author Klaus Meffert
213    * @since 2.0
214    */

215   public boolean getDoubletteChromosomesAllowed() {
216     return m_doublettesAllowed;
217   }
218
219   /**
220    * @return always true as no Chromosome can be returnd multiple times
221    *
222    * @author Klaus Meffert
223    * @since 2.0
224    */

225   public boolean returnsUniqueChromosomes() {
226     return true;
227   }
228
229   /**
230    * Setting this parameter controls how many chromosomes of the original
231    * population will be considered for selection to the next population. If
232    * the value is 1 then the whole original population is considered, if it is
233    * 0.5 only half of the chromosomes are considered. If doublettes are allowed,
234    * then a number of chromosomes missing (number of to be selected minus number
235    * selected) will be added.
236    * @param a_originalRate the rate of how many of the original chromosomes
237    * will be selected according to BestChromosomeSelector's strategy. The rest
238    * (non-original) of the chromosomes is added as duplicates
239    *
240    * @author Klaus Meffert
241    * @since 2.0
242    */

243   public void setOriginalRate(final double a_originalRate) {
244     if (a_originalRate < 0.0d || a_originalRate > 1.0d) {
245       throw new IllegalArgumentException JavaDoc("Original rate must be greater than"
246                                          + " zero and not greater than one!");
247     }
248     m_config.m_originalRate = a_originalRate;
249   }
250
251   /**
252    *
253    * @return see setOriginalRate
254    *
255    * @author Klaus Meffert
256    * @since 2.0
257    */

258   public double getOriginalRate() {
259     return m_config.m_originalRate;
260   }
261
262   class BestChromosomesSelectorConfig
263       implements java.io.Serializable JavaDoc {
264     /**
265      * The rate of original Chromosomes selected. This is because we otherwise
266      * would always return the original input as output
267      */

268     public double m_originalRate;
269   }
270 }
271
Popular Tags