1 | package cecj.statistics; |
---|
2 | |
---|
3 | import java.io.File; |
---|
4 | import java.io.IOException; |
---|
5 | |
---|
6 | import ec.EvolutionState; |
---|
7 | import ec.Individual; |
---|
8 | import ec.Statistics; |
---|
9 | import ec.util.Output; |
---|
10 | import ec.util.Parameter; |
---|
11 | |
---|
12 | public class AverageObjectiveFitnessStatistics extends Statistics { |
---|
13 | |
---|
14 | private static final String P_COUNT_LAST = "count-last"; |
---|
15 | private static final String P_FREQUENCY = "frequency"; |
---|
16 | private static final String P_FITNESS_CALCULATOR = "fitness-calc"; |
---|
17 | private static final String P_FITNESS_FILE = "fitness-file"; |
---|
18 | |
---|
19 | public int fitnessStatisticslog; |
---|
20 | |
---|
21 | public AverageObjectiveFitnessStatistics() { |
---|
22 | fitnessStatisticslog = 0; |
---|
23 | } |
---|
24 | |
---|
25 | private int frequency; |
---|
26 | private ObjectiveFitnessCalculator fitnessCalc; |
---|
27 | |
---|
28 | private int countLast; |
---|
29 | private int lastCounter; |
---|
30 | private float sumLastFitnesses; |
---|
31 | private float lastFitnesses[]; |
---|
32 | |
---|
33 | @Override |
---|
34 | public void setup(EvolutionState state, Parameter base) { |
---|
35 | super.setup(state, base); |
---|
36 | |
---|
37 | Parameter countLastParam = base.push(P_COUNT_LAST); |
---|
38 | countLast = state.parameters.getIntWithDefault(countLastParam, null, -1); |
---|
39 | if (countLast != -1) { |
---|
40 | lastFitnesses = new float[countLast]; |
---|
41 | lastCounter = 0; |
---|
42 | sumLastFitnesses = 0.0f; |
---|
43 | } |
---|
44 | |
---|
45 | Parameter fitnessCalcParameter = base.push(P_FITNESS_CALCULATOR); |
---|
46 | fitnessCalc = (ObjectiveFitnessCalculator) state.parameters |
---|
47 | .getInstanceForParameter(fitnessCalcParameter, null, ObjectiveFitnessCalculator.class); |
---|
48 | fitnessCalc.setup(state, fitnessCalcParameter); |
---|
49 | |
---|
50 | Parameter frequencyParam = base.push(P_FREQUENCY); |
---|
51 | frequency = state.parameters.getIntWithDefault(frequencyParam, null, 1); |
---|
52 | |
---|
53 | File fitnessStatisticsFile = state.parameters.getFile(base.push(P_FITNESS_FILE), null); |
---|
54 | if (fitnessStatisticsFile != null) { |
---|
55 | try { |
---|
56 | fitnessStatisticslog = state.output.addLog(fitnessStatisticsFile, Output.V_VERBOSE, |
---|
57 | false, true, false); |
---|
58 | } catch (IOException i) { |
---|
59 | state.output.fatal("An IOException occurred while trying to create the log " |
---|
60 | + fitnessStatisticsFile + ":\n" + i); |
---|
61 | } |
---|
62 | } |
---|
63 | } |
---|
64 | |
---|
65 | @Override |
---|
66 | public void postEvaluationStatistics(EvolutionState state) { |
---|
67 | super.postEvaluationStatistics(state); |
---|
68 | |
---|
69 | if ((state.generation % frequency != 0) && (state.generation != state.numGenerations - 1)) { |
---|
70 | return; |
---|
71 | } |
---|
72 | |
---|
73 | for (int subpop = 0; subpop < state.population.subpops.length; ++subpop) { |
---|
74 | float sumFitness = 0; |
---|
75 | float maxFitness = Float.NEGATIVE_INFINITY; |
---|
76 | float maxSubjectiveFitness = Float.NEGATIVE_INFINITY; |
---|
77 | float objectiveFitnessOfSubjectivelyBest = -1; |
---|
78 | |
---|
79 | float[] fitnesses = new float[state.population.subpops[subpop].individuals.length]; |
---|
80 | |
---|
81 | for (int i = 0; i < state.population.subpops[subpop].individuals.length; ++i) { |
---|
82 | Individual ind = state.population.subpops[subpop].individuals[i]; |
---|
83 | fitnesses[i] = fitnessCalc.calculateObjectiveFitness(state, ind); |
---|
84 | |
---|
85 | sumFitness += fitnesses[i]; |
---|
86 | maxFitness = Math.max(maxFitness, fitnesses[i]); |
---|
87 | if (ind.fitness.fitness() > maxSubjectiveFitness) { |
---|
88 | maxSubjectiveFitness = ind.fitness.fitness(); |
---|
89 | objectiveFitnessOfSubjectivelyBest = fitnesses[i]; |
---|
90 | } |
---|
91 | } |
---|
92 | |
---|
93 | float sumSquareDiffs = 0; |
---|
94 | float avgFitness = sumFitness / state.population.subpops[subpop].individuals.length; |
---|
95 | for (int i = 0; i < state.population.subpops[subpop].individuals.length; ++i) { |
---|
96 | float diff = fitnesses[i] - avgFitness; |
---|
97 | sumSquareDiffs += (diff * diff); |
---|
98 | } |
---|
99 | |
---|
100 | double stdev = Math.sqrt(sumSquareDiffs |
---|
101 | / state.population.subpops[subpop].individuals.length); |
---|
102 | |
---|
103 | if (countLast != -1) { |
---|
104 | sumLastFitnesses -= lastFitnesses[lastCounter]; |
---|
105 | sumLastFitnesses += objectiveFitnessOfSubjectivelyBest; |
---|
106 | |
---|
107 | lastFitnesses[lastCounter] = objectiveFitnessOfSubjectivelyBest; |
---|
108 | lastCounter++; |
---|
109 | lastCounter %= countLast; |
---|
110 | |
---|
111 | float avgLastFitness = sumLastFitnesses / countLast; |
---|
112 | state.output.println(state.generation + "\t" + avgFitness + "\t" + stdev + "\t" |
---|
113 | + maxFitness + "\t" + objectiveFitnessOfSubjectivelyBest + "\t" |
---|
114 | + avgLastFitness, Output.V_VERBOSE + 1, fitnessStatisticslog); |
---|
115 | } else { |
---|
116 | state.output.println(state.generation + "\t" + avgFitness + "\t" + stdev + "\t" |
---|
117 | + maxFitness + "\t" + objectiveFitnessOfSubjectivelyBest, |
---|
118 | Output.V_VERBOSE + 1, fitnessStatisticslog); |
---|
119 | } |
---|
120 | } |
---|
121 | |
---|
122 | if (state.generation == state.numGenerations - 1) { |
---|
123 | saveIndividuals(state); |
---|
124 | } |
---|
125 | } |
---|
126 | |
---|
127 | private void saveIndividuals(EvolutionState state) { |
---|
128 | for (int subpop = 0; subpop < state.population.subpops.length; ++subpop) { |
---|
129 | state.output.println("\nSubpopulation " + subpop + " individuals : ", |
---|
130 | Output.V_VERBOSE + 1, fitnessStatisticslog); |
---|
131 | Individual[] inds = state.population.subpops[subpop].individuals; |
---|
132 | for (Individual ind : inds) { |
---|
133 | ind.printIndividual(state, fitnessStatisticslog, Output.V_VERBOSE + 1); |
---|
134 | } |
---|
135 | } |
---|
136 | } |
---|
137 | } |
---|