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