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.

Set up 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 = RandomRegistry
            .with(factory.create(123))
            .call(() ->
                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:
9.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. Each thread will get the same random generator, when getting one with the random() method.
      Parameters:
      random - the new RandomGenerator for the global scope
      Throws:
      NullPointerException - if the random object is null
      See Also:
      Implementation Requirements:
      The given random generator must be thread safe.
    • random

      public static void random(RandomGeneratorFactory<?> factory)
      Set a new RandomGeneratorFactory for the global scope. When setting a random generator factory instead of the generator directly, every thread gets its own generator. It is not necessary, that the created random generators must be thread-safe.
      Parameters:
      factory - the random generator factory
      Throws:
      NullPointerException - if the factory object is null.
    • random

      public static void random(Supplier<? extends RandomGenerator> supplier)
      Set a new Supplier of RandomGenerator for the global scope. When setting a random generator supplier instead of the generator directly, every thread gets its own generator, as returned by the supplier. It is not necessary, that the created random generators must be thread-safe.
      Parameters:
      supplier - the random generator supplier
      Throws:
      NullPointerException - if the supplier object is null.
      See Also:
    • reset

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

      public static RandomRegistry.Runner with(RandomGenerator random)
      Return a scoped runner with the given random generator bound to the RandomRegistry.
      Parameters:
      random - the random generator to bind
      Returns:
      a new scoped runner object
    • with

      Return a scoped runner with the given random generator factory bound to the RandomRegistry. Every thread spawned in the returned runner will use a new random generator, created by the factory.
      Parameters:
      factory - the random generator factory used for creating the desired random generator. Every thread gets its own random generator when calling random().
      Returns:
      a new scoped runner object
    • with

      public static RandomRegistry.Runner with(Supplier<? extends RandomGenerator> supplier)
      Return a scoped runner with the given random generator supplier bound to the RandomRegistry. Every thread spawned in the returned runner will use a new random generator, returned by the supplier.
      Parameters:
      supplier - the random generator supplier used for creating the desired random generator. Every thread gets its own random generator when calling random().
      Returns:
      a new scoped runner object