我正在寻找一种简单的算法,如何仅使用ANSI rand()函数生成伪随机浮点数,但具有任意概率分布。对于简单的统一分布,我使用以下代码:
x = (float)rand() / (float)RAND_MAX;
当然它不是很准确,但足以满足我的需求。我还需要其他发行版如logistic和gaussian。理想情况下,我必须使用有限长度的简单向量来定义任意pdf,例如,对于逻辑pdf,此向量可能如下所示:
logistic_pdf = {0., 0.26894, 0.33924, 0.41742, 0.5, 0.58257, 0.66075, 1.};
和统一(使用相同的维度8):
uniform_pdf = {0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125};
这只是一个想法。但我不确定如何仅使用rand()->{0...RAND_MAX}
有效地实现它。
答案 0 :(得分:3)
没有简单的算法可以做任意复杂的事情。你必须为每个'arbirary'发行版找到inverse probability integral transform。
答案 1 :(得分:2)
答案 2 :(得分:2)
你的问题没有一个简单的答案。 Luc Devroye在他的文本“Non-Uniform Random Variate Generation”中花了800多页来全面地解决这个问题。
答案 3 :(得分:1)
看看这个link。这是泊松分布的一个例子:
#include < stdlib.h >
#include < math.h >
int Poisson ( double ev ) {
int n = 0; // counter of iterations
double em; // e^(-ev), where v is the expected value
double x; // pseudorandom number
em = exp (-ev);
x = rand() / (double) RAND_MAX; // check your C compiler docs
// for the correct constant name
while (x > em) {
n++;
x *= rand() / (double) RAND_MAX;
}
return n;
}
main () {
int i;
for (i = 0; i< 1000; i++) {
printf("new Poisson value: %d\n", Poisson(.133333) );
}
}
答案 4 :(得分:0)
您将不得不进行一些研究,因为从每个分布中绘制伪随机值的方法会有所不同。一个合理的起点是维基百科。他们有从normal / Gaussian distribution和logistic distribution生成值的方法。其他可能感兴趣的是exponential distribution, beta distribution和gamma distribution。
或者,如果您有一些您想要复制的源数据,您可以创建您拥有的数据的直方图,并从该数据生成CDF。然后简单地生成X~U(0,1),并确定直方图中哪个bin对应,在bin的上边界和下边界之间线性缩放。这是stafan提到的逆概率积分变换方法的本质。