我正在尝试编写蒙特卡罗模拟。在我的模拟中,我需要从离散概率分布中生成许多随机变量。
我确实有一个封闭形式的分布解决方案,它有有限的支持;但是,它不是标准分布。我知道我可以绘制一个统一的 [0,1) 随机变量并将其与 CDF 进行比较,从我的分布中得到一个随机变量,但分布中的参数总是在变化。使用这种方法太慢了。
所以我想我的问题有两个部分:
是否有一种方法/算法可以在不使用 CDF 的情况下快速生成有限的离散随机变量?
是否有已经具有此功能的 Python 模块和/或 C++ 库?
我正在尝试编写蒙特卡罗模拟。在我的模拟中,我需要从离散概率分布中生成许多随机变量。
我确实有一个封闭形式的分布解决方案,它有有限的支持;但是,它不是标准分布。我知道我可以绘制一个统一的 [0,1) 随机变量并将其与 CDF 进行比较,从我的分布中得到一个随机变量,但分布中的参数总是在变化。使用这种方法太慢了。
所以我想我的问题有两个部分:
是否有一种方法/算法可以在不使用 CDF 的情况下快速生成有限的离散随机变量?
是否有已经具有此功能的 Python 模块和/或 C++ 库?
如果您通过分析了解您的pdf,确实接受/拒绝是要走的路。我们称它为 f(x)。找到一个 pdf g(x) 使得存在一个常数 c,这样 cg(x) > f(x),并且你知道如何用 pdf g(x) 模拟一个变量 - 例如,当你工作时对于具有有限支持的分布,统一将做:g(x)= 1 /(您的域的大小)在域上。
然后画一对 (G, U) 使得 G 用 pdf g(x) 模拟,并且 U 在 [0, cg(G)] 上是均匀的。然后,如果 U < f(G),接受 U 作为变量。否则重画。您最终将接受的 U 将具有 f 作为 pdf 格式。
请注意,常数 c 决定了该方法的效率。c 越小,你的效率就越高——基本上你需要平均 c 图纸来获得正确的变量。最好让函数 g 足够简单(不要忘记您需要使用 g 作为 pdf 来绘制变量),但将尽可能小的 c.
Acceptance\Rejection:找到一个总是高于 pdf 的函数。生成 2 个随机变量。第一个缩放以计算值,第二个用于决定是接受还是拒绝选择。冲洗并重复,直到您接受一个值。抱歉,我不能更具体,但我已经有一段时间没有这样做了。它是一个标准算法,但我会亲自从头开始实现它,所以我不知道有任何实现。
如果接受拒绝也太低效,您也可以尝试一些马尔可夫链 MC 方法,它们会生成一系列样本,每个样本都依赖于前一个样本,因此通过跳过其中的块,可以对子样本进行子采样,从而获得或多或少独立的集合。他们只需要 PDF,甚至只需要 PDF 的倍数。通常它们使用固定分布,但也可以适应缓慢变化的分布。