5

我正在寻找一种简单的算法,如何仅使用 ANSI rand() 函数但具有任意概率分布来生成伪随机浮点数。对于简单的均匀分布,我使用以下代码:

x = (float)rand() / (float)RAND_MAX;

当然它不是很准确,但足以满足我的需求。我还需要其他分布,如逻辑和高斯分布。理想情况下,我必须使用有限长度的简单向量定义任意 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}仅使用有效地实现它。

4

5 回答 5

3

没有简单的算法可以做任意复杂的事情。您必须为每个“任意”分布找到逆概率积分变换。

于 2012-11-30T15:56:41.177 回答
2

对于任意离散分布,有一个线性时间初始化常数时间采样算法:

http://web.eecs.utk.edu/~vose/Publications/random.pdf

看看这个!它非常聪明,实现起来也不难。

于 2013-04-17T12:18:21.167 回答
2

你的问题没有一个简单的答案。Luc Devroye 用 800 多页的篇幅在他的文章“非均匀随机变量生成”中非常全面地解决了这个问题。

于 2014-04-01T17:02:31.720 回答
1

看看这个链接。这是泊松分布的示例:

#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) );
    }
  }
于 2012-11-30T12:26:30.893 回答
0

您将不得不做一些研究,因为从每个分布中绘制伪随机值的方法会有所不同。一个合理的起点是维基百科。他们有从正态/高斯分布逻辑分布生成值的方法。其他可能感兴趣的是指数分布beta 分布gamma 分布

或者,如果您有一些您有兴趣复制的源数据,您可以创建您拥有的数据的直方图并从该数据生成 CDF。然后简单地生成 X~U(0,1),并确定直方图中的哪个 bin 对应,在 bin 的上限和下限之间线性缩放。这是 stafan 提到的逆概率积分变换方法的本质。

于 2012-11-30T15:29:44.070 回答