001 /*
002 * Java Genetic Algorithm Library (jenetics-5.1.0).
003 * Copyright (c) 2007-2019 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.BiFunction;
025 import java.util.function.Predicate;
026
027 import io.jenetics.Gene;
028 import io.jenetics.Phenotype;
029
030 /**
031 * This interface allows you to define constraints on single phenotypes. It is a
032 * more advanced version of the {@link Phenotype#isValid()} method, which checks
033 * the validity of the underlying genotypes and/or chromosomes. Additionally it
034 * is possible to <em>repair</em> invalid individuals. The evolution
035 * {@link Engine} is using the constraint in the following way: check the validity
036 * and repair invalid individuals.
037 * <pre>{@code
038 * for (int i = 0; i < population.size(); ++i) {
039 * final Phenotype<G, C> individual = population.get(i);
040 * if (!constraint.test(individual)) {
041 * population.set(i, constraint.repair(individual, generation));
042 * }
043 * }
044 * }</pre>
045 *
046 * @see Engine.Builder#constraint(Constraint)
047 *
048 * @apiNote
049 * This class is part of the more advanced API and is not needed for default use
050 * cases.
051 *
052 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
053 * @version 5.0
054 * @since 5.0
055 */
056 public interface Constraint<
057 G extends Gene<?, G>,
058 C extends Comparable<? super C>
059 > {
060
061 /**
062 * Checks the validity of the given {@code individual}.
063 *
064 * @param individual the phenotype to check
065 * @return {@code true} if the given {@code individual} is valid,
066 * {@code false} otherwise
067 * @throws NullPointerException if the given {@code individual} is
068 * {@code null}
069 */
070 public boolean test(final Phenotype<G, C> individual);
071
072 /**
073 * Tries to repair the given phenotype. This method is called by the
074 * evolution {@link Engine} if the {@link #test(Phenotype)} method returned
075 * {@code false}.
076 *
077 * @param individual the phenotype to repair
078 * @param generation the actual generation used for the repaired phenotype
079 * @return a newly created, valid phenotype. The implementation is free to
080 * use the given invalid {@code individual} as a starting point for
081 * the created phenotype.
082 * @throws NullPointerException if the given {@code individual} is
083 * {@code null}
084 */
085 public Phenotype<G, C> repair(
086 final Phenotype<G, C> individual,
087 final long generation
088 );
089
090
091 /**
092 * Return a new constraint object with the given {@code validator} and
093 * {@code repairer}.
094 *
095 * @param validator the phenotype validator used by the constraint
096 * @param repairer the phenotype repairer used by the constraint
097 * @param <G> the gene type
098 * @param <C> the fitness value type
099 * @return a new constraint strategy
100 * @throws NullPointerException if one of the arguments is {@code null}
101 */
102 public static <G extends Gene<?, G>, C extends Comparable<? super C>>
103 Constraint<G, C> of(
104 final Predicate<? super Phenotype<G, C>> validator,
105 final BiFunction<? super Phenotype<G, C>, Long, Phenotype<G, C>> repairer
106 ) {
107 requireNonNull(validator);
108 requireNonNull(repairer);
109
110 return new Constraint<G, C>() {
111 @Override
112 public boolean test(final Phenotype<G, C> individual) {
113 return validator.test(individual);
114 }
115
116 @Override
117 public Phenotype<G, C> repair(
118 final Phenotype<G, C> individual,
119 final long generation
120 ) {
121 return repairer.apply(individual, generation);
122 }
123 };
124 }
125
126 /**
127 * Return a new constraint object with the given {@code validator}. The used
128 * repairer just creates a new phenotype by using the phenotype to be
129 * repaired as template. The <em>repaired</em> phenotype might still be
130 * invalid.
131 *
132 * @param validator the phenotype validator used by the constraint
133 * @param <G> the gene type
134 * @param <C> the fitness value type
135 * @return a new constraint strategy
136 * @throws NullPointerException if one of the arguments is {@code null}
137 */
138 public static <G extends Gene<?, G>, C extends Comparable<? super C>>
139 Constraint<G, C> of(final Predicate<? super Phenotype<G, C>> validator) {
140 return of(
141 validator,
142 (pt, gen) -> Phenotype.of(pt.getGenotype().newInstance(), gen)
143 );
144 }
145
146 }
|