[44] | 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 | } |
---|