一般来说,要从任意分布生成随机数,您首先要生成均匀随机数,然后将它们传递给累积分布函数的逆函数。
例如,假设您想要在区间 [-10.0, 10.0] 上均匀分布的随机数,而您得到的只是来自 [0.0, 1.0] 的随机数。 [-10.0, 10.0] 上均匀分布的累积分布函数为:
cdf(x) = 0.05 * x + 0.5 for x in [-10.0, 10.0]
这表示生成的随机数小于 x 的概率。倒数是
icdf(y) = 20.0 * y - 10.0 for y in [0.0, 1.0]
(您可以通过切换 x 和 y 轴在纸上轻松获得)。
因此要获得均匀分布在 [-10.0, 10.0] 上的随机数,您可以使用以下代码:
#include <stdlib.h>
// Returns uniformly distributed random numbers from [0.0, 1.0].
double uniform0to1Random() {
double r = random();
return r / ((double)RAND_MAX + 1);
}
// Returns uniformly distributed random numbers from [-10.0, 10.0].
double myRandom() {
return 20.0 * uniform0to1Random() - 10.0;
}
事实上,您不需要 uniform0to1Random(),因为已经有很多来自 [0.0, 1.0] 的好的统一随机数生成器(例如在 boost 库中)。
您可以使用该方法生成具有几乎任何您想要的概率分布的随机数,方法是对如上所示的逆累积分布进行采样。
更多详情请见http://en.wikipedia.org/wiki/Inverse_transform_sampling。