以N为模的随机数的均匀性

dra*_*oot 11 c random uniform

在[0,n)中选择随机数的一种常用方法是采用rand()模n的结果:rand() % n.但是,即使可用rand()实现返回的结果完全一致,当n = n均匀分配时,结果[0,n]数的均匀性是否应该存在问题?例如假设为2,n为2.然后,在3个可能的输出中:0,1和2,当我们使用模n时,我们分别得到0,1和0 .因此输出将根本不是均匀的.RAND_MAX + 1RAND_MAXrand()

这在实践中是一个真正的问题吗?选择[0,n]中的随机数是一种更好的方法,从rand()输出中均匀推导出来,最好没有任何浮点运算?

Kev*_*vin 7

你是对的,rand() % N不是精确均匀分布的.确切地说,重要的是多少取决于你想要的数字范围和你想要的随机程度,但如果你想要足够的随机性,你甚至不关心它,你也不想使用它rand().获得一个真正的随机数生成器.

也就是说,要得到一个真正的随机分布,mod到下一个2的幂并进行采样,直到你得到一个你想要的范围(例如0-9,使用while(n = rand()%0x10 > 10);).

  • @Kevin:你判断rand()的任何特定实现,即在现代glibc中发现的那个吗? (2认同)
  • @ToddLehman 在我的系统(OSX 10.10)上,低位肯定不统一。在命令行上运行它以获得实时更新计数:http://pastebin.com/D5r7we3H (2认同)

sla*_*pon 6

这取决于:

  • RAND_MAX 的值
  • 你的 N 值

让我们假设您的 RAND_MAX 是 2^32。如果 N 相当小(假设为 2),则偏差为 1 / 2^31 —— 或者太小而无法注意到。

但是如果 N 大一点,比如 2^20,那么偏差就是 1 / 2^12,或者大约是 4096 中的 1。大很多,但仍然很小。

  • 更差。Visual C++ 实现具有 RAND_MAX==0x7FFF,从 MS-DOS 上的 16 位 MSC 3.0 遗留下来。 (5认同)
  • 一些系统的“RAND_MAX”为“0xffff”,导致*大得多的偏差。 (3认同)
  • 相反,我认为答案是正确的。我们假设一个 PRNG 生成具有完美分布的数字。问题是,我们关心偏见吗?我试图提供一种量化偏差的方法,以便提问者可以自己确定他是否可以容忍。这都是非常语言非特定的。 (2认同)