说我有这个循环:
for (i=0; i < 100; i++)
{
srand(time(NULL));
printf("%d\n", rand());
}
如果我的机器速度相当快,它应该打印相同的数字100次。
但如果我这样修改它:
for (i=0; i < 100; i++)
{
srand(time(NULL) + rand());
printf("%d\n", rand());
}
然后它应该打印100个不同的数字。我的问题是,播种这样的随机数发生器有什么不对吗?效率怎么样?它会显着降低效率吗?
一个附带问题,如果我将main()
函数中的随机数发生器播种一次,对其他函数来说也足够了(即我不需要在使用rand()
的另一个函数中再次播种它)?
修改
我有可能需要以这种方式使用(除非当然有更好的方法,我不知道)。假设我有一个自定义库,其中包含使用rand()
的函数。但是这个函数不知道随机数是否是之前播种的。在这种情况下,我将srand(time(NULL) + rand())
放在该函数中,以确保随机化器即使之前没有播种也会播种。
示例:
int main()
{
int i;
srand(time(NULL)); // Seeded here, but the print_rand() function does not know it
for (i=0; i < 100; i++)
{
print_rand();
}
return(0);
}
// Pretend this function is in a library
void print_rand()
{
srand(time(NULL) + rand()); // No guarantee if seeding was done before, so doing it here
printf("%d\n", rand());
}
编辑2
我刚用1000000循环测试了它。播种一次0.024s
,播种每次4.972s
。所以我想如果它是一个大循环,它确实会显着降低性能。
答案 0 :(得分:2)
PRNG不止一次播种通常是错误的。它确实没有增加PRNG的安全性,也没有使它更快(可能更慢!)
PRNG只需要播种一次
是的,它足以在一个地方种下它。另一个故事是,如果你有同一个prng的多个实例,但事实并非如此,那就是C不是C ++而rand()是静态的。
关于你想用随机数据做什么......
答案 1 :(得分:2)
不要这样做。
播种一次。 如果反复使用, srand(time(NULL) + rand());
会引入统计偏差。直观地说,这是由于两个影响:(i)srand(rand())
将有效地省略所有其他数字,这将增加方差;(ii)srand(time(NULL))
将引入一个额外的加性常数,这将导致模运算符在要比应该更频繁地调用生成器。您甚至可能会损害生成器的周期性。
为什么不试试呢?我希望平均值将大致正确,但我认为方差和更高的时刻将会消失。
答案 2 :(得分:1)
您似乎想要改进rand
的输出。
srand
一次。rand
,在大多数系统上生成的数字都可以轻松预测。 rand
仅适用于非常简单的情况,其中的某些内容对人类来说是随意的。就像一个简单的游戏。在那些情况下,调用srand
一次就足够了。
如果您实际上想要生成随机(定义为“不可预测”)数字,则不应使用rand
或random
。然后,您需要对您的操作系统进行一些研究,并查看生成随机数的适当库。
回答这个问题。它不应该伤害这样做。也许你会让可预测的数字更加可预测。也许有偏见的数字会略微偏颇。人类(唯一可以被rand
愚弄的实体)仍然可能看到它们足够随机。另一方面,你这样做没有任何好处,为什么要浪费时间?