001/* 002 * Java Genetic Algorithm Library (jenetics-1.6.0). 003 * Copyright (c) 2007-2014 Franz Wilhelmstötter 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 * Author: 018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at) 019 */ 020package org.jenetics; 021 022import static java.lang.Double.NaN; 023import static java.lang.String.format; 024import static org.jenetics.internal.util.object.eq; 025 026import javolution.xml.XMLFormat; 027import javolution.xml.stream.XMLStreamException; 028 029import org.jscience.mathematics.number.Float64; 030 031import org.jenetics.internal.util.HashBuilder; 032 033import org.jenetics.stat.Variance; 034import org.jenetics.util.accumulators; 035import org.jenetics.util.accumulators.MinMax; 036 037/** 038 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a> 039 * @since 1.0 040 * @version 1.0 — <em>$Date: 2014-03-01 $</em> 041 */ 042public class NumberStatistics< 043 G extends Gene<?, G>, 044 R extends Number & Comparable<? super R> 045> 046 extends Statistics<G, R> 047{ 048 049 /** 050 * Builder for the NumberStatistics class. 051 * 052 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a> 053 * @since 1.0 054 * @version 1.0 — <em>$Date: 2014-03-01 $</em> 055 */ 056 public static class Builder< 057 G extends Gene<?, G>, 058 R extends Number & Comparable<? super R> 059 > 060 extends Statistics.Builder<G, R> 061 { 062 protected double _fitnessMean = NaN; 063 protected double _fitnessVariance = NaN; 064 protected double _standardError = NaN; 065 066 /** 067 * Create a new NumberStatistics builder. 068 */ 069 public Builder() { 070 } 071 072 @Override 073 public Builder<G, R> statistics(final Statistics<G, R> statistics) { 074 super.statistics(statistics); 075 return this; 076 } 077 078 /** 079 * Set the values of this builder with the values of the given 080 * {@code statistics}. 081 * 082 * @param statistics the statistics values. If the {@code statistics} 083 * is {@code null} nothing is set. 084 * @return this builder. 085 */ 086 public Builder<G, R> statistics(final NumberStatistics<G, R> statistics) { 087 if (statistics != null) { 088 super.statistics(statistics); 089 _fitnessMean = statistics._fitnessMean; 090 _fitnessVariance = statistics._fitnessVariance; 091 _standardError = statistics._standardError; 092 } 093 return this; 094 } 095 096 /** 097 * @see NumberStatistics#getFitnessMean() 098 */ 099 public Builder<G, R> fitnessMean(final double fitnessMean) { 100 _fitnessMean = fitnessMean; 101 return this; 102 } 103 104 /** 105 * @see NumberStatistics#getFitnessVariance() 106 */ 107 public Builder<G, R> fitnessVariance(final double fitnessVariance) { 108 _fitnessVariance = fitnessVariance; 109 return this; 110 } 111 112 /** 113 * @see NumberStatistics#getStandardError() 114 */ 115 public Builder<G, R> standardError(final double standardError) { 116 _standardError = standardError; 117 return this; 118 } 119 120 @Override 121 public NumberStatistics<G, R> build() { 122 return new NumberStatistics<>( 123 _optimize, 124 _generation, 125 _best, 126 _worst, 127 _fitnessMean, 128 _fitnessVariance, 129 _samples, 130 _ageMean, 131 _ageVariance, 132 _standardError, 133 _killed, 134 _invalid 135 ); 136 } 137 } 138 139 private static final long serialVersionUID = 2L; 140 141 protected final double _fitnessMean; 142 protected final double _fitnessVariance; 143 protected final double _standardError; 144 145 protected NumberStatistics( 146 final Optimize optimize, 147 final int generation, 148 final Phenotype<G, R> best, 149 final Phenotype<G, R> worst, 150 final double fitnessMean, 151 final double fitnessVariance, 152 final int samples, 153 final double ageMean, 154 final double ageVariance, 155 final double errorOfMean, 156 final int killed, 157 final int invalid 158 ) { 159 super( 160 optimize, 161 generation, 162 best, 163 worst, 164 samples, 165 ageMean, 166 ageVariance, 167 killed, 168 invalid 169 ); 170 171 _fitnessMean = fitnessMean; 172 _fitnessVariance = fitnessVariance; 173 _standardError = errorOfMean; 174 } 175 176 /** 177 * Return the mean of the fitness values. 178 * 179 * @return the mean of the fitness values. 180 */ 181 public double getFitnessMean() { 182 return _fitnessMean; 183 } 184 185 /** 186 * Return the variance of the fitness values. 187 * 188 * @return the variance of the fitness values. 189 */ 190 public double getFitnessVariance() { 191 return _fitnessVariance; 192 } 193 194 /** 195 * Return the <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Standard_error_%28statistics%29"> 196 * Standard error 197 * </a> of the calculated fitness mean. 198 * 199 * @return the standard error of the calculated fitness mean. 200 */ 201 public double getStandardError() { 202 return _standardError; 203 } 204 205 @Override 206 public int hashCode() { 207 return HashBuilder.of(getClass()). 208 and(super.hashCode()). 209 and(_fitnessMean). 210 and(_fitnessVariance). 211 and(_standardError).value(); 212 } 213 214 @Override 215 public boolean equals(final Object obj) { 216 if (obj == this) { 217 return true; 218 } 219 if (!(obj instanceof NumberStatistics<?, ?>)) { 220 return false; 221 } 222 223 final NumberStatistics<?, ?> statistics = (NumberStatistics<?, ?>) obj; 224 return eq(statistics._fitnessMean, _fitnessMean) && 225 eq(statistics._fitnessVariance, _fitnessVariance) && 226 eq(statistics._standardError, _standardError) && 227 super.equals(obj); 228 } 229 230 @Override 231 public String toString() { 232 final String fpattern = "| %28s: %-26.11f|\n"; 233 234 final StringBuilder out = new StringBuilder(); 235 out.append(super.toString()).append("\n"); 236 out.append("+---------------------------------------------------------+\n"); 237 out.append("| Fitness Statistics |\n"); 238 out.append("+---------------------------------------------------------+\n"); 239 out.append(format(fpattern, "Fitness mean", _fitnessMean)); 240 out.append(format(fpattern, "Fitness variance", _fitnessVariance)); 241 out.append(format(fpattern, "Fitness error of mean", _standardError)); 242 out.append("+---------------------------------------------------------+"); 243 244 return out.toString(); 245 } 246 247 @SuppressWarnings({ "unchecked", "rawtypes" }) 248 static final XMLFormat<NumberStatistics> XML = 249 new XMLFormat<NumberStatistics>(NumberStatistics.class) 250 { 251 private static final String FITNESS_MEAN = "fitness-mean"; 252 private static final String FITNESS_VARIANCE = "fitness-variance"; 253 private static final String ERROR_OF_MEAN = "error-of-mean"; 254 255 @Override 256 public NumberStatistics newInstance( 257 final Class<NumberStatistics> type, 258 final InputElement xml 259 ) 260 throws XMLStreamException 261 { 262 final Statistics stats = Statistics.XML.newInstance( 263 Statistics.class, xml 264 ); 265 final Float64 fitnessMean = xml.get(FITNESS_MEAN); 266 final Float64 fitnessVariance = xml.get(FITNESS_VARIANCE); 267 final Float64 errorOfMean = xml.get(ERROR_OF_MEAN); 268 269 final Builder builder = new Builder().statistics(stats); 270 builder.fitnessMean(fitnessMean.doubleValue()); 271 builder.fitnessVariance(fitnessVariance.doubleValue()); 272 builder.standardError(errorOfMean.doubleValue()); 273 274 return builder.build(); 275 } 276 277 @Override 278 public void write(final NumberStatistics s, final OutputElement xml) 279 throws XMLStreamException 280 { 281 Statistics.XML.write(s, xml); 282 xml.add(Float64.valueOf(s.getFitnessMean()), FITNESS_MEAN); 283 xml.add(Float64.valueOf(s.getFitnessVariance()), FITNESS_VARIANCE); 284 xml.add(Float64.valueOf(s.getStandardError()), ERROR_OF_MEAN); 285 } 286 287 @Override 288 public void read(final InputElement xml, final NumberStatistics p) { 289 } 290 }; 291 292 /** 293 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a> 294 * @since 1.0 295 * @version 1.0 — <em>$Date: 2014-03-01 $</em> 296 */ 297 public static class Calculator< 298 G extends Gene<?, G>, 299 R extends Number & Comparable<? super R> 300 > 301 extends Statistics.Calculator<G, R> 302 { 303 304 public Calculator() { 305 } 306 307 @Override 308 public NumberStatistics.Builder<G, R> evaluate( 309 final Iterable<? extends Phenotype<G, R>> population, 310 final int generation, 311 final Optimize opt 312 ) { 313 final Builder<G, R> builder = new Builder<>(); 314 builder.generation(generation); 315 builder.optimize(opt); 316 317 final MinMax<Phenotype<G, R>> minMax = new MinMax<>(); 318 final Variance<Integer> age = new Variance<>(); 319 final Variance<R> fitness = new Variance<>(); 320 321 accumulators.<Phenotype<G, R>>accumulate( 322 population, 323 minMax, 324 age.map(Phenotype.Age(generation)), 325 fitness.map(Phenotype.<R>Fitness()) 326 ); 327 builder.bestPhenotype(opt.best(minMax.getMax(), minMax.getMin())); 328 builder.worstPhenotype(opt.worst(minMax.getMax(), minMax.getMin())); 329 builder.fitnessMean(fitness.getMean()); 330 builder.fitnessVariance(fitness.getVariance()); 331 builder.samples((int)minMax.getSamples()); 332 builder.ageMean(age.getMean()); 333 builder.ageVariance(age.getVariance()); 334 builder.standardError(fitness.getStandardError()); 335 336 return builder; 337 } 338 } 339 340}