C中重复且可预测的RNG值

C中重复且可预测的RNG值,c,C,我试图在C语言中生成10000个随机数,但在使用伪RNG获得随机甚至随机结果时遇到困难。我用了一种我认为应该创造一致性的方法来使用模,它确实做到了,但是当在另一个调用RNG(4)的函数的循环中运行时,结果相当于0,0,0,0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3等 任何使其接近1,3,2,0,2,3,1,0,0,3,2,0,1等的方法都将不胜感激 谢谢大家! 编辑:谢谢大家的回复!将播种移动到调用RNG的函数的开头,现在一切都很好 不要每次要生成号码时都调用

我试图在C语言中生成10000个随机数,但在使用伪RNG获得随机甚至随机结果时遇到困难。我用了一种我认为应该创造一致性的方法来使用模,它确实做到了,但是当在另一个调用RNG(4)的函数的循环中运行时,结果相当于0,0,0,0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3等

任何使其接近1,3,2,0,2,3,1,0,0,3,2,0,1等的方法都将不胜感激

谢谢大家!


编辑:谢谢大家的回复!将播种移动到调用RNG的函数的开头,现在一切都很好

不要每次要生成号码时都调用
srand
srand
初始化伪随机数生成器,并打算在程序开始时或要重置生成器时仅调用一次。通过每次重置它,您将强制
rand
在时钟上每秒钟内每次调用它时生成相同的号码

不要使用
x%n
将数字减少到所需的范围。众所周知,
rand
的旧实现糟糕透顶,并且具有低位模式。相反,使用
x/((RAND\u MAX+1u)/n)

代码
int range=RAND\u MAX-(RAND\u MAX%n)有缺陷。假设
n
为4,
RAND_MAX
为7,表示
RAND
返回0到7。此代码将
range
设置为4,然后将
设置为while(x>range)x=rand()丢弃5、6和7,而保留4。这里有两个错误:代码保留了5个值0、1、2、3和4,这与所需的4范围不匹配(不是4的倍数),并且不必要地丢弃了值。如果我们保持4、5、6和7,我们会有一场比赛。您可以使用:

unsigned range = (RAND_MAX + 1u) - ((RAND_MAX + 1u) % n);
以及:


如果你使用C++,切换到使用。如果您使用的是C,请在实现中检查

rand
的质量,或者切换到另一个生成器,例如POSIX
srandom
random

不要在每次生成数字时调用
srand
srand
初始化伪随机数生成器,并打算在程序开始时或要重置生成器时仅调用一次。通过每次重置它,您将强制
rand
在时钟上每秒钟内每次调用它时生成相同的号码

不要使用
x%n
将数字减少到所需的范围。众所周知,
rand
的旧实现糟糕透顶,并且具有低位模式。相反,使用
x/((RAND\u MAX+1u)/n)

代码
int range=RAND\u MAX-(RAND\u MAX%n)有缺陷。假设
n
为4,
RAND_MAX
为7,表示
RAND
返回0到7。此代码将
range
设置为4,然后将
设置为while(x>range)x=rand()丢弃5、6和7,而保留4。这里有两个错误:代码保留了5个值0、1、2、3和4,这与所需的4范围不匹配(不是4的倍数),并且不必要地丢弃了值。如果我们保持4、5、6和7,我们会有一场比赛。您可以使用:

unsigned range = (RAND_MAX + 1u) - ((RAND_MAX + 1u) % n);
以及:


如果你使用C++,切换到使用。如果您使用的是C,请在实现中检查

rand
的质量,或者切换到另一个生成器,如POSIX
srandom
random

如其他地方所述,对重复数字的修复是将调用移动到
srand(时间(NULL))
在该函数之外,每个程序在开始时只调用一次

至于为什么会出现重复的数字:该函数每秒被调用几次。每次函数在给定的秒内执行时,
time(NULL)
返回相同的数字,该代码使用该数字为随机数生成器设定种子


从特定种子生成的随机数序列总是相同的。此代码从该序列中获取第一个数字,该数字在1秒内始终不变,直到
time(NULL)
返回一个新值。

如其他地方所述,重复数字的修复方法是将调用移到该函数之外的
srand(time(NULL))
,并在每个程序开始时仅调用一次

至于为什么会出现重复的数字:该函数每秒被调用几次。每次函数在给定的秒内执行时,
time(NULL)
返回相同的数字,该代码使用该数字为随机数生成器设定种子


从特定种子生成的随机数序列总是相同的。此代码从该序列中获取第一个数字,该数字在1秒内始终不变,直到
time(NULL)
返回一个新值。

1。选择是使用
C
还是
C++
。2.如果您选择了
C++
,我知道每次调用
RNG
,您都在使用
srand
重置种子。停止在每个循环中重置
srand()
。如果您想要一个可重复的伪随机数序列,请使用常量调用
srand()
(一次),而不是使用
时间(NULL)
,它的设计目的是在每次运行时为您提供一个新序列。或者根本不调用所有的
srand()
,这相当于调用
srand(1)
.1。选择是使用
C
还是
C++
。2.如果您选择了
C++
,我知道每次调用
RNG
,您都在使用
srand
重置种子。停止在每个循环中重置
srand()
。如果您想要一个可重复的伪随机数序列,请使用常量调用
srand()
(一次),而不是使用
时间(NULL)
,它的设计目的是在每次运行时为您提供一个新序列。或者根本不使用所有的
srand()
,这是等效的
while (x >= range) x = rand();