Constraint.java
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     extends Gene<?, G>,
058     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 }