Class Limits

java.lang.Object
io.jenetics.engine.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 therefore recommended creating new instances for every stream and don't reuse it.
Since:
3.0
Version:
3.7
See Also:
  • Method Details

    • infinite

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

      public static Predicate<Object> byFixedGeneration(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<Object> byExecutionTime(Duration duration, InstantSource 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 a 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<Object> byExecutionTime(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 a 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 var 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 a 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 a 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

      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 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 to 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: