伪随机数发生器 - 指数分布

Cha*_*lts 57 language-agnostic random algorithm exponential-distribution

我想生成一些伪随机数,直到现在我一直非常满意.Net库的Random.Next(int min, int max)功能.这个品种的PRNG 应该使用Uniform分布,但我非常希望使用指数分布生成一些数字.

我正在用C#编程,虽然我会接受伪代码或C++,Java等.

任何建议/代码片段/算法/想法?

Alo*_*hal 99

由于您可以访问统一的随机数生成器,因此可以使用反转方法生成随其他分布一起分发的随机数,该分布的CDF很容易知道.

因此,生成一个统一的随机数u,in [0,1),然后x通过以下方式计算:

x = log(1-u)/(),

其中λ是指数分布的速率参数.现在,x是一个具有指数分布的随机数.注意,log上面是ln自然对数.

  • @khalafnt:指数分布的范围为[0,无穷大],因此生成数字> 1并不奇怪. (5认同)
  • [0,1]中的1-u等于(0,1).所以你可以只记录((0,1))/( - λ) (4认同)
  • @varela:完全正确,但是让我添加一个小警告:由于我知道大多数随机数生成器在`[0,1)`中生成数字,有人可能会意外地尝试`log([0,1))/ (-λ)`.这可能很少创建`+ infinity`,即如果随机数生成器生成'0'(由于`[0,1)`).我认为发生这种情况的机会非常非常小,但不是零.此分布也可能有点*错误.通过使用`1- [0,1)`,可以防止错误.没有它,我们需要它 - 然后检查"0".这将花费更多的运行时间.无论如何,你的评论是对的. (2认同)

dmc*_*kee 13

采样的基本定理认为,如果你可以归一化,整合和反转所需的分布,那么你就可以免费回家了.

如果您具有F(x)标准化的所需分布[a,b].你计算

C(y) = \int_a^y F(x) dx
Run Code Online (Sandbox Code Playgroud)

反转得到C^{-1},z在[0,1)上统一投掷并找到

x_i = C^{-1}(z_i)
Run Code Online (Sandbox Code Playgroud)

这将具有所需的分布.


在你的情况下:F(x) = ke^{-kx}我会假设你想要的[0,infinity].我们得到:

C(y) = 1 - e^{-ky}
Run Code Online (Sandbox Code Playgroud)

这是可以转换的

x = -1/k  ln(1 - z)
Run Code Online (Sandbox Code Playgroud)

为z统一抛出[0,1).


但是,坦率地说,使用经过良好调试的库是比较聪明的,除非你为自己的启发做这件事.


zah*_*ani 12

这是我在维基百科上找到的公式:

T = -Ln(u) / ?

我们在 [0,1] 中创建一个具有均匀分布 (u) 的随机数,我们得到 x :

随机 R = 新随机();

double u = R.NextDouble();

double x = -Math.Log(u)/(?);


Ram*_*nka 6

如果你想要好的随机数,可以考虑链接到gsl例程:http://www.gnu.org/software/gsl/ .他们有常规gsl_ran_exponential.如果你想使用在[0,1)上具有均匀分布的内置生成器生成随机数(例如u = Random.Next(0,N-1)/ N,对于某些大N),那么只需使用:

-mu * log (1-u)
Run Code Online (Sandbox Code Playgroud)

请参阅gsl源代码中的randist/exponential.c.

编辑:只是为了与后来的一些答案进行比较 - 这相当于mu = 1/lambda.mu这里是分布的均值,也称为OP链接到的维基百科页面上的scale参数,lambda是rate参数.