具有任意概率分布的随机数仅使用rand()

时间:2012-11-30 12:21:48

标签: c algorithm math random probability

我正在寻找一种简单的算法,如何仅使用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}有效地实现它。

5 个答案:

答案 0 :(得分:3)

没有简单的算法可以做任意复杂的事情。你必须为每个'arbirary'发行版找到inverse probability integral transform

答案 1 :(得分:2)

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

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

看看吧!它非常聪明,并不难实现。

答案 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 distributionlogistic distribution生成值的方法。其他可能感兴趣的是exponential distributionbeta distributiongamma distribution

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