具有不同种子的Java随机实例是否真的产生不同的序列,或者它们是否在相同序列的不同位置开始?

时间:2016-08-09 23:46:35

标签: java random

想象一下,使用不同的种子rA和rB实例化两个Random。看看rA生成的第一个整数是什么。然后在rB上调用nextInt(),直到得到相同的整数。

groovy:000> rA = new Random()
===> java.util.Random@463b4ac8
groovy:000> rB = new Random(1)
===> java.util.Random@5644dc81
groovy:000> rA_0 = rA.nextInt()
===> -1458003306
groovy:000> rB_0 = rB.nextInt()
===> -1155869325
groovy:000> for (int rB_n = rB.nextInt(); rB_n != rA_0; rB_n = rB.nextInt());
===> null

可能这两个实例现在是"同步了,"可以这么说,他们将无限期地生成相同的整数序列?

groovy:000> rA.nextInt()
===> 1701960179
groovy:000> rB.nextInt()
===> 1760857409
groovy:000> for (int rB_n = rB.nextInt(); rB_n != rA_0; rB_n = rB.nextInt());
===> null
groovy:000> rB.nextInt()
===> 614305687

所显示的有限实验未发现序列的这种碰撞,但很难知道是否可以找到这种碰撞。

要重新解释这个问题,我们是否使用一个非常长的序列,种子确定我们开始的序列在哪里,或者可以依赖于具有不同种子的随机实例来实际产生完全不同的数字序列?或者更糟糕的是,一些种子共享序列? (或者它取决于Sally在哪个海岸上出售海贝壳?)

1 个答案:

答案 0 :(得分:2)

Java Random.next()(所有公共nextX()方法的基础)在合同上有义务遵循以下LCG等式:

(x * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)

因此,给定当前状态(x),完全确定下一个状态。

所以假设这是一个&#34;全周期&#34; LCG(即它迭代所有可能的值),然后必须是rB最终达到rA的起始状态的情况。此时,其输出序列将与rA的输出序列匹配。