Class RandomRegistry

java.lang.Object
io.jenetics.util.RandomRegistry

public final class RandomRegistry extends Object
This class holds the RandomGenerator engine used for the GA. The RandomRegistry is thread safe and is initialized with the RandomGeneratorFactory.getDefault() PRNG.

Setup the PRNG used for the evolution process

There are several ways on how to set the RandomGenerator used during the evolution process.

Using a RandomGeneratorFactory
The following example registers the L128X1024MixRandom random generator. By using a factory, each thread gets its own generator instance, which ensures thread-safety without the necessity of the created random generator to be thread-safe.

// This is the default setup.
RandomRegistry.random(RandomGeneratorFactory.getDefault());

// Using the "L128X1024MixRandom" random generator for the evolution.
RandomRegistry.random(RandomGeneratorFactory.of("L128X1024MixRandom"));

Using a RandomGenerator Supplier
If you have a random engine, which is not available as RandomGeneratorFactory, it is also possible to register a Supplier of the desired random generator. This method has the same thread-safety property as the method above.
RandomRegistry.random(() -> new MySpecialRandomGenerator());
Register a random generator supplier is also more flexible. It allows using the streaming and splitting capabilities of the random generators implemented in the Java library.
final Iterator<RandomGenerator> randoms =
    StreamableGenerator.of("L128X1024MixRandom")
        .rngs()
        .iterator();

RandomRegistry.random(randoms::next);

Using a RandomGenerator instance
It is also possible to set a single random generator instance for the whole evolution process. When using this setup, the used random generator must be thread safe.
RandomRegistry.random(new Random(123456));

The following code snippet shows an almost complete example of a typical random generator setup.

public class GA {
    public static void main(final String[] args) {
        // Initialize the registry with the factory of the PRGN.
        final var factory = RandomGeneratorFactory.of("L128X1024MixRandom");
        RandomRegistry.random(factory);

        final Engine<DoubleGene, Double> engine = ...;
        final EvolutionResult<DoubleGene, Double> result = engine.stream()
            .limit(100)
            .collect(toBestEvolutionResult());
    }
}

Setup of a local PRNG

You can temporarily (and locally) change the implementation of the PRNG. E.g., for initialize the engine stream with the same initial population.
public class GA {
    public static void main(final String[] args) {
        // Create a reproducible list of genotypes.
        final var factory = RandomGeneratorFactory.of("L128X1024MixRandom");
        final List<Genotype<DoubleGene>> genotypes =
            with(factory.create(123), r ->
                Genotype.of(DoubleChromosome.of(0, 10)).instances()
                    .limit(50)
                    .collect(toList())
            );

        final Engine<DoubleGene, Double> engine = ...;
        final EvolutionResult<DoubleGene, Double> result = engine
             // Initialize the evolution stream with the given genotypes.
            .stream(genotypes)
            .limit(100)
            .collect(toBestEvolutionResult());
    }
}

The default random generator used by Jenetics is L64X256MixRandom. Via the system property io.jenetics.util.defaultRandomGenerator, it is possible to use a different random generator.


 java -Dio.jenetics.util.defaultRandomGenerator=L64X1024MixRandom \
      -cp jenetics-@__version__@.jar:app.jar \
          com.foo.bar.MyJeneticsApp
 
Since:
1.0
Version:
8.0
See Also:
  • Method Details

    • random

      public static RandomGenerator random()
      Return the RandomGenerator of the current scope.
      Returns:
      the RandomGenerator of the current scope
    • random

      public static void random(RandomGenerator random)
      Set a new RandomGenerator for the global scope. The given RandomGenerator must be thread safe, which is the case for the Java Random class.
      Parameters:
      random - the new RandomGenerator for the global scope
      Throws:
      NullPointerException - if the random object is null
      See Also:
    • random

      public static <R extends RandomGenerator> void random(RandomGeneratorFactory<? extends R> factory)
      Set a new RandomGeneratorFactory for the global scope.
      Parameters:
      factory - the random generator factory
      Throws:
      NullPointerException - if the factory object is null.
    • random

      public static <R extends RandomGenerator> void random(Supplier<? extends R> supplier)
      Set a new Supplier of RandomGenerator for the global scope.
      Parameters:
      supplier - the random generator supplier
      Throws:
      NullPointerException - if the supplier object is null.
    • reset

      public static void reset()
      Set the random object to its default value.
    • using

      public static <R extends RandomGenerator> void using(R random, Consumer<? super R> consumer)
      Executes the consumer code using the given random generator.
      final MSeq<Integer> seq = ...;
      using(new Random(123), r -> {
          seq.shuffle();
      });
      
      The example above shuffles the given integer seq using the given Random(123) engine.
      Type Parameters:
      R - the type of the random engine
      Parameters:
      random - the PRNG used within the consumer
      consumer - the consumer which is executed with the scope of the given random engine.
      Throws:
      NullPointerException - if one of the arguments is null
      Since:
      3.0
    • using

      public static <R extends RandomGenerator> void using(RandomGeneratorFactory<? extends R> factory, Consumer<? super R> consumer)
      Executes the consumer code using the given random generator.
      final MSeq<Integer> seq = ...;
      using(RandomGeneratorFactory.getDefault(), r -> {
          seq.shuffle();
      });
      
      The example above shuffles the given integer seq using the given RandomGeneratorFactory.getDefault() factory.
      Type Parameters:
      R - the type of the random engine
      Parameters:
      factory - the random generator factory used within the consumer
      consumer - the consumer which is executed within the scope of the given random generator.
      Throws:
      NullPointerException - if one of the arguments is null
      Since:
      7.0
    • using

      public static <R extends RandomGenerator> void using(Supplier<? extends R> supplier, Consumer<? super R> consumer)
      Executes the consumer code using the given random generator supplier.
      final MSeq<Integer> seq = ...;
      using(() -> new MyRandomGenerator(), r -> seq.shuffle());
      
      Type Parameters:
      R - the type of the random engine
      Parameters:
      supplier - the random generator supplier used within the consumer
      consumer - the consumer which is executed within the scope of the given random generator.
      Throws:
      NullPointerException - if one of the arguments is null
      Since:
      7.0
    • with

      public static <R extends RandomGenerator, T> T with(R random, Function<? super R,? extends T> function)
      Opens a new scope with the given random generator and executes the given function within it. The following example shows how to create a reproducible list of genotypes:
      final List<Genotype<DoubleGene>> genotypes =
          with(new LCG64ShiftRandom(123), r ->
              Genotype.of(DoubleChromosome.of(0, 10)).instances()
                 .limit(50)
                 .collect(toList())
          );
      
      Type Parameters:
      R - the type of the random engine
      T - the function return type
      Parameters:
      random - the PRNG used for the opened scope
      function - the function to apply within the random scope
      Returns:
      the object returned by the given function
      Throws:
      NullPointerException - if one of the arguments is null
      Since:
      3.0
    • with

      public static <R extends RandomGenerator, T> T with(RandomGeneratorFactory<? extends R> factory, Function<? super R,? extends T> function)
      Opens a new scope with the given random generator factory and executes the given function within it.
      final List<Genotype<DoubleGene>> genotypes =
          with(RandomGeneratorFactory.getDefault(), random ->
              Genotype.of(DoubleChromosome.of(0, 10)).instances()
                 .limit(50)
                 .collect(toList())
          );
      
      Type Parameters:
      R - the type of the random engine
      T - the function return type
      Parameters:
      factory - the PRNG used for the opened scope
      function - the function to apply within the random scope
      Returns:
      the object returned by the given function
      Throws:
      NullPointerException - if one of the arguments is null.
      Since:
      3.0
    • with

      public static <R extends RandomGenerator, T> T with(Supplier<? extends R> supplier, Function<? super R,? extends T> function)
      Opens a new scope with the given random generator supplier and executes the given function within it.
      final List<Genotype<DoubleGene>> genotypes =
          with(() -> new MyRandomGenerator(), random ->
              Genotype.of(DoubleChromosome.of(0, 10)).instances()
                 .limit(50)
                 .collect(toList())
          );
      
      Type Parameters:
      R - the type of the random engine
      T - the function return type
      Parameters:
      supplier - the PRNG used for the opened scope
      function - the function to apply within the random scope
      Returns:
      the object returned by the given function
      Throws:
      NullPointerException - if one of the arguments is null.
      Since:
      3.0