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