001 /*
002 * Java Genetic Algorithm Library (jenetics-5.2.0).
003 * Copyright (c) 2007-2020 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@gmail.com)
019 */
020 package io.jenetics.engine;
021
022 import static io.jenetics.internal.util.SerialIO.readInt;
023 import static io.jenetics.internal.util.SerialIO.readLong;
024 import static io.jenetics.internal.util.SerialIO.writeInt;
025 import static io.jenetics.internal.util.SerialIO.writeLong;
026 import static java.util.Objects.requireNonNull;
027 import static io.jenetics.internal.util.Hashes.hash;
028
029 import java.io.DataInput;
030 import java.io.DataOutput;
031 import java.io.IOException;
032 import java.io.InvalidObjectException;
033 import java.io.ObjectInput;
034 import java.io.ObjectInputStream;
035 import java.io.ObjectOutput;
036 import java.io.Serializable;
037 import java.time.Duration;
038 import java.util.Objects;
039
040 /**
041 * This class contains timing information about one evolution step.
042 *
043 * @implNote
044 * This class is immutable and thread-safe.
045 *
046 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
047 * @since 3.0
048 * @version 5.2
049 */
050 public final /*record*/ class EvolutionDurations
051 implements
052 Comparable<EvolutionDurations>,
053 Serializable
054 {
055 private static final long serialVersionUID = 2L;
056
057 /**
058 * Constant for zero evolution durations.
059 */
060 public static final EvolutionDurations ZERO = EvolutionDurations.of(
061 Duration.ZERO,
062 Duration.ZERO,
063 Duration.ZERO,
064 Duration.ZERO,
065 Duration.ZERO,
066 Duration.ZERO,
067 Duration.ZERO
068 );
069
070 private final Duration _offspringSelectionDuration;
071 private final Duration _survivorsSelectionDuration;
072 private final Duration _offspringAlterDuration;
073 private final Duration _offspringFilterDuration;
074 private final Duration _survivorFilterDuration;
075 private final Duration _evaluationDuration;
076 private final Duration _evolveDuration;
077
078 EvolutionDurations(
079 final Duration offspringSelectionDuration,
080 final Duration survivorsSelectionDuration,
081 final Duration offspringAlterDuration,
082 final Duration offspringFilterDuration,
083 final Duration survivorFilterDuration,
084 final Duration evaluationDuration,
085 final Duration evolveDuration
086 ) {
087 _offspringSelectionDuration = requireNonNull(offspringSelectionDuration);
088 _survivorsSelectionDuration = requireNonNull(survivorsSelectionDuration);
089 _offspringAlterDuration = requireNonNull(offspringAlterDuration);
090 _offspringFilterDuration = requireNonNull(offspringFilterDuration);
091 _survivorFilterDuration = requireNonNull(survivorFilterDuration);
092 _evaluationDuration = requireNonNull(evaluationDuration);
093 _evolveDuration = requireNonNull(evolveDuration);
094 }
095
096 /**
097 * Return the duration needed for selecting the offspring population.
098 *
099 * @return the duration needed for selecting the offspring population
100 */
101 public Duration offspringSelectionDuration() {
102 return _offspringSelectionDuration;
103 }
104
105 /**
106 * Return the duration needed for selecting the offspring population.
107 *
108 * @return the duration needed for selecting the offspring population
109 * @deprecated Use {@link #offspringSelectionDuration()} instead
110 */
111 @Deprecated
112 public Duration getOffspringSelectionDuration() {
113 return _offspringSelectionDuration;
114 }
115
116 /**
117 * Return the duration needed for selecting the survivors population.
118 *
119 * @return the duration needed for selecting the survivors population
120 */
121 public Duration survivorsSelectionDuration() {
122 return _survivorsSelectionDuration;
123 }
124
125 /**
126 * Return the duration needed for selecting the survivors population.
127 *
128 * @return the duration needed for selecting the survivors population
129 * @deprecated Use {@link #survivorsSelectionDuration()} instead
130 */
131 @Deprecated
132 public Duration getSurvivorsSelectionDuration() {
133 return _survivorsSelectionDuration;
134 }
135
136 /**
137 * Return the duration needed for altering the offspring population.
138 *
139 * @return the duration needed for altering the offspring population
140 */
141 public Duration offspringAlterDuration() {
142 return _offspringAlterDuration;
143 }
144
145 /**
146 * Return the duration needed for altering the offspring population.
147 *
148 * @return the duration needed for altering the offspring population
149 * @deprecated Use {@link #offspringAlterDuration()} instead
150 */
151 @Deprecated
152 public Duration getOffspringAlterDuration() {
153 return _offspringAlterDuration;
154 }
155
156 /**
157 * Return the duration needed for removing and replacing invalid offspring
158 * individuals.
159 *
160 * @return the duration needed for removing and replacing invalid offspring
161 * individuals
162 */
163 public Duration offspringFilterDuration() {
164 return _offspringFilterDuration;
165 }
166
167 /**
168 * Return the duration needed for removing and replacing invalid offspring
169 * individuals.
170 *
171 * @return the duration needed for removing and replacing invalid offspring
172 * individuals
173 * @deprecated Use {@link #offspringFilterDuration()} instead
174 */
175 @Deprecated
176 public Duration getOffspringFilterDuration() {
177 return _offspringFilterDuration;
178 }
179
180 /**
181 * Return the duration needed for removing and replacing old and invalid
182 * survivor individuals.
183 *
184 * @return the duration needed for removing and replacing old and invalid
185 * survivor individuals
186 */
187 public Duration survivorFilterDuration() {
188 return _survivorFilterDuration;
189 }
190
191 /**
192 * Return the duration needed for removing and replacing old and invalid
193 * survivor individuals.
194 *
195 * @return the duration needed for removing and replacing old and invalid
196 * survivor individuals
197 * @deprecated Use {@link #survivorFilterDuration()} instead
198 */
199 @Deprecated
200 public Duration getSurvivorFilterDuration() {
201 return _survivorFilterDuration;
202 }
203
204 /**
205 * Return the duration needed for evaluating the fitness function of the new
206 * individuals.
207 *
208 * @return the duration needed for evaluating the fitness function of the new
209 * individuals
210 */
211 public Duration evaluationDuration() {
212 return _evaluationDuration;
213 }
214
215 /**
216 * Return the duration needed for evaluating the fitness function of the new
217 * individuals.
218 *
219 * @return the duration needed for evaluating the fitness function of the new
220 * individuals
221 * @deprecated Use {@link #evaluationDuration()} instead
222 */
223 @Deprecated
224 public Duration getEvaluationDuration() {
225 return _evaluationDuration;
226 }
227
228 /**
229 * Return the duration needed for the whole evolve step.
230 *
231 * @return the duration needed for the whole evolve step
232 */
233 public Duration evolveDuration() {
234 return _evolveDuration;
235 }
236
237 /**
238 * Return the duration needed for the whole evolve step.
239 *
240 * @return the duration needed for the whole evolve step
241 * @deprecated Use {@link #evolveDuration()} instead
242 */
243 @Deprecated
244 public Duration getEvolveDuration() {
245 return _evolveDuration;
246 }
247
248 /**
249 * Returns a copy of this duration with the specified duration added.
250 * <p>
251 * This instance is immutable and unaffected by this method call.
252 *
253 * @param other the duration to add
254 * @return a {@code EvolutionDurations} based on this duration with the
255 * specified duration added
256 * @throws NullPointerException if the {@code other} duration is {@code null}
257 * @throws ArithmeticException if numeric overflow occurs
258 */
259 public EvolutionDurations plus(final EvolutionDurations other) {
260 requireNonNull(other);
261 return of(
262 _offspringSelectionDuration.plus(other._offspringSelectionDuration),
263 _survivorsSelectionDuration.plus(other._survivorsSelectionDuration),
264 _offspringAlterDuration.plus(other._offspringAlterDuration),
265 _offspringFilterDuration.plus(other._offspringFilterDuration),
266 _survivorFilterDuration.plus(other._survivorFilterDuration),
267 _evaluationDuration.plus(other._evaluationDuration),
268 _evolveDuration.plus(other._evolveDuration)
269 );
270 }
271
272 EvolutionDurations plusEvaluation(final Duration duration) {
273 return of(
274 _offspringSelectionDuration,
275 _survivorsSelectionDuration,
276 _offspringAlterDuration,
277 _offspringFilterDuration,
278 _survivorFilterDuration,
279 _evaluationDuration.plus(duration),
280 _evolveDuration
281 );
282 }
283
284 EvolutionDurations plusEvolve(final Duration duration) {
285 return of(
286 _offspringSelectionDuration,
287 _survivorsSelectionDuration,
288 _offspringAlterDuration,
289 _offspringFilterDuration,
290 _survivorFilterDuration,
291 _evaluationDuration,
292 _evolveDuration.plus(duration)
293 );
294 }
295
296 /**
297 * Compares two durations objects. Only the {@link #evolveDuration()}
298 * property is taken into account for the comparison.
299 *
300 * @param other the other durations object this object is compared with
301 * @return a integer smaller/equal/greater than 0 if the
302 * {@link #evolveDuration()} property of {@code this} object is
303 * smaller/equal/greater than the corresponding property of the
304 * {@code other} project.
305 */
306 @Override
307 public int compareTo(final EvolutionDurations other) {
308 return _evolveDuration.compareTo(other._evolveDuration);
309 }
310
311 @Override
312 public int hashCode() {
313 return
314 hash(_offspringSelectionDuration,
315 hash(_survivorFilterDuration,
316 hash(_offspringAlterDuration,
317 hash(_offspringFilterDuration,
318 hash(_survivorsSelectionDuration,
319 hash(_evaluationDuration,
320 hash(_evolveDuration)))))));
321 }
322
323 @Override
324 public boolean equals(final Object obj) {
325 return obj == this ||
326 obj instanceof EvolutionDurations &&
327 Objects.equals(_offspringSelectionDuration,
328 ((EvolutionDurations)obj)._offspringSelectionDuration) &&
329 Objects.equals(_survivorsSelectionDuration,
330 ((EvolutionDurations)obj)._survivorsSelectionDuration) &&
331 Objects.equals(_offspringAlterDuration,
332 ((EvolutionDurations)obj)._offspringAlterDuration) &&
333 Objects.equals(_offspringFilterDuration,
334 ((EvolutionDurations)obj)._offspringFilterDuration) &&
335 Objects.equals(_survivorFilterDuration,
336 ((EvolutionDurations)obj)._survivorFilterDuration) &&
337 Objects.equals(_evaluationDuration,
338 ((EvolutionDurations)obj)._evaluationDuration) &&
339 Objects.equals(_evolveDuration,
340 ((EvolutionDurations)obj)._evolveDuration);
341 }
342
343 /**
344 * Return an new {@code EvolutionDurations} object with the given values.
345 *
346 * @param offspringSelectionDuration the duration needed for selecting the
347 * offspring population
348 * @param survivorsSelectionDuration the duration needed for selecting the
349 * survivors population
350 * @param offspringAlterDuration the duration needed for altering the
351 * offspring population
352 * @param offspringFilterDuration the duration needed for removing and
353 * replacing invalid offspring individuals
354 * @param survivorFilterDuration the duration needed for removing and
355 * replacing old and invalid survivor individuals
356 * @param evaluationDuration the duration needed for evaluating the fitness
357 * function of the new individuals
358 * @param evolveDuration the duration needed for the whole evolve step
359 * @return an new durations object
360 * @throws NullPointerException if one of the arguments is
361 * {@code null}
362 */
363 public static EvolutionDurations of(
364 final Duration offspringSelectionDuration,
365 final Duration survivorsSelectionDuration,
366 final Duration offspringAlterDuration,
367 final Duration offspringFilterDuration,
368 final Duration survivorFilterDuration,
369 final Duration evaluationDuration,
370 final Duration evolveDuration
371 ) {
372 return new EvolutionDurations(
373 offspringSelectionDuration,
374 survivorsSelectionDuration,
375 offspringAlterDuration,
376 offspringFilterDuration,
377 survivorFilterDuration,
378 evaluationDuration,
379 evolveDuration
380 );
381 }
382
383
384 /* *************************************************************************
385 * Java object serialization
386 * ************************************************************************/
387
388 private Object writeReplace() {
389 return new Serial(Serial.EVOLUTION_DURATIONS, this);
390 }
391
392 private void readObject(final ObjectInputStream stream)
393 throws InvalidObjectException
394 {
395 throw new InvalidObjectException("Serialization proxy required.");
396 }
397
398 void write(final ObjectOutput out) throws IOException {
399 writeDuration(_offspringSelectionDuration, out);
400 writeDuration(_survivorsSelectionDuration, out);
401 writeDuration(_offspringAlterDuration, out);
402 writeDuration(_offspringFilterDuration, out);
403 writeDuration(_survivorFilterDuration, out);
404 writeDuration(_evaluationDuration, out);
405 writeDuration(_evolveDuration, out);
406 }
407
408 private static void writeDuration(final Duration duration, final DataOutput out)
409 throws IOException
410 {
411 writeLong(duration.getSeconds(), out);
412 writeInt(duration.getNano(), out);
413 }
414
415 @SuppressWarnings({"unchecked", "rawtypes"})
416 static EvolutionDurations read(final ObjectInput in) throws IOException {
417 return new EvolutionDurations(
418 readDuration(in),
419 readDuration(in),
420 readDuration(in),
421 readDuration(in),
422 readDuration(in),
423 readDuration(in),
424 readDuration(in)
425 );
426 }
427
428 private static Duration readDuration(final DataInput in) throws IOException {
429 final long seconds = readLong(in);
430 final int nanos = readInt(in);
431 return Duration.ofSeconds(seconds, nanos);
432 }
433
434 }
|