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 */
020 package org.jenetics;
021
022 import static java.lang.Double.NaN;
023 import static java.lang.String.format;
024 import static org.jenetics.internal.util.object.eq;
025
026 import javolution.xml.XMLFormat;
027 import javolution.xml.stream.XMLStreamException;
028
029 import org.jscience.mathematics.number.Float64;
030
031 import org.jenetics.internal.util.HashBuilder;
032
033 import org.jenetics.stat.Variance;
034 import org.jenetics.util.accumulators;
035 import 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 */
042 public 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 }
|