【问题标题】:using rand to generate a random numbers使用 rand 生成随机数
【发布时间】:2010-07-01 16:13:57
【问题描述】:

gcc 4.4.4 c89

我正在使用下面的代码。但是,我一直收到相同的号码:

    size_t i = 0;

    for(i = 0; i < 3; i++) {
        /* Initialize random number */
        srand((unsigned int)time(NULL));
        /* Added random number (simulate seconds) */
        add((rand() % 30) + 1);
    }

我希望返回 0 到 30。但是,我上次运行这个时,我得到了 17 次 3 次。

非常感谢,

【问题讨论】:

  • 注意:0 到 30 实际上是 31 个唯一值。您的代码将始终返回 1 到 30。如果您真的需要 0-30,您应该 %31(没有“+ 1”)。 Off by 1 错误很容易被忽略。 (在这种情况下显然是 9 年)。

标签: c


【解决方案1】:

您正在循环播种(由于循环执行速度有多快而具有相同的值),这会导致每次生成的随机数都相同。

你需要将你的种子函数移出循环:

/* Initialize random number */
srand((unsigned int)time(NULL));

for(i = 0; i < 3; i++) {
    /* Added random number (simulate seconds) */
    add((rand() % 30) + 1);
}

【讨论】:

    【解决方案2】:

    您只需在程序开始时调用 srand 一次。

    srand 使用时间(以秒为单位)初始化伪随机数生成器。如果你用一个特定的数字初始化它,你总是会得到相同的数字序列。这就是为什么您通常希望在开始时使用时间对其进行初始化(这样每次运行程序时种子都不同),然后只使用rand 来生成看似随机的数字。

    在您的情况下,每次迭代的时间不会改变,因为它的分辨率仅为 1 秒,因此您总是得到伪随机序列的第一个数字,这始终是相同的。

    【讨论】:

    • need to call srand just once, at the beginning of your program. 是真的吗?我的意思是我认为,如果需要,他们应该在需要更改随机数生成器的种子并获得不同的随机数序列时调用srand
    • 这段特定的代码是这样的;)。当然,您可以在出于某种原因想要更改种子时调用它;这不是被禁止的。
    • @skwllsp 并且通常每个请求只有一次!
    • @skwllsp 如何通过设置不同的种子比使用旧种子生成的序列的子序列更好地实现不同的序列?
    • @Michał Trybus 我不是在谈论更好的序列。重点是我认为once at the beginning of the program 是不正确的。
    【解决方案3】:

    您只需在循环前执行一次srand((unsigned int)time(NULL))

    【讨论】:

      【解决方案4】:

      完全有可能3乘以17仍然是完全随机的。

      当使用 1-30 的范围和三个选择时,有大约十分之一的机会得到两个相同的数字。 (这是由于birthday problem

      现在,使用相同的范围,获得三个相同结果的概率仍然是 900 分之一。

      您可能想了解更多关于 analysis page of random.org 的背景信息

      【讨论】:

      • 在这种情况下(即使不是编码错误)连续获得两个 17 与生日问题无关。假设每个随机数是独立的,计算连续获得两个 17 的概率为 1/30*1/30 或 1/900。对于三个,它将是 1/30*1/30*1/30,或 1/27000。
      • 但您忘记了获得三个相同数字有 30 种不同的可能性。 1/27000 * 30 = 1/900
      • 现在,对于两个相同的...实际上有 XYX、XXY 和 YXY 三个组合,每个组合有 30 个可能性。 1/900 * 30 = 1/30 * 3 = 3/30 = 1/10
      • 记住,365个选项的可能性,只有23个拉,重复的机会是50%!
      【解决方案5】:

      伪随机数生成器的种子只能在循环外调用一次。用时间做种子是好事。 但是仍然有可能获得相同的随机数。

      【讨论】:

        【解决方案6】:

        我更建议使用 gettimeofday() 系统调用来检索要用于提供 srand() 的种子。

        类似

        struct timeval tv; ... gettimeofday(&tv, NULL); srand(tv.tv_usec); ...

        这种方法可以在您的伪数生成代码中添加更多熵。 恕我直言,当然

        捋捋

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-21
          • 1970-01-01
          • 1970-01-01
          • 2015-09-29
          • 1970-01-01
          • 1970-01-01
          • 2015-02-27
          • 1970-01-01
          相关资源
          最近更新 更多