3

我正在编写蒙特卡罗模拟,并且需要大量随机位来生成均匀分布在 {1,2,...,N} 上的整数,其中 N<40。使用 C 函数的问题在于,使用标准技术rand我会浪费很多非常好的位。rand % N生成整数的更好方法是什么?

我不需要加密安全的随机数,但我不希望它们扭曲我的结果。另外,我不考虑从 random.org 下载一批位作为解决方案。

4

3 回答 3

2

rand % N不工作;它会扭曲您的结果,除非RAND_MAX + 1N.

正确的方法是找出N小于的最大倍数RAND_MAX,然后生成随机数,直到小于该值。只有这样你才应该做模运算。这为您提供了 50% 的最坏情况拒绝率。

于 2012-05-21T18:51:27.610 回答
1

除了奥利的回答:

如果您非常关心位,那么您可以手动管理一个位队列,只检索下一个数字所需的数量(即上(log2(n)))。

但你应该确保你的发电机足够好。简单的线性同余(sp?)生成器在较高位上比较低位更好(请参阅注释),因此您当前的模块化除法方法在那里更有意义。

numeric recipes 在这方面有一个非常好的部分,并且非常容易阅读(不确定它是否提到了保存位,但作为一般参考)。

如果您不确定是否需要更新,我现在不会担心这个(除非您从了解您的特定背景的人那里得到更好的建议)。

于 2012-05-21T18:57:01.743 回答
0

以 base40表示rand,并将数字作为数字。删除任何不完整的数字,也就是说,如果第一个数字没有完整范围 [0..39],则删除第一个数字,如果第一个数字取其最高可能值,则删除整个随机数(例如,如果 RAND_MAX 是 base40 是21 23 05 06,删除所有具有最高基数 40 位 21) 的数字。

于 2012-05-21T19:02:06.420 回答