我正在编写蒙特卡罗模拟,并且需要大量随机位来生成均匀分布在{1,2,...,N}上的整数,其中N <40。使用C rand
函数的问题是我使用标准rand % N
技术浪费了很多非常好的位。什么是生成整数的更好方法?
我不需要加密安全随机数,但我不希望它们扭曲我的结果。另外,我不考虑从random.org下载一批比特解决方案。
答案 0 :(得分:2)
rand % N
不起作用;除非RAND_MAX + 1
是N
的倍数,否则会导致您的结果出现偏差。
正确的方法是找出小于N
的{{1}}的最大倍数,然后生成随机数,直到它小于该值。只有这样你才能进行模运算。这使您的最差情况下的拒绝率为50%。
答案 1 :(得分:1)
除了oli的回答:
如果你非常关心比特,那么你可以手工管理一个比特队列,只检索下一个数字所需的数量(即上限(log2(n)))。
但是你应该确保你的发电机足够好。简单线性同余(sp?)生成器在较高位中比较低位(见注释)更好,因此您当前的模块化划分方法在那里更有意义。
数值配方在这一切方面有一个非常好的部分,并且非常容易阅读(不确定它提到了保存位,但作为一般参考)。
更新如果您不确定是否需要,我现在不担心这个问题(除非您从了解您特定背景的人那里得到更好的建议)。
答案 2 :(得分:0)
在base40中代表rand
并将数字作为数字。丢弃任何不完整的数字,即如果没有全范围[0..39]则丢弃第一个数字,如果第一个数字取其最高可能值,则丢弃整个随机数(例如,如果RAND_MAX为base40,则为21 23 05 06,丢弃所有具有最高基数-40位数的数字21)。