如果以这种方式完成,可以多次播种随机数发生器吗?

时间:2015-08-25 12:15:27

标签: c loops random random-seed

说我有这个循环:

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。所以我想如果它是一个大循环,它确实会显着降低性能。

3 个答案:

答案 0 :(得分:2)

PRNG不止一次播种通常是错误的。它确实没有增加PRNG的安全性,也没有使它更快(可能更慢!)

PRNG只需要播种一次

是的,它足以在一个地方种下它。另一个故事是,如果你有同一个prng的多个实例,但事实并非如此,那就是C不是C ++而rand()是静态的。

关于你想用随机数据做什么......

  • 加密东西?忘记使用rand(),srand()和time()
  • 随机化一些 游戏AI?可以没问题

答案 1 :(得分:2)

不要这样做。

播种一次。

如果反复使用,

srand(time(NULL) + rand());会引入统计偏差。直观地说,这是由于两个影响:(i)srand(rand())将有效地省略所有其他数字,这将增加方差;(ii)srand(time(NULL))将引入一个额外的加性常数,这将导致模运算符在要比应该更频繁地调用生成器。您甚至可能会损害生成器的周期性。

为什么不试试呢?我希望平均值将大致正确,但我认为方差和更高的时刻将会消失。

答案 2 :(得分:1)

您似乎想要改进rand的输出。

  1. 您的方法不会这样做。由于您的代码很可能已知,因此任何人都可以看到您所执行的操作,然后您的方法只相当于仅调用srand一次。
  2. 即使不知道您的代码,只要知道您使用rand,在大多数系统上生成的数字都可以轻松预测。
  3. rand仅适用于非常简单的情况,其中的某些内容对人类来说是随意的。就像一个简单的游戏。在那些情况下,调用srand一次就足够了。

    如果您实际上想要生成随机(定义为“不可预测”)数字,则不应使用randrandom。然后,您需要对您的操作系统进行一些研究,并查看生成随机数的适当库。

    回答这个问题。它不应该伤害这样做。也许你会让可预测的数字更加可预测。也许有偏见的数字会略微偏颇。人类(唯一可以被rand愚弄的实体)仍然可能看到它们足够随机。另一方面,你这样做没有任何好处,为什么要浪费时间?