根据分布生成随机数

Nil*_*age 17 random distribution

我想根据一些发行版生成随机数.我怎样才能做到这一点?

Don*_*ows 18

你得到的标准随机数发生器(rand()在简单变换后的C中,在许多语言中是等价的)是对范围[0,1]上的均匀分布的相当好的近似.如果这就是你所需要的,你就完成了.将它转换为在更大的整数范围内生成的随机数也是微不足道的.

将均匀分布转换为正态分布已经在SO上进行了覆盖,如同指数分布一样.

[编辑]:对于三角形分布,转换一个统一变量相对简单(在类似C的东西中):

double triangular(double a,double b,double c) {
   double U = rand() / (double) RAND_MAX;
   double F = (c - a) / (b - a);
   if (U <= F)
      return a + sqrt(U * (b - a) * (c - a));
   else
      return b - sqrt((1 - U) * (b - a) * (b - c));
}
Run Code Online (Sandbox Code Playgroud)

这只是转换维基百科页面上给出的公式.如果你想要别人,那就是开始寻找的地方; 通常,您使用统一变量来选择所需分布的累积密度函数的垂直轴上的点(假设它是连续的),并反转CDF以获得具有所需分布的随机值.

  • +1我很欣赏这个C伪代码,因为我在看维基百科有关三角分布的文章,却不知道如何将其转换为代码。一个更正:rand()返回一个从0到RAND_MAX的整数,所以我想你要`U =((double)rand())/ RAND_MAX`。否则,您的sqrt((1-U)...)将虚构出来。 (2认同)

Raf*_*sta 11

正确的方法是将分布分解为n-1个二进制分布.那就是如果你有这样的发行版:

A: 0.05
B: 0.10
C: 0.10
D: 0.20
E: 0.55
Run Code Online (Sandbox Code Playgroud)

您将其转换为4个二进制分布:

1. A/E: 0.20/0.80
2. B/E: 0.40/0.60
3. C/E: 0.40/0.60
4. D/E: 0.80/0.20
Run Code Online (Sandbox Code Playgroud)

从n-1分布中均匀地选择,然后根据二进制分布中的每一个的概率选择第一个或第二个符号.

代码就在这里

  • 离散RV可能是你所做的编程中最常见的,但我们很多人需要高斯,指数,三角形,对数正态,beta,gamma,Weibull等等我们的工作分布.即使使用离散分布,它们也不适用于无限范围(泊松,几何).别名表以恒定时间生成值,但大多数连续反转或合成也是如此.同时,用表格近似连续分布需要计算方法不需要的大量设置和存储.别名表在适用时很可爱,但它们不是一般解决方案. (2认同)

小智 5

这实际上取决于分布。最一般的方法如下。设 P(X) 为根据分布生成的随机数小于 X 的概率。

首先生成 0 到 1 之间的均匀随机 X。之后,您找到 Y,使得 P(Y) = X 并输出 Y。您可以使用二分查找找到这样的 Y(因为 P(X) 是 X 的递增函数)。

这不是很有效,但适用于可以有效计算 P(X) 的分布。


小智 5

您可以查找逆变换采样、拒绝采样以及 Devroye 的书“非均匀随机变量生成”/Springer Verlag 1986