【问题标题】:How unique is rand() in C?rand() 在 C 中有多独特?
【发布时间】:2012-09-06 21:15:59
【问题描述】:

我将rand() 用于需要唯一值的 6 位字段。我做得对吗?

概率是多少,rand() 可以在连续或频繁调用时给我类似的值?

当我使用 rand() 时,它是独一无二的。但是,当我打电话给srand(time(NULL))srand(clock()) 时,返回了相同的号码。似乎,它对我来说是相反的。还是这样?

【问题讨论】:

  • 您应该只调用一次srand。这就是伪随机数序列的种子。
  • RAND_MAX 需要有 15 个“活动位”。在最坏的可能实现中,只有 32K 个不同的值。好消息:现在大多数实现都更好了。
  • @wildplasser 尽管rand()/srand() 按照您的comment 执行是合理的,但不幸的是,C 没有指定“只有(至少)32K 个不同的值”,只有值的范围 - 他们需要并非全部发生。

标签: c random unique uniqueidentifier


【解决方案1】:

rand() 返回介于 0 和 RAND_MAX 之间的值。由于它是离散的均匀分布,因此重复数字的概率为 1/(RAND_MAX+1),因此无法保证唯一性。

srand(seed) 初始化您的随机数生成器,以便每次从rand() 获得的数字序列都是相同的,因为您每次都使用seed 对其进行初始化。

在您的示例中,seed = time(NULL) 是从 1970 年 1 月 1 日起经过的秒数,因此确保了不同的种子,因此每次调用 srand(time(NULL)) 时都有不同的随机数序列(假设它不是在同一秒)。

【讨论】:

    【解决方案2】:

    随机数是随机的,而不是唯一的。就像掷骰子的情况一样,您可以连续掷出几个六,您的rand 有时可以(并且应该)给您相同的数字。

    为了确保数字是唯一的,请构建一个集合,在其中注册您已经添加的每个数字。当一个随机数出现不止一次时,扔掉第二个,然后去寻找下一个。

    【讨论】:

      【解决方案3】:

      正如其他人指出的那样,不能保证唯一性。但是,您可能会看到重复的数字,因为您错误地使用了 srand() 和 rand()。

      srand() 用于播种随机数生成器。这意味着在调用 srand 之后对 rand() 的一系列调用将产生一系列特定的值。如果您使用相同的值调用 srand(),则 rand() 将产生相同系列的值(对于给定的实现,不同实现之间无法保证)

      int main() {
          srand(100);
          for(int i = 0; i<5; ++i)
              printf("%d\n",rand());
      
          printf("\nreset\n\n");
      
          srand(100);
          for(int i = 0; i<5; ++i)
              printf("%d\n",rand());
      
      }
      

      对我来说,这会产生:

      365
      1216
      5415
      16704
      24504
      
      reset
      
      365
      1216
      5415
      16704
      24504
      

      time() 和 clock() 返回时间,但如果你调用它们的速度足够快,那么返回的值将是相同的,所以你会从 rand() 中得到相同的一系列值。

      此外,rand() 通常不是一个很好的随机数生成器,使用它通常意味着您必须将一系列数字转换为您实际需要的分布。你应该找到一个不同的随机源,要么学习正确的方法来产生你想要的分布,要么使用一个可以为你做的库。 (例如,产生 0 到 N 之间的“随机”数字的一种常用方法是 rand() % N,但这并不是最好的方法。

      C++ 在&lt;random&gt; 中提供了一个更好的随机数库。它提供了不同的 PRNG 算法,例如 linear_congruential、mersenne_twister,甚至可能提供加密安全的 RNG(取决于实现)。它还提供了用于生成各种分布的对象,例如应避免rand() % N 中的错误的uniform_int_distribution。

      【讨论】:

        【解决方案4】:

        rand() 在连续或频繁调用时可以给我类似的值的几率是多少?

        rand 的算法在 C 中未指定。rand 返回的数字的随机性质量也是如此。

        【讨论】:

          猜你喜欢
          • 2011-05-21
          • 2014-01-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多