java17学习笔记-增强型伪随机数生成器
JEP 356: Enhanced Pseudo-Random Number Generators
为伪随机数提供新的接口类型和生成器 (PRNG),包括可跳转的 PRNG 和附加类 可拆分的 PRNG 算法 (LXM)。
提供了一个新的接口RandomGenerator,它提供了一个 适用于所有现有和新 PRNG 的统一 API。 RandomGenerator提供ints
, longs
, doubles
, nextBoolean
, nextInt
, nextLong
, nextDouble
, and nextFloat
的方法及其所有当前参数变体。
四个新的专用 RandomGenerator 接口:
SplittableRandomGenerator extends RandomGenerator 提供了split 和splits两个方法
。
可分割性允许用户从现有的RandomGenerator中生成一个新的RandomGenerator,该RandomGeneraker通常会产生统计上独立的结果。
创建SplittableGenerator类型的Random
var splittableRandom = new SplittableRandom(); var l32X64MixRandom = RandomGeneratorFactory.of("L32X64MixRandom");System.out.println(l32X64MixRandom.create().nextBoolean());var splittableGenerator = andomGenerator.SplittableGenerator.of("L32X64MixRandom");System.out.println(splittableGenerator.nextBoolean());
case "SplittableRandom" -> new SplittableRandom();
case "L32X64MixRandom" -> new L32X64MixRandom();
case "L64X128MixRandom" -> new L64X128MixRandom();
case "L64X128StarStarRandom" -> new L64X128StarStarRandom();
case "L64X256MixRandom" -> new L64X256MixRandom();
case "L64X1024MixRandom" -> new L64X1024MixRandom();
case "L128X128MixRandom" -> new L128X128MixRandom();
case "L128X256MixRandom" -> new L128X256MixRandom();
case "L128X1024MixRandom" -> new L128X1024MixRandom();
可选参数和官方文档给出的不一样,这里需要注意一下
split 和splits两个方法
var splittableRandom = new SplittableRandom();splittableRandom.splits(3).forEach(item->{System.out.println(item.nextBoolean());});SplittableRandom split = splittableRandom.split();System.out.println(split.nextBoolean());
JumpableRandomGenerator extends RandomGenerator 提供了jump和jumps两个方法
跳跃性允许用户在中等数量的平局中向前跳跃。
作者一开始认为跳跃是跳过下一次随机数,会影响最终概率,但是发现并影响结果。
网上也看了很多博主的文章都是清一色的RandomGeneratorFactory.jumpable(),也不知道怎么来的,反正我是找不到jumpable()方法。
var splittableGenerator = RandomGenerator.JumpableGenerator.of("Xoshiro256PlusPlus");splittableGenerator.jumps(4).forEach(item->{System.out.println(item.nextBoolean());});RandomGeneratorFactory<RandomGenerator.JumpableGenerator> factory = RandomGeneratorFactory.of("Xoshiro256PlusPlus");RandomGenerator.JumpableGenerator jumpable = factory.create();int trueCount = 0, falseCount = 0, totalCount = 10000;for (int i = 0; i < totalCount; i++) {double d = jumpable.nextDouble(100.00);if (d > 60.00) {trueCount++;} else {falseCount++;jumpable.jump();jumpable.jump();}}System.out.println(trueCount);System.out.println(falseCount);System.out.println(trueCount * 1.00 / totalCount);
case "Xoroshiro128PlusPlus" -> new Xoroshiro128PlusPlus(); case "Xoshiro256PlusPlus" -> new Xoshiro256PlusPlus();
LeapableRandomGenerator extends RandomGenerator 还提供方法命名为leap和jumps。Leapability允许用户跳过大量的绘图。
目前还没有找到可以使用的创建方法只能new RandomGenerator.LeapableGenerator(),然后实现接口未实现的方法来创建
ArbitrarilyJumpableRandomGenerat extends LeapableRandomGenerator提供了还提供了jump和jumps的其他变体,允许指定任意跳跃距离
同上
最实用的部分是新加了线程安全的随机数ThreadLocalRandom,使用如下
ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();System.out.println(threadLocalRandom.nextBoolean());