Class Limits


  • public final class Limits
    extends Object
    This class contains factory methods for creating predicates, which can be used for limiting the evolution stream. Some of the limit predicates have to maintain internal state for working properly. It is therefor recommended to create new instances for every stream and don't reuse it.
    Since:
    3.0
    Version:
    3.7
    See Also:
    EvolutionStream.limit(Predicate)
    • Method Detail

      • infinite

        public static Predicate<Objectinfinite()
        Return a predicate which always return true.
        Returns:
        a predicate which always return true
        Since:
        4.1
      • byFixedGeneration

        public static Predicate<ObjectbyFixedGeneration​(long generation)
        Return a predicate, which will truncate the evolution stream after the given number of generations. The returned predicate behaves like a call of the Stream.limit(long) and exists for completeness reasons.
        Parameters:
        generation - the number of generations after the evolution stream is truncated
        Returns:
        a predicate which truncates the evolution stream after the given number of generations
        Throws:
        IllegalArgumentException - if the given generation is smaller than zero.
        Since:
        3.1
        Implementation Note:
        This predicate is mainly there for completion reason and behaves exactly as the Stream.limit(long) function, except for the number of evaluations performed by the resulting stream. The evaluation of the population is max generations + 1. This is because the limiting predicate works on the EvolutionResult object, which guarantees to contain an evaluated population. That means, that the population must be evaluated at least once, even for a generation limit of zero. If this is an unacceptable performance penalty, better use the Stream.limit(long) function instead.
      • bySteadyFitness

        public static <C extends Comparable<? super C>> Predicate<EvolutionResult<?,​C>> bySteadyFitness​(int generations)
        Return a predicate, which will truncate the evolution stream if no better phenotype could be found after the given number of generations.
        final Phenotype<DoubleGene, Double> result = engine.stream() // Truncate the evolution stream after 5 "steady" generations. .limit(bySteadyFitness(5)) // The evolution will stop after maximal 100 generations. .limit(100) .collect(toBestPhenotype());
        Type Parameters:
        C - the fitness type
        Parameters:
        generations - the number of steady generations
        Returns:
        a predicate which truncate the evolution stream if no better phenotype could be found after a give number of generations
        Throws:
        IllegalArgumentException - if the generation is smaller than one.
      • byExecutionTime

        public static Predicate<ObjectbyExecutionTime​(Duration duration,
                                                        Clock clock)
        Return a predicate, which will truncate the evolution stream if the GA execution exceeds a given time duration. This predicate is (normally) used as safety net, for guaranteed stream truncation.
        final Phenotype<DoubleGene, Double> result = engine.stream() // Truncate the evolution stream after 5 "steady" generations. .limit(bySteadyFitness(5)) // The evolution will stop after maximal 500 ms. .limit(byExecutionTime(Duration.ofMillis(500), Clock.systemUTC()) .collect(toBestPhenotype());
        Parameters:
        duration - the duration after the evolution stream will be truncated
        clock - the clock used for measure the execution time
        Returns:
        a predicate, which will truncate the evolution stream, based on the exceeded execution time
        Throws:
        NullPointerException - if one of the arguments is null
        Since:
        3.1
      • byExecutionTime

        public static Predicate<ObjectbyExecutionTime​(Duration duration)
        Return a predicate, which will truncate the evolution stream if the GA execution exceeds a given time duration. This predicate is (normally) used as safety net, for guaranteed stream truncation.
        final Phenotype<DoubleGene, Double> result = engine.stream() // Truncate the evolution stream after 5 "steady" generations. .limit(bySteadyFitness(5)) // The evolution will stop after maximal 500 ms. .limit(byExecutionTime(Duration.ofMillis(500)) .collect(toBestPhenotype());
        Parameters:
        duration - the duration after the evolution stream will be truncated
        Returns:
        a predicate, which will truncate the evolution stream, based on the exceeded execution time
        Throws:
        NullPointerException - if the evolution duration is null
        Since:
        3.1
      • byFitnessThreshold

        public static <C extends Comparable<? super C>> Predicate<EvolutionResult<?,​C>> byFitnessThreshold​(C threshold)
        Return a predicate, which will truncated the evolution stream if the best fitness of the current population becomes less than the specified threshold and the objective is set to minimize the fitness. This predicate also stops the evolution if the best fitness in the current population becomes greater than the user-specified fitness threshold when the objective is to maximize the fitness.
        final Phenotype<DoubleGene, Double> result = engine.stream() // Truncate the evolution stream if the best fitness is higher than // the given threshold of '2.3'. .limit(byFitnessThreshold(2.3)) // The evolution will stop after maximal 250 generations; guarantees // the termination (truncation) of the evolution stream. .limit(250) .collect(toBestPhenotype());
        Type Parameters:
        C - the fitness type
        Parameters:
        threshold - the desired threshold
        Returns:
        the predicate which truncates the evolution stream based on the given threshold.
        Throws:
        NullPointerException - if the given threshold is null.
        Since:
        3.1
      • byFitnessConvergence

        public static <N extends Number & Comparable<? super N>> Predicate<EvolutionResult<?,​N>> byFitnessConvergence​(int shortFilterSize,
                                                                                                                            int longFilterSize,
                                                                                                                            BiPredicate<DoubleMoments,​DoubleMoments> proceed)
        Return a predicate, which will truncate the evolution stream if the fitness is converging. Two filters of different lengths are used to smooth the best fitness across the generations.
        final Phenotype<DoubleGene, Double> result = engine.stream() .limit(byFitnessConvergence(5, 15, (s, l) -> { final double div = max(abs(s.getMean()), abs(l.getMean())); final eps = abs(s.getMean() - l.getMean())/(div <= 10E-20 ? 1.0 : div); return eps >= 10E-5 })) .collect(toBestPhenotype());
        In the example above, the moving average of the short- and long filter is used for determining the fitness convergence.
        Type Parameters:
        N - the fitness type
        Parameters:
        shortFilterSize - the size of the short filter
        longFilterSize - the size of the long filter. The long filter size also determines the minimum number of generations of the evolution stream.
        proceed - the predicate which determines when the evolution stream is truncated. The first parameter of the predicate contains the double statistics of the short filter and the second parameter contains the statistics of the long filter
        Returns:
        a new fitness convergence strategy
        Throws:
        NullPointerException - if the proceed predicate is null
        Since:
        3.7
        API Note:
        The returned predicate maintains mutable state. Using it in a parallel evolution streams needs external synchronization of the test method.
      • byFitnessConvergence

        public static <N extends Number & Comparable<? super N>> Predicate<EvolutionResult<?,​N>> byFitnessConvergence​(int shortFilterSize,
                                                                                                                            int longFilterSize,
                                                                                                                            double epsilon)
        Return a predicate, which will truncate the evolution stream if the fitness is converging. Two filters of different lengths are used to smooth the best fitness across the generations. When the smoothed best fitness from the long filter is less than a user-specified percentage away from the smoothed best fitness from the short filter, the fitness is deemed as converged and the evolution terminates.
        final Phenotype<DoubleGene, Double> result = engine.stream() .limit(byFitnessConvergence(5, 15, 10E-4)) .collect(toBestPhenotype());
        In the given example, the evolution stream stops, if the difference of the mean values of the long and short filter is less than 1%. The short filter calculates the mean of the best fitness values of the last 5 generations. The long filter uses the best fitness values of the last 15 generations.
        Type Parameters:
        N - the fitness type
        Parameters:
        shortFilterSize - the size of the short filter
        longFilterSize - the size of the long filter. The long filter size also determines the minimum number of generations of the evolution stream.
        epsilon - the maximal relative distance of the mean value between the short and the long filter. The epsilon must within the range of [0..1].
        Returns:
        a new fitness convergence strategy
        Throws:
        IllegalArgumentException - if shortFilterSize < 1 || longFilterSize < 2 || shortFilterSize >= longFilterSize
        IllegalArgumentException - if epsilon is not in the range of [0..1]
        Since:
        3.7
        API Note:
        The returned predicate maintains mutable state. Using it in a parallel evolution streams needs external synchronization of the test method.
      • byPopulationConvergence

        public static <N extends Number & Comparable<? super N>> Predicate<EvolutionResult<?,​N>> byPopulationConvergence​(BiPredicate<Double,​DoubleMoments> proceed)
        A termination method that stops the evolution when the population is deemed as converged. The population is deemed as converged when the average fitness across the current population is less than a user-specified percentage away from the best fitness of the current population. This method takes a predicate with the best fitness and the population fitness moments and determine whether to proceed or not.
        Type Parameters:
        N - the fitness type
        Parameters:
        proceed - the predicate which determines when the evolution stream is truncated. The first parameter of the predicate contains the best fitness of the population and the second parameter contains the statistics of population fitness values
        Returns:
        a new fitness convergence strategy
        Throws:
        NullPointerException - if the proceed predicate is null
        Since:
        3.9
      • byPopulationConvergence

        public static <N extends Number & Comparable<? super N>> Predicate<EvolutionResult<?,​N>> byPopulationConvergence​(double epsilon)
        A termination method that stops the evolution when the population is deemed as converged. The population is deemed as converged when the average fitness across the current population is less than a user-specified percentage away from the best fitness of the current population.
        Type Parameters:
        N - the fitness type
        Parameters:
        epsilon - the maximal relative distance of the best fitness value of the population and the mean value of the population fitness values.
        Returns:
        a new fitness convergence strategy
        Throws:
        IllegalArgumentException - if epsilon is not in the range of [0..1]
        Since:
        3.9
      • byGeneConvergence

        public static <G extends NumericGene<?,​G>> Predicate<EvolutionResult<G,​?>> byGeneConvergence​(Predicate<DoubleMoments> geneConvergence,
                                                                                                                 double convergedGeneRate)
        A termination method that stops the evolution when a user-specified percentage of the genes (convergedGeneRage) that make up a Genotype are deemed as converged. A gene is deemed as converged, if the geneConvergence Predicate<DoubleMoments> for this gene returns true.
        Type Parameters:
        G - the gene type
        Parameters:
        geneConvergence - predicate which defines when a gene is deemed as converged, by using the statistics of this gene over all genotypes of the population
        convergedGeneRate - the percentage of genes which must be converged for truncating the evolution stream
        Returns:
        a new gene convergence predicate
        Throws:
        NullPointerException - if the given gene convergence predicate is null
        IllegalArgumentException - if the convergedGeneRate is not within the range [0, 1]
        Since:
        4.0
        See Also:
        byGeneConvergence(double, double)
      • byGeneConvergence

        public static <G extends NumericGene<?,​G>> Predicate<EvolutionResult<G,​?>> byGeneConvergence​(double convergenceRate,
                                                                                                                 double convergedGeneRate)
        A termination method that stops the evolution when a user-specified percentage of the genes (convergedGeneRage) that make up a Genotype are deemed as converged. A gene is deemed as converged when the average value of that gene across all of the genotypes in the current population is less than a user-specified percentage (convergenceRate) away from the maximum gene value across the genotypes.

        This method is equivalent the following code snippet:

        final Predicate<EvolutionResult<DoubleGene, ?>> limit = byGeneConvergence( stat -> stat.getMax()*convergenceRate <= stat.getMean(), convergedGeneRate );
        Type Parameters:
        G - the gene type
        Parameters:
        convergenceRate - the relative distance of the average gene value to its maximum value
        convergedGeneRate - the percentage of genes which must be converged for truncating the evolution stream
        Returns:
        a new gene convergence predicate
        Throws:
        IllegalArgumentException - if the convergedGeneRate or convergenceRate are not within the range [0, 1]
        Since:
        4.0
        See Also:
        byGeneConvergence(Predicate, double)