001 /*
002 * Java Genetic Algorithm Library (jenetics-6.1.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 java.util.Objects.requireNonNull;
023
024 import java.util.function.Function;
025
026 import io.jenetics.Gene;
027
028 /**
029 * The evolution interceptor allows to update the {@link EvolutionStart} object,
030 * <em>before</em> the evolution start, and update the {@link EvolutionResult}
031 * object <em>after</em> the evolution.
032 *
033 * @see EvolutionResult#toUniquePopulation()
034 * @see Engine.Builder#interceptor(EvolutionInterceptor)
035 *
036 * @param <G> the gene type
037 * @param <C> the fitness result type
038 *
039 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
040 * @since 6.0
041 * @version 6.0
042 */
043 public interface EvolutionInterceptor<
044 G extends Gene<?, G>,
045 C extends Comparable<? super C>
046 > {
047
048 /**
049 * This method is called right before the evaluation of a generation is
050 * started.
051 *
052 * @param start the evolution start object
053 * @return the possible <em>update</em> evolution start object
054 * @throws NullPointerException if the evolution {@code start} object is
055 * {@code null}
056 */
057 default EvolutionStart<G, C> before(final EvolutionStart<G, C> start) {
058 return start;
059 }
060
061 /**
062 * This method is called after the evaluation of a generation. If this
063 * method alters the evolution result object, the population within this
064 * result object is re-evaluated.
065 *
066 * @param result the evolution result object to update
067 * @return the possible <em>updated</em> evolution result object
068 * @throws NullPointerException if the evolution {@code result} object is
069 * {@code null}
070 */
071 default EvolutionResult<G, C> after(final EvolutionResult<G, C> result) {
072 return result;
073 }
074
075 /**
076 * Composes {@code this} interceptor with the {@code other} one. The
077 * {@link #before(EvolutionStart)} of {@code this} interceptor is called
078 * <em>after</em> the {@code before} method of the {@code other} interceptor.
079 * And the {@link #after(EvolutionResult)} of {@code this} interceptor is
080 * called <em>before</em> the {@code after} method of the {@code other}
081 * interceptor.
082 *
083 * @param other the other, composing interceptor
084 * @return a new, composed interceptor
085 * @throws NullPointerException if the {@code other} interceptor is
086 * {@code null}
087 */
088 default EvolutionInterceptor<G, C>
089 compose(final EvolutionInterceptor<G, C> other) {
090 requireNonNull(other);
091 return EvolutionInterceptor.of(
092 start -> before(other.before(start)),
093 result -> other.after(after(result))
094 );
095 }
096
097 /**
098 * Create a new interceptor instance with the given {@code before} and
099 * {@code after} functions.
100 *
101 * @param before the function executed before each evolution step
102 * @param after the function executed after each evolution step
103 * @param <G> the gene type
104 * @param <C> the fitness result type
105 * @return a new interceptor instance with the given interceptor functions
106 * @throws NullPointerException if one of the functions is {@code null}
107 */
108 public static <G extends Gene<?, G>, C extends Comparable<? super C>>
109 EvolutionInterceptor<G, C> of(
110 final Function<? super EvolutionStart<G, C>, EvolutionStart<G, C>> before,
111 final Function<? super EvolutionResult<G, C>, EvolutionResult<G, C>> after
112 ) {
113 requireNonNull(before);
114 requireNonNull(after);
115
116 return new EvolutionInterceptor<>() {
117 @Override
118 public EvolutionStart<G, C> before(final EvolutionStart<G, C> start) {
119 return before.apply(start);
120 }
121
122 @Override
123 public EvolutionResult<G, C> after(final EvolutionResult<G, C> result) {
124 return after.apply(result);
125 }
126 };
127 }
128
129 /**
130 * Create a new interceptor instance with the given {@code before} function.
131 *
132 * @param before the function executed before each evolution step
133 * @param <G> the gene type
134 * @param <C> the fitness result type
135 * @return a new interceptor instance with the given interceptor function
136 * @throws NullPointerException if the function is {@code null}
137 */
138 public static <G extends Gene<?, G>, C extends Comparable<? super C>>
139 EvolutionInterceptor<G, C>
140 ofBefore(final Function<? super EvolutionStart<G, C>, EvolutionStart<G, C>> before) {
141 return EvolutionInterceptor.of(before, Function.identity());
142 }
143
144 /**
145 * Create a new interceptor instance with the given {@code after} function.
146 *
147 * @param after the function executed after each evolution step
148 * @param <G> the gene type
149 * @param <C> the fitness result type
150 * @return a new interceptor instance with the given interceptor function
151 * @throws NullPointerException if the function is {@code null}
152 */
153 public static <G extends Gene<?, G>, C extends Comparable<? super C>>
154 EvolutionInterceptor<G, C>
155 ofAfter(final Function<? super EvolutionResult<G, C>, EvolutionResult<G, C>> after) {
156 return EvolutionInterceptor.of(Function.identity(), after);
157 }
158
159 /**
160 * Return an interceptor object which does nothing.
161 *
162 * @param <G> the gene type
163 * @param <C> the fitness result type
164 * @return a new <em>identity</em> interceptor
165 */
166 public static <G extends Gene<?, G>, C extends Comparable<? super C>>
167 EvolutionInterceptor<G, C> identity() {
168 return EvolutionInterceptor.of(Function.identity(), Function.identity());
169 }
170
171 }
|