具有不同种子的PRNG序列是否会在C中重叠

时间:2015-09-23 19:09:21

标签: c random

如果我在C中将种子设置为0,我将在调用rand()三次后获得此序列:

38, 7719, 21238, ...,

如果我将种子设置为1(srand(1)),我将得到另一个序列:

41, 18467, 6334, ...,

我知道这是非常不可能的,但srand(1)的序列会在srand(0)的序列中出现吗?我的意思是,使用srand(0)我会得到:

38, 7719, 21238, ..., ..., ..., 41, 18467, 6334, ...,?

谢谢!

3 个答案:

答案 0 :(得分:3)

对于rand,它没有由标准指定,但C标准中建议的示例实现肯定会产生重叠序列(实际上只有一个序列而种子只是起点)。

如果您需要更强大的属性,则需要选择合适的PRNG而不是仅使用rand。对于一个体面的PRNG来说,保证没有重叠的长度为N的子序列是非常困难的,并且对于合理大小的N,该陈述的简单证据甚至是真实性将表明非常 PRNG。但是很容易保证,对于具有足够大状态的良好PRNG,不同的种子不会产生完全相同的序列,只是从不同的点开始。

答案 1 :(得分:3)

虽然没有标准定义 - 你的问题的答案是肯定的,它取决于所使用的算法,通常是线性同余生成器(LCG)。 LCG被认为在交叉自相关方面很高。查看在您的平台中如何实现rand将让您更好地表征它。以下是Rand Implementation

的示例

答案 2 :(得分:2)

实际答案是它取决于生成器的实现,而标准中没有定义。即使对于线性同余生成器(LCG)也是如此,它通常用作rand的默认实现。

LCG是形式

的递归关系
state = (A * state + B) % M

表示适当的整数值常量ABM。设置种子会初始化state

ABM的某些选择将无法实现完整周期(相对于模数M),在这种情况下,LCG可以生成两个或更多不重叠的子序列。例如,对于A = 3B = 0M = 11,您会发现自己处于两个不重叠的子循环中的一个,具体取决于您的种子值。 用1播种将产生以下序列:

3,9,5,4,1,3,9,5,4,1,3,9...

用2播种将产生:

6,7,10,8,2,6,7,10,8,2,6,7...

系数的其他选择可以达到完整周期。在任何一种情况下,种子值对应于选择循环或子循环的入口点。

对于保持较大状态空间并折叠状态以生成每个报告值的其他类生成器,您可以重复单个值而不重复相同的序列,直到您枚举整个(不可见)状态空间。这就是Mersenne Twister等发电机如何实现周期长度,例如2 19937 -1。对于单个观察,不同(非常大)状态可以折叠到相同的32或64位数量,但是将导致为下一个值计算(和折叠)完全不同的状态,因此您将看到单个值的重复而不会看到重复一系列价值观。