KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > examples > supergene > AbstractSupergeneTest


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.supergene;
11
12 import org.jgap.*;
13 import org.jgap.impl.*;
14
15 /**
16  * Abstract class for testing Supergene performance.
17  *
18  * @author Neil Rotstan
19  * @author Klaus Meffert
20  * @author Audrius Meskauskas (subsequent adaptation)
21  * @since 2.0
22  * */

23 public abstract class AbstractSupergeneTest {
24   /** String containing the CVS revision. Read out via reflection!*/
25   private static final String JavaDoc CVS_REVISION = "$Revision: 1.3 $";
26
27   private transient Configuration m_conf;
28
29   /**
30    * Gene index for the dimes gene
31    */

32   public static final int DIMES = 0;
33
34   /**
35    * Gene index for the quarters gene.
36    */

37   public static final int QUARTERS = 1;
38
39   /**
40    * Gene index for the nickels gene
41    * Only used in the alternative presentation */

42   public static final int NICKELS = 2;
43
44   /**
45    * Gene index for the pennies gene.
46    * Only used in the alternative presentation */

47   public static final int PENNIES = 3;
48
49   /**
50    * The total number of times we'll let the population evolve.
51    */

52   public static int MAX_ALLOWED_EVOLUTIONS = 200;
53
54   /**
55    * Chromosome size.
56    */

57   public static int POPULATION_SIZE = 2000;
58
59   public static boolean REPORT_ENABLED = true;
60
61   /**
62    * @return created Dimes gene instance
63    */

64   protected Gene getDimesGene(Configuration a_conf) {
65     try {
66       return new IntegerGene(a_conf, 0, 2); // 10?
67
}
68     catch (InvalidConfigurationException iex) {
69       throw new IllegalStateException JavaDoc(iex.getMessage());
70     }
71   };
72
73   /**
74    * @return created Nickels gene instance
75    */

76   protected Gene getNickelsGene(Configuration a_conf) {
77     try {
78       return new IntegerGene(a_conf, 0, 5);
79     }
80     catch (InvalidConfigurationException iex) {
81       throw new IllegalStateException JavaDoc(iex.getMessage());
82     }
83   }
84
85   /**
86    * @return created Pennies (1) gene instance
87    */

88   protected Gene getPenniesGene(Configuration a_conf) {
89     try {
90       return new IntegerGene(a_conf, 0, 7);
91     }
92     catch (InvalidConfigurationException iex) {
93       throw new IllegalStateException JavaDoc(iex.getMessage());
94     }
95   }
96
97   /**
98    * @return created Quarters gene instance
99    */

100   protected Gene getQuartersGene(Configuration a_conf) {
101     try {
102       return new IntegerGene(a_conf, 0, 3);
103     }
104     catch (InvalidConfigurationException iex) {
105       throw new IllegalStateException JavaDoc(iex.getMessage());
106     }
107   }
108
109   /** Compute the money value from the coin information. */
110   public static int amountOfChange(int a_numQuarters, int a_numDimes,
111                                    int a_numNickels, int a_numPennies) {
112     return (a_numQuarters * 25) + (a_numDimes * 10) + (a_numNickels * 5)
113         + a_numPennies;
114   };
115
116   /**
117    * Executes the genetic algorithm to determine the minimum number of
118    * coins necessary to make up the given target amount of change. The
119    * solution will then be written to System.out.
120    *
121    * @param a_targetChangeAmount the target amount of change for which this
122    * method is attempting to produce the minimum number of coins
123    *
124    * @return absolute difference between the required and computed change
125    * amount
126    * @throws Exception
127    */

128   public abstract int makeChangeForAmount(int a_targetChangeAmount)
129       throws Exception JavaDoc;
130
131   /**
132    * Write report on eveluation to the given stream.
133    * @param a_fitnessFunction p_SupergeneChangeFitnessFunction
134    * @param a_population Genotype
135    * @return Chromosome
136    */

137   public IChromosome report(SupergeneChangeFitnessFunction a_fitnessFunction,
138                             Genotype a_population) {
139     IChromosome bestSolutionSoFar = a_population.getFittestChromosome();
140     if (!REPORT_ENABLED) {
141       return bestSolutionSoFar;
142     }
143     System.out.println("\nThe best solution has a fitness value of "
144                        + bestSolutionSoFar.getFitnessValue());
145     System.out.println("It contained the following: ");
146     System.out.println("\t" + a_fitnessFunction.getNumberOfCoinsAtGene(
147         bestSolutionSoFar, QUARTERS) + " quarters.");
148     System.out.println("\t" + a_fitnessFunction.getNumberOfCoinsAtGene(
149         bestSolutionSoFar, DIMES) + " dimes.");
150     System.out.println("\t" + a_fitnessFunction.getNumberOfCoinsAtGene(
151         bestSolutionSoFar, NICKELS) + " nickels.");
152     System.out.println("\t" + a_fitnessFunction.getNumberOfCoinsAtGene(
153         bestSolutionSoFar, PENNIES) + " pennies.");
154     System.out.println("For a total of " + a_fitnessFunction.amountOfChange(
155         bestSolutionSoFar) + " cents in "
156                        + a_fitnessFunction.getTotalNumberOfCoins(
157         bestSolutionSoFar) + " coins.");
158     return bestSolutionSoFar;
159   }
160
161   /**
162    * If set to true (required for strict tests), only tasks with existing
163    * solutions will be submitted as a test tasks.
164    */

165   public static boolean EXISTING_SOLUTIONS_ONLY = false;
166
167   /**
168    * Test the method, returns the sum of all differences between
169    * the required and obtained excange amount. One exception counts
170    * as 1000 on the error score.
171    */

172   public int test() {
173     int s = 0;
174     int e;
175     Test:
176         for (int amount = 20; amount < 100; amount++) {
177       try {
178         if (REPORT_ENABLED) {
179           System.out.println("EXCANGING " + amount + " ");
180         }
181         // Do not solve cases without solutions
182
if (EXISTING_SOLUTIONS_ONLY) {
183           if (!Force.solve(amount)) {
184             continue Test;
185           }
186         }
187         // Need to reset the configuration because it needs to be changed each
188
// time when looping.
189
// -------------------------------------------------------------------
190
DefaultConfiguration.reset();
191         e = makeChangeForAmount(amount);
192         if (REPORT_ENABLED) {
193           System.out.println(" err " + e);
194           System.out.println("---------------");
195         }
196         s = s + e;
197       }
198       catch (Exception JavaDoc ex) {
199         ex.printStackTrace();
200         s += 1000;
201       }
202     }
203     if (REPORT_ENABLED) {
204       System.out.println("Sum of errors " + s);
205     }
206     return s;
207   }
208
209   /**
210    * Find and print the solution, return the solution error.
211    * @return absolute difference between the required and computed change
212    */

213   protected int solve(Configuration a_conf, int a_targetChangeAmount,
214                       SupergeneChangeFitnessFunction a_fitnessFunction,
215                       Gene[] a_sampleGenes)
216       throws InvalidConfigurationException {
217     IChromosome sampleChromosome = new Chromosome(a_conf, a_sampleGenes);
218     a_conf.setSampleChromosome(sampleChromosome);
219     // Finally, we need to tell the Configuration object how many
220
// Chromosomes we want in our population. The more Chromosomes,
221
// the larger number of potential solutions (which is good for
222
// finding the answer), but the longer it will take to evolve
223
// the population (which could be seen as bad). We'll just set
224
// the population size to 500 here.
225
// ------------------------------------------------------------
226
a_conf.setPopulationSize(POPULATION_SIZE);
227     // Create random initial population of Chromosomes.
228
// ------------------------------------------------
229
Genotype population = Genotype.randomInitialGenotype(a_conf);
230     int s;
231     Evolution:
232         // Evolve the population, break if the the change solution is found.
233
// -----------------------------------------------------------------
234
for (int i = 0; i < MAX_ALLOWED_EVOLUTIONS; i++) {
235       population.evolve();
236       s = Math.abs(a_fitnessFunction.amountOfChange(population.
237           getFittestChromosome())
238                    - a_targetChangeAmount);
239       if (s == 0) {
240         break Evolution;
241       }
242     }
243     // Display the best solution we found.
244
// -----------------------------------
245
IChromosome bestSolutionSoFar = report(a_fitnessFunction, population);
246     return Math.abs(a_fitnessFunction.amountOfChange(bestSolutionSoFar)
247                     - a_targetChangeAmount);
248   }
249
250 }
251
Popular Tags