【问题标题】:Generating Uniformly Distributed Pseudo-random Numbers in C++在 C++ 中生成均匀分布的伪随机数
【发布时间】:2013-08-22 23:47:37
【问题描述】:

cplusplus.com reference 中指出,在尝试生成随机数时使用模运算符会使较小的数字更有可能:

random_var = rand() % 100 + 1; //this will generate numbers between 1-100

为什么较低的数字更有可能?如果是,我们为什么不使用下面的代码:

random_var = rand()/(RAND_MAX/100) + 1; //also will generate those, more uniform I guess

【问题讨论】:

  • 我稍微解释了一下in this answer
  • 最简单的替换就是使用<random>

标签: c++ random


【解决方案1】:

假设 RAND_MAX 是 150。(显然实际上不是。)我们想要 0-99 之间的数字。然后我们做rand() % 100。很酷。

问题是,如果 RAND() 返回一个大于 100 的数字怎么办?让我们选择 102。102 % 100 = 22 % 100 = 2。所以有一个2/150 的机会,我们会用给定的算法得到一个 2。但是50以上的数字呢?只有1/150 机会我们会得到它。 RAND_MAX 越高,这个问题就越小,但它仍然是一个问题。

请注意,如果 RAND_MAX 可以被您想要“调制”它的数字整除,那么所有数字的可能性都相同。即如果 RAND_MAX 是 200 而不是 150。希望这会有所帮助!

编辑:实际数学。

RAND_MAX 保证至少为 32767。如果我们想要一个 0-99 的范围,我们可以使用RAND() % 100。然后,0 到 67 之间的数字将全部出现 328 次,而 68-99 则每个仅出现 327 次。前 68 个数字的概率为 1.0010071%,其余数字的概率仅为 0.9979553%。我们希望他们都是 1%!通常不是主要问题,但根据用例,可能会出现一些奇怪的行为。

【讨论】:

  • 谢谢,我现在明白了,如果我们在第二种情况下对 rand()/(RAND_MAX/100) 使用浮点除法会怎样。这样能解决问题吗?
  • 我没有运行模拟或完成数学运算,但我很确定第二种方法是正确的。我认为由于浮动的性质,它可能会有一些奇怪的行为,并且会慢一点,但看起来它会是一个更平坦的分布。如果我错了,请有人纠正我!
  • (显然,在第二种方法中,您需要一个浮点除法的地板。)
猜你喜欢
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
  • 2021-12-28
  • 2020-09-07
  • 2015-06-24
  • 2013-12-09
  • 2013-05-10
  • 2015-08-14
相关资源
最近更新 更多