【发布时间】:2011-09-14 18:48:25
【问题描述】:
据我所知 rand() 不会生成均匀的随机分布。什么功能/算法将允许我这样做?我不需要加密随机性,只需要均匀随机分布。最后,哪些库提供这些功能? 谢谢!
【问题讨论】:
-
你需要像
unidrnd这样的东西,见octave.sourceforge.net/octave/function/unidrnd.html .. 我想也有一个C++ API,试着挖掘代码:)
据我所知 rand() 不会生成均匀的随机分布。什么功能/算法将允许我这样做?我不需要加密随机性,只需要均匀随机分布。最后,哪些库提供这些功能? 谢谢!
【问题讨论】:
unidrnd 这样的东西,见octave.sourceforge.net/octave/function/unidrnd.html .. 我想也有一个C++ API,试着挖掘代码:)
rand()确实生成均匀(伪)随机分布。
来自C standard (3.7 MB PDF) 第 7.20.2.1 节的实际要求是:
rand 函数计算伪随机整数序列 范围 0 到 RAND_MAX。
其中 RAND_MAX 至少为 32767。这确实含糊不清,但其目的是为您提供统一的分布 - 实际上,这就是实现的实际作用。
该标准提供了一个示例实现,但不要求使用 C 实现。
在实践中,肯定有更好的随机数生成器。 rand() 的一个具体要求是它必须为给定的种子生成完全相同的数字序列(srand() 的参数)。您的描述并不表明这对您来说是个问题。
一个问题是rand() 给你一个固定范围内均匀分布的数字。如果你想要不同范围内的数字,你必须做一些额外的工作。例如,如果 RAND_MAX 是 32767,那么rand() 可以产生 32768 个不同的值;如果不丢弃某些值,您将无法获得 0..9 范围内的随机数,因为无法将这 32768 个不同的值均匀地分配到 10 个大小相等的存储桶中。
其他 PRNG 可能会给您比 rand() 更好的结果,但它们仍然可能会遇到同样的问题。
像往常一样,comp.lang.c FAQ 比我回答得更好;见问题 13.15 到 13.21。
【讨论】:
这是一篇用 C# 编写的文章和 stand-alone random number generator。代码非常小,很容易移植到 C++ 等。
每当这个话题出现时,就会有人回应说您不应该使用自己的随机数生成器,而应该让专家来处理。我回应说你不应该想出你自己的算法。把它留给专家,因为它确实非常微妙。但是拥有自己的实现是可以的,甚至是有益的。这样您就知道正在做什么,并且可以跨语言或平台使用相同的方法。
那篇文章中的算法由随机数生成领域的顶级专家 George Marsaglia 编写。尽管代码很小,但该方法经得起标准测试。
【讨论】:
BSD random() 函数(包含在 POSIX/SUS 的 XSI 选项中)几乎是普遍可用的,并且在大多数系统上都比 rand 好得多(除了一些 rand 实际使用 random 并因此它们'都很好)。
如果您宁愿不使用系统库,这里有一些关于您选择的有用信息:
http://guru.multimedia.cx/category/pseudo-random-number-generators/
(来自 FFmpeg 的 Michael Niedermayer。)
【讨论】:
【讨论】: