KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > examples > dynamicMutation > DynamicMutationExample


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 examples.dynamicMutation;
11
12 import org.jgap.*;
13 import org.jgap.impl.*;
14
15 /**
16  * Experiment on how to dynamically adapt the mutation rate for different
17  * genes. This example works with coins (see MinimizingMakeChange for
18  * documentation). The idea is that a quarter has more impact onto the solution
19  * than a penny, so a quarter should mutate less frequently, probably.
20  *
21  * @author Klaus Meffert
22  * @since 2.6
23  */

24 public class DynamicMutationExample {
25   /** String containing the CVS revision. Read out via reflection!*/
26   private final static String JavaDoc CVS_REVISION = "$Revision: 1.4 $";
27
28   /**
29    * The total number of times we'll let the population evolve.
30    */

31   private static final int MAX_ALLOWED_EVOLUTIONS = 200;
32
33   /**
34    * Executes the genetic algorithm to determine the minimum number of
35    * coins necessary to make up the given target amount of change. The
36    * solution will then be written to System.out.
37    *
38    * @param a_targetChangeAmount the target amount of change for which this
39    * method is attempting to produce the minimum number of coins
40    * @throws Exception
41    *
42    * @author Neil Rotstan
43    * @author Klaus Meffert
44    * @since 1.0
45    */

46   public static void makeChangeForAmount(int a_targetChangeAmount)
47       throws Exception JavaDoc {
48     // Start with a DefaultConfiguration, which comes setup with the
49
// most common settings.
50
// -------------------------------------------------------------
51
Configuration conf = new DefaultConfiguration();
52     // Add custom mutation operator
53
conf.getGeneticOperators().clear();
54 // IUniversalRateCalculator mutCalc = new CoinsMutationRateCalc();
55
TwoWayMutationOperator mutOp = new TwoWayMutationOperator(conf, 7);
56     conf.addGeneticOperator(mutOp);
57     conf.addGeneticOperator(new CrossoverOperator());
58     conf.setPreservFittestIndividual(!true);
59     conf.setKeepPopulationSizeConstant(false);
60     // Set the fitness function we want to use, which is our
61
// MinimizingMakeChangeFitnessFunction. We construct it with
62
// the target amount of change passed in to this method.
63
// ---------------------------------------------------------
64
FitnessFunction myFunc =
65         new DynamicMutationFitnessFunction(a_targetChangeAmount);
66     conf.setFitnessFunction(myFunc);
67 // conf.setBulkFitnessFunction(new BulkFitnessOffsetRemover(myFunc));
68
conf.setFitnessEvaluator(new DeltaFitnessEvaluator());
69     // Now we need to tell the Configuration object how we want our
70
// Chromosomes to be setup. We do that by actually creating a
71
// sample Chromosome and then setting it on the Configuration
72
// object. As mentioned earlier, we want our Chromosomes to each
73
// have four genes, one for each of the coin types. We want the
74
// values (alleles) of those genes to be integers, which represent
75
// how many coins of that type we have. We therefore use the
76
// IntegerGene class to represent each of the genes. That class
77
// also lets us specify a lower and upper bound, which we set
78
// to sensible values for each coin type.
79
// --------------------------------------------------------------
80
Gene[] sampleGenes = new Gene[4];
81     sampleGenes[0] = new IntegerGene(conf, 0, 3 * 10); // Quarters
82
sampleGenes[1] = new IntegerGene(conf, 0, 2 * 10); // Dimes
83
sampleGenes[2] = new IntegerGene(conf, 0, 1 * 10); // Nickels
84
sampleGenes[3] = new IntegerGene(conf, 0, 4 * 10); // Pennies
85
IChromosome sampleChromosome = new Chromosome(null, sampleGenes);
86     conf.setSampleChromosome(sampleChromosome);
87     // Finally, we need to tell the Configuration object how many
88
// Chromosomes we want in our population. The more Chromosomes,
89
// the larger number of potential solutions (which is good for
90
// finding the answer), but the longer it will take to evolve
91
// the population (which could be seen as bad).
92
// ------------------------------------------------------------
93
conf.setPopulationSize(80);
94     // Create random initial population of Chromosomes.
95
// Here we try to read in a previous run via XMLManager.readFile(..)
96
// for demonstration purpose!
97
// -----------------------------------------------------------------
98
Genotype population;
99     // Initialize the population randomly
100
population = Genotype.randomInitialGenotype(conf);
101     // Evolve the population. Since we don't know what the best answer
102
// is going to be, we just evolve the max number of times.
103
// ---------------------------------------------------------------
104
for (int i = 0; i < MAX_ALLOWED_EVOLUTIONS; i++) {
105       population.evolve();
106     }
107     // Display the best solution we found.
108
// -----------------------------------
109
IChromosome bestSolutionSoFar = population.getFittestChromosome();
110     System.out.println("The best solution has a fitness value of " +
111                        bestSolutionSoFar.getFitnessValue());
112     System.out.println("It contained the following: ");
113     System.out.println("\t" +
114                        DynamicMutationFitnessFunction.
115                        getNumberOfCoinsAtGene(
116         bestSolutionSoFar, 0) + " quarters.");
117     System.out.println("\t" +
118                        DynamicMutationFitnessFunction.
119                        getNumberOfCoinsAtGene(
120         bestSolutionSoFar, 1) + " dimes.");
121     System.out.println("\t" +
122                        DynamicMutationFitnessFunction.
123                        getNumberOfCoinsAtGene(
124         bestSolutionSoFar, 2) + " nickels.");
125     System.out.println("\t" +
126                        DynamicMutationFitnessFunction.
127                        getNumberOfCoinsAtGene(
128         bestSolutionSoFar, 3) + " pennies.");
129     System.out.println("For a total of " +
130                        DynamicMutationFitnessFunction.amountOfChange(
131         bestSolutionSoFar) + " cents in " +
132                        DynamicMutationFitnessFunction.
133                        getTotalNumberOfCoins(
134         bestSolutionSoFar) + " coins.");
135   }
136
137   /**
138    * Main method. A single command-line argument is expected, which is the
139    * amount of change to create (in other words, 75 would be equal to 75
140    * cents).
141    *
142    * @param args amount of change in cents to create
143    * @throws Exception
144    *
145    * @author Neil Rotstan
146    * @author Klaus Meffert
147    * @since 1.0
148    */

149   public static void main(String JavaDoc[] args)
150       throws Exception JavaDoc {
151     if (args.length != 1) {
152       System.out.println("Syntax: DynamicMutationExample <amount>");
153     }
154     else {
155       int amount = 0;
156       try {
157         amount = Integer.parseInt(args[0]);
158       }
159       catch (NumberFormatException JavaDoc e) {
160         System.out.println(
161             "The <amount> argument must be a valid integer value");
162         System.exit(1);
163       }
164       if (amount < 1 ||
165           amount >= DynamicMutationFitnessFunction.MAX_BOUND) {
166         System.out.println("The <amount> argument must be between 1 and "
167                            +
168                            (DynamicMutationFitnessFunction.MAX_BOUND - 1)
169                            + ".");
170       }
171       else {
172         makeChangeForAmount(amount);
173       }
174     }
175   }
176
177   /**
178    * This class only is an experiment!
179    *
180    * @author Klaus Meffert
181    * @since 2.6
182    */

183   public static class CoinsMutationRateCalc
184       implements IUniversalRateCalculator {
185     private int m_evolution;
186
187     private double m_rate0 = 0.2d;
188
189     private double m_rate1 = 0.6d;
190
191     private double m_rate2 = 0.7d;
192
193     private double m_rate3 = 1.0d;
194
195     public int calculateCurrentRate() {
196       int size;
197       size = 15;
198       if (size < 1) {
199         size = 1;
200       }
201       return size;
202     }
203
204     public boolean toBePermutated(IChromosome a_chrom, int a_geneIndex) {
205       RandomGenerator generator
206           = a_chrom.getConfiguration().getRandomGenerator();
207       double mult = 0.0d;
208       switch (a_geneIndex) {
209         case 0:
210           mult = get(0);
211           break;
212         case 1:
213           mult = m_rate1;
214           break;
215         case 2:
216           mult = m_rate2;
217           break;
218         case 3:
219           mult = m_rate3;
220           m_evolution++;
221           break;
222       }
223       return (generator.nextDouble() < (1 / calculateCurrentRate()) * mult);
224     }
225
226     private double get(int a_index) {
227       if (m_evolution > 90) {
228         m_rate0 = 1.0d;
229       }
230       else if (m_evolution > 60) {
231         m_rate0 = 0.75d;
232       }
233       else if (m_evolution > 30) {
234         m_rate0 = 0.5d;
235       }
236       else if (m_evolution > 15) {
237         m_rate0 = 0.4d;
238       }
239       return m_rate0;
240     }
241   }
242 }
243
Popular Tags