EvolutionStream.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-4.0.0).
003  * Copyright (c) 2007-2017 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 java.util.function.Function;
023 import java.util.function.Predicate;
024 import java.util.function.Supplier;
025 import java.util.stream.Stream;
026 
027 import io.jenetics.Gene;
028 
029 /**
030  * The {@code EvolutionStream} class extends the Java {@link Stream} and adds a
031  * method for limiting the evolution by a given predicate.
032  *
033  @see java.util.stream.Stream
034  @see Engine
035  *
036  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
037  @since 3.0
038  @version 3.1
039  */
040 public interface EvolutionStream<
041     extends Gene<?, G>,
042     extends Comparable<? super C>
043 >
044     extends Stream<EvolutionResult<G, C>>
045 {
046 
047     /**
048      * Returns a stream consisting of the elements of this stream, truncated
049      * when the given {@code proceed} predicate returns {@code false}.
050      <p>
051      <i>General usage example:</i>
052      <pre>{@code
053      * final Phenotype<DoubleGene, Double> result = engine.stream()
054      *      // Truncate the evolution stream after 5 "steady" generations.
055      *     .limit(bySteadyFitness(5))
056      *      // The evolution will stop after maximal 100 generations.
057      *     .limit(100)
058      *     .collect(toBestPhenotype());
059      * }</pre>
060      *
061      @see Limits
062      *
063      @param proceed the predicate which determines whether the stream is
064      *        truncated or not. <i>If the predicate returns {@code false}, the
065      *        evolution stream is truncated.</i>
066      @return the new stream
067      @throws NullPointerException if the given predicate is {@code null}.
068      */
069     public EvolutionStream<G, C>
070     limit(final Predicate<? super EvolutionResult<G, C>> proceed);
071 
072     /**
073      * Create a new {@code EvolutionStream} from the given {@code start}
074      * population and {@code evolution} function. The main purpose of this
075      * factory method is to simplify the creation of an {@code EvolutionStream}
076      * from an own evolution (GA) engine.
077      *
078      <pre>{@code
079      * final Supplier<EvolutionStart<DoubleGene, Double>> start = ...
080      * final EvolutionStream<DoubleGene, Double> stream =
081      *     EvolutionStream.of(start, new MySpecialEngine());
082      * }</pre>
083      *
084      * A more complete example for would look like as:
085      *
086      <pre>{@code
087      * public final class SpecialEngine {
088      *
089      *     // The fitness function.
090      *     private static Double fitness(final Genotype<DoubleGene> gt) {
091      *         return gt.getGene().getAllele();
092      *     }
093      *
094      *     // Create new evolution start object.
095      *     private static EvolutionStart<DoubleGene, Double>
096      *     start(final int populationSize, final long generation) {
097      *         final Population<DoubleGene, Double> population =
098      *             Genotype.of(DoubleChromosome.of(0, 1)).instances()
099      *                 .map(gt -> Phenotype.of(gt, generation, SpecialEngine::fitness))
100      *                 .limit(populationSize)
101      *                 .collect(Population.toPopulation());
102      *
103      *         return EvolutionStart.of(population, generation);
104      *     }
105      *
106      *     // The special evolution function.
107      *     private static EvolutionResult<DoubleGene, Double>
108      *     evolve(final EvolutionStart<DoubleGene, Double> start) {
109      *         // Your special evolution implementation comes here!
110      *         return null;
111      *     }
112      *
113      *     public static void main(final String[] args) {
114      *         final Genotype<DoubleGene> best = EvolutionStream
115      *             .of(() -> start(50, 0), SpecialEngine::evolve)
116      *             .limit(Limits.bySteadyFitness(10))
117      *             .limit(1000)
118      *             .collect(EvolutionResult.toBestGenotype());
119      *
120      *         System.out.println(String.format("Best Genotype: %s", best));
121      *     }
122      * }
123      * }</pre>
124      *
125      *
126      @since 3.1
127      *
128      @param <G> the gene type
129      @param <C> the fitness type
130      @param start the evolution start
131      @param evolution the evolution function
132      @return a new {@code EvolutionStream} with the given {@code start} and
133      *         {@code evolution} function
134      @throws java.lang.NullPointerException if one of the arguments is
135      *         {@code null}
136      */
137     public static <G extends Gene<?, G>, C extends Comparable<? super C>>
138     EvolutionStream<G, C> of(
139         final Supplier<EvolutionStart<G, C>> start,
140         final Function<? super EvolutionStart<G, C>, EvolutionResult<G, C>> evolution
141     ) {
142         return new EvolutionStreamImpl<>(start, evolution);
143     }
144 
145 }