FitnessVarianceAdaptiveEngine.java
01 /*
02  * Java Genetic Algorithm Library (jenetics-7.1.2).
03  * Copyright (c) 2007-2023 Franz Wilhelmstötter
04  *
05  * Licensed under the Apache License, Version 2.0 (the "License");
06  * you may not use this file except in compliance with the License.
07  * You may obtain a copy of the License at
08  *
09  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * Author:
18  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
19  */
20 package io.jenetics.ext.engine;
21 
22 import static java.util.Objects.requireNonNull;
23 
24 import java.util.function.Function;
25 
26 import io.jenetics.Alterer;
27 import io.jenetics.Gene;
28 import io.jenetics.engine.Engine;
29 import io.jenetics.engine.EvolutionResult;
30 import io.jenetics.engine.EvolutionStreamable;
31 import io.jenetics.stat.DoubleMomentStatistics;
32 import io.jenetics.util.DoubleRange;
33 
34 /**
35  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
36  @version 5.0
37  @since 5.0
38  */
39 final class FitnessVarianceAdaptiveEngine<
40     extends Gene<?, G>,
41     extends Number & Comparable<? super N>
42 >
43     implements Function<EvolutionResult<G, N>, EvolutionStreamable<G, N>>
44 {
45 
46     private final DoubleRange _variance;
47     private final Engine.Builder<G, N> _builder;
48     private final Alterer<G, N> _narrow;
49     private final Alterer<G, N> _enlarge;
50 
51     private Engine<G, N> _engine;
52     private boolean _narrowing;
53 
54     FitnessVarianceAdaptiveEngine(
55         final DoubleRange variance,
56         final Engine.Builder<G, N> builder,
57         final Alterer<G, N> narrow,
58         final Alterer<G, N> enlarge
59     ) {
60         _variance = requireNonNull(variance);
61         _builder = requireNonNull(builder).copy();
62         _narrow = requireNonNull(narrow);
63         _enlarge = requireNonNull(enlarge);
64     }
65 
66     @Override
67     public EvolutionStreamable<G, N> apply(final EvolutionResult<G, N> result) {
68         if (result == null || _engine == null) {
69             _engine = _builder
70                 .alterers(_enlarge)
71                 .build();
72             _narrowing = false;
73         else {
74             final DoubleMomentStatistics stat = new DoubleMomentStatistics();
75 
76             result.population()
77                 .forEach(pt -> stat.accept(pt.fitness().doubleValue()));
78 
79             if (stat.variance() < _variance.min() && _narrowing) {
80                 _engine = _builder
81                     .alterers(_enlarge)
82                     .build();
83                 _narrowing = false;
84             else if (stat.variance() > _variance.max() && !_narrowing) {
85                 _engine = _builder
86                     .alterers(_narrow)
87                     .build();
88                 _narrowing = true;
89             }
90         }
91 
92         assert _engine != null;
93         return _engine;
94     }
95 
96 }