KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jgap > audit > Evaluator


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.audit;
11
12 import org.jgap.*;
13 import java.util.*;
14
15 /**
16  * Gathers statistical data and returns them on request.
17  *
18  * @author Klaus Meffert
19  * @since 2.2
20  */

21 public class Evaluator {
22   /**@todo implement: overall score calculation (out of best/avg. fitness value
23    * etc.)
24    */

25
26   /** String containing the CVS revision. Read out via reflection!*/
27   private final static String JavaDoc CVS_REVISION = "$Revision: 1.10 $";
28
29   /**
30    * Each data has its own data container
31    */

32   private Map m_permutationData;
33
34   /**
35    * Stores the run-numbers (indexes) for all permutations submitted
36    */

37   private Map m_permutationRuns;
38
39   /**
40    * For processinf without permutation
41    */

42   private KeyedValues2D m_data;
43
44   private PermutingConfiguration m_permConf;
45
46   /**
47    * Genotype data per permutation per run
48    */

49   private Map m_genotypeData;
50
51   /**
52    * Genotype data per permutation (averaged over all runs)
53    */

54   private List m_genotypeDataAvg;
55
56   public Evaluator(final PermutingConfiguration a_conf) {
57     if (a_conf == null) {
58       throw new IllegalArgumentException JavaDoc("Configuration must not be null!");
59     }
60     m_permConf = a_conf;
61     m_data = new KeyedValues2D();
62     m_permutationData = new Hashtable();
63     m_permutationRuns = new Hashtable();
64     m_genotypeData = new Hashtable();
65     m_genotypeDataAvg = new Vector();
66   }
67
68   public boolean hasNext() {
69     return m_permConf.hasNext();
70   }
71
72   public Configuration next()
73       throws InvalidConfigurationException {
74     return m_permConf.next();
75   }
76
77   public void setValue(double a_value, Comparable JavaDoc a_rowKey,
78                        Comparable JavaDoc a_columnKey) {
79     m_data.setValue(new Double JavaDoc(a_value), a_rowKey, a_columnKey);
80 // fireDatasetChanged();
81
}
82
83   public Number JavaDoc getValue(Comparable JavaDoc rowKey, Comparable JavaDoc columnKey) {
84     return m_data.getValue(rowKey, columnKey);
85   }
86
87   /**
88    * Sets a specific value.
89    * @param a_permutation int
90    * @param a_run int
91    * @param a_value double
92    * @param a_rowKey Comparable
93    * @param a_columnKey Comparable
94    *
95    * @author Klaus Meffert
96    * @since 2.2
97    */

98   public void setValue(int a_permutation, int a_run, double a_value,
99                        Comparable JavaDoc a_rowKey, Comparable JavaDoc a_columnKey) {
100     Object JavaDoc key = createKey(a_permutation, a_run);
101     KeyedValues2D a_data = (KeyedValues2D) m_permutationData.get(
102         key);
103     if (a_data == null) {
104       a_data = new KeyedValues2D();
105       m_permutationData.put(key, a_data);
106     }
107     // Add run-number (index).
108
// -----------------------
109
addRunNumber(a_permutation, a_run);
110     a_data.setValue(new Double JavaDoc(a_value), a_rowKey, a_columnKey);
111   }
112
113   protected void addRunNumber(int a_permutation, int a_run) {
114     Map v = (Map) m_permutationRuns.get(new Integer JavaDoc(a_permutation));
115     if (v == null) {
116       v = new Hashtable();
117     }
118     v.put(new Integer JavaDoc(a_run), new Integer JavaDoc(a_run));
119     m_permutationRuns.put(new Integer JavaDoc(a_permutation), v);
120   }
121
122   public Number JavaDoc getValue(int a_permutation, int a_run, Comparable JavaDoc rowKey,
123                          Comparable JavaDoc columnKey) {
124     KeyedValues2D a_data = (KeyedValues2D) m_permutationData.get(
125         createKey(a_permutation, a_run));
126     if (a_data == null) {
127       return null;
128     }
129     return a_data.getValue(rowKey, columnKey);
130   }
131
132   public KeyedValues2D getData() {
133     return m_data;
134   }
135
136   protected Object JavaDoc createKey(int a_permutation, int a_run) {
137     return a_permutation + "_" + a_run;
138   }
139
140   /**
141    * Calculates the average fitness value curve for a given permutation.
142    * If permutation -1 is given, a composition of all permutations available
143    * is created.
144    * @param a_permutation -1 to use all permutations
145    * @return DefaultKeyedValues2D list of fitness values, one for each
146    * individual in the generation
147    *
148    * @author Klaus Meffert
149    * @since 2.2
150    */

151   public KeyedValues2D calcAvgFitness(int a_permutation) {
152     if (a_permutation == -1) {
153       Iterator it = m_permutationRuns.keySet().iterator();
154       Integer JavaDoc permNumberI;
155       int permNumber;
156       KeyedValues2D result = new KeyedValues2D();
157       while (it.hasNext()) {
158         permNumberI = (Integer JavaDoc) it.next();
159         permNumber = permNumberI.intValue();
160         calcAvgFitnessHelper(permNumber, result);
161       }
162       return result;
163     }
164     else {
165       KeyedValues2D a_data = new KeyedValues2D();
166       calcAvgFitnessHelper(a_permutation, a_data);
167       return a_data;
168     }
169   }
170
171   protected void calcAvgFitnessHelper(int a_permutation,
172                                       final KeyedValues2D result) {
173     // Determine run-numbers of given permutation.
174
// -------------------------------------------
175
Map runNumbers = (Map) m_permutationRuns.get(new Integer JavaDoc(a_permutation));
176     if (runNumbers == null) {
177       return;
178     }
179     // Loop over all run-numbers.
180
// --------------------------
181
Iterator it = runNumbers.keySet().iterator();
182     int numRuns = runNumbers.keySet().size();
183     Integer JavaDoc runI;
184     while (it.hasNext()) {
185       runI = (Integer JavaDoc) it.next();
186       // Determine dataset of given permutation.
187
// ---------------------------------------
188
KeyedValues2D a_data = (KeyedValues2D) m_permutationData.
189           get(createKey(a_permutation, runI.intValue()));
190       // Determine values for current run-number and "add" them to gathered
191
// data.
192
// ------------------------------------------------------------------
193
for (int col = 0; col < a_data.getColumnCount(); col++) {
194         for (int row = 0; row < a_data.getRowCount(); row++) {
195           // Previous value (summation).
196
// --------------------------.
197
Double JavaDoc d = (Double JavaDoc) result.getValue(a_data.getRowKey(row),
198                                               a_data.getColumnKey(col));
199           double newValue;
200           if (d == null) {
201             newValue = 0.0d;
202           }
203           else {
204             newValue = d.doubleValue();
205           }
206           // Add current value (divided by total number of runs to get an
207
// averaged value).
208
// ------------------------------------------------------------
209
newValue +=
210               a_data.getValue(a_data.getRowKey(row), a_data.getColumnKey(col)).
211               doubleValue() / numRuns;
212           // Set averaged value back to result dataset.
213
// ------------------------------------------
214
result.setValue(new Double JavaDoc(newValue), a_data.getRowKey(row),
215                           a_data.getColumnKey(col));
216         }
217       }
218     }
219   }
220
221   /**
222    * Returns a list of lists (i.e. a matrix) to use for output as a table
223    * @param a_data DefaultKeyedValues2D
224    * @return List
225    */

226   /**@todo implement*/
227 // public List getTable(KeyedValues2D a_data) {
228
// return null;
229
// }
230

231   /**
232    * Calculates average fitness value improvement per generation.
233    *
234    * @param a_permutation int
235    * @return DefaultKeyedValues2D
236    *
237    * @author Klaus Meffert
238    * @since 2.2
239    */

240   public KeyedValues2D calcAvgFitnessImpr(int a_permutation) {
241     /**@todo implement*/
242     /**@todo is this method used resp. contained in calcPerformance?*/
243     Map runNumbers = (Map) m_permutationRuns.get(new Integer JavaDoc(a_permutation));
244     if (runNumbers == null) {
245       return null;
246     }
247 // Map fitnessImpr = new Hashtable();
248
// Loop over all run-numbers.
249
// --------------------------
250
Iterator it = runNumbers.keySet().iterator();
251 // int numRuns = runNumbers.keySet().size();
252
Integer JavaDoc runI;
253     while (it.hasNext()) {
254       runI = (Integer JavaDoc) it.next();
255       // Determine dataset of given permutation.
256
// ---------------------------------------
257
KeyedValues2D a_data = (KeyedValues2D) m_permutationData.
258           get(createKey(a_permutation, runI.intValue()));
259       for (int col = 0; col < a_data.getColumnCount(); col++) {
260         for (int row = 0; row < a_data.getRowCount(); row++) {
261         }
262       }
263     }
264     return null;
265   }
266
267   /**
268    *
269    * @param a_permutation the permutation to determine the number of runs for
270    * @return the number of runs for the given permutation
271    */

272   public int getNumberOfRuns(int a_permutation) {
273     Map runNumbers = (Map) m_permutationRuns.get(new Integer JavaDoc(a_permutation));
274     if (runNumbers == null) {
275       return 0;
276     }
277     else {
278       return runNumbers.keySet().size();
279     }
280   }
281
282   /**
283    * Stores information contained in the given genotype.
284    * @param a_permutation int
285    * @param a_run index of the run proceeded for the given genotype
286    * @param a_genotype the genotype holding the population of chromosomes
287    *
288    * @author Klaus Meffert
289    * @since 2.2
290    */

291   public void storeGenotype(int a_permutation, int a_run, Genotype a_genotype) {
292     /**@todo implement*/
293     // average and maximum fitness value
294
//
295
GenotypeData data = new GenotypeData();
296     int generation = a_genotype.getConfiguration().getGenerationNr();
297     data.generation = generation;
298     Population pop = a_genotype.getPopulation();
299     data.hashCode = a_genotype.hashCode();
300     int popSize = pop.size();
301     data.chromosomeData = new ChromosomeData[popSize];
302     data.size = popSize;
303     // gather data of Chromosomes
304
IChromosome chrom;
305     ChromosomeData chromData;
306     for (int i = 0; i < popSize; i++) {
307       chrom = pop.getChromosome(i);
308       chromData = new ChromosomeData();
309       chromData.fitnessValue = chrom.getFitnessValue();
310       chromData.size = chrom.size();
311       chromData.index = i;
312       data.chromosomeData[i] = chromData;
313     }
314     String JavaDoc key = a_permutation + "_" + a_run;
315     m_genotypeData.put(key, data);
316     addRunNumber(a_permutation, a_run);
317   }
318
319   public GenotypeData retrieveGenotype(int a_permutation, int a_run) {
320     return (GenotypeData) m_genotypeData.get(a_permutation + "_" + a_run);
321   }
322
323   /**
324    * Calculates performance metrics for a given permutation and run stored
325    * before with storeGenotype, like:
326    * average fitness, maximum fitness...
327    * @param a_permutation the permutation to compute the performance metrics
328    * for
329    * @return computed statistical data
330    *
331    * @author Klaus Meffert
332    * @since 2.2
333    */

334   public GenotypeDataAvg calcPerformance(int a_permutation) {
335     int numRuns = getNumberOfRuns(a_permutation);
336     GenotypeData data;
337     GenotypeDataAvg dataAvg = new GenotypeDataAvg();
338     dataAvg.permutation = a_permutation;
339     double sizeAvg = 0.0d;
340     double fitnessAvg = 0.0d;
341     double fitnessBest = -1.0d;
342     double fitnessBestOld = -1.0d;
343     double fitness;
344     int fitnessBestGen = -1;
345     double fitnessAvgChroms;
346     double fitnessDiversityChromsOld = -1.0d;
347     double fitnessBestDeltaAvg = 0.0d;
348     double fitnessDiversity;
349     double fitnessDiversityAvg = 0.0d;
350     int size;
351     ChromosomeData chrom;
352     for (int i = 0; i < numRuns; i++) {
353       data = retrieveGenotype(a_permutation, i);
354       // generation the genotype data represents
355
if (i == 0) {
356         dataAvg.generation = data.generation;
357       }
358       // average number of chromosomes
359
sizeAvg += (double) data.size / numRuns;
360       size = data.size;
361       fitnessAvgChroms = 0.0d;
362       fitnessDiversity = 0.0d;
363       double fitnessBestLocal = -1.0d;
364       for (int j = 0; j < size; j++) {
365         chrom = data.chromosomeData[j];
366         fitness = chrom.fitnessValue;
367         // diversity of fitness values over all chromosomes
368
if (j > 0) {
369           fitnessDiversity += Math.abs(fitness - fitnessDiversityChromsOld) /
370               (size - 1);
371         }
372         fitnessDiversityChromsOld = fitness;
373         // average fitness value for generation over all Chromosomes
374
fitnessAvgChroms += fitness / size;
375         // fittest chromosome in generation over all runs
376
if (fitnessBest < fitness) {
377           fitnessBest = fitness;
378           // memorize generation number in which fittest chromosome appeared
379
fitnessBestGen = data.generation;
380         }
381         // fittest chromosome in generation over current runs
382
if (fitnessBestLocal < fitness) {
383           fitnessBestLocal = fitness;
384         }
385       }
386       // average fitness value for generation over all runs
387
fitnessAvg += fitnessAvgChroms / numRuns;
388       // average fitness delta value for generation over all runs
389
fitnessDiversityAvg += fitnessDiversity / numRuns;
390       // absolute delta between two adjacent best fitness values
391
if (i > 0) {
392         fitnessBestDeltaAvg += Math.abs(fitnessBestLocal - fitnessBestOld) /
393             (numRuns - 1);
394       }
395       fitnessBestOld = fitnessBestLocal;
396     }
397     dataAvg.sizeAvg = sizeAvg;
398     dataAvg.avgFitnessValue = fitnessAvg;
399     dataAvg.bestFitnessValue = fitnessBest;
400     dataAvg.bestFitnessValueGeneration = fitnessBestGen;
401     dataAvg.avgDiversityFitnessValue = fitnessDiversityAvg;
402     dataAvg.avgBestDeltaFitnessValue = fitnessBestDeltaAvg;
403     //store computed (averaged) data
404
m_genotypeDataAvg.add(dataAvg);
405     return dataAvg;
406   }
407
408   /**
409    * Averaged genotype data (computed over all runs of a permutation)
410    *
411    * @author Klaus Meffert
412    * @since 2.2
413    */

414   public class GenotypeDataAvg {
415     public int permutation;
416
417     public int generation;
418
419     public double sizeAvg;
420
421     public double bestFitnessValue;
422
423     public double avgFitnessValue;
424
425     public int bestFitnessValueGeneration;
426
427     public double avgDiversityFitnessValue;
428
429     public double avgBestDeltaFitnessValue;
430   }
431   /**
432    * Genotype data for one single run
433    *
434    * @author Klaus Meffert
435    * @since 2.2
436    */

437   public class GenotypeData {
438     public int generation;
439
440     public int hashCode;
441
442     public int size;
443
444     public ChromosomeData[] chromosomeData;
445   }
446   public class ChromosomeData {
447     public int index;
448
449     public int size;
450
451     public double fitnessValue;
452   }
453 }
454
Popular Tags