【随机数】根据概率密度生成随机数

前言

程序中常见的随机数函数通常都是均匀分布的,有时我们需要按照一个非均匀的概率来生成数字。

对于离散随机而言,可以通过分区实现,本文只讨论连续型随机变量的逆变换法。

这里所说的均匀与非均匀实际上指的是概率密度函数:

概率密度函数

连续型随机变量中,概率密度函数是一个描述这个随机变量的输出值在某个确定的取值点附近的可能性的函数。

累积概率分布

是一个随机变量,是任意实数,函数

称为的累积概率分布函数,该函数具有以下性质:

1.有界性

2.单调性

3.右连续性

逆变换法(Inverse Transform Method)

性质

对于连续型随机变量,F在区间(0,1)的反函数一定存在

U\sim U(0,1),若X = F^{-1}(U),则X的分布函数与F相同,即F_{X}= F.

证明

F_{_X}(a) = P(X\leqslant a) = P(F^{-1}(U)\leqslant a) = P(U\leqslant F(a)) = F(a) 

F_{X}= F.

算法步骤

  1. 生成一个服从均匀分布的随机数U\sim U(0,1);

  2. F为指定分布的分布函数,则X = F^{-1}(U)即为指定分布的随机数。

简单点说,就是将F(x)在dy微元映射到x轴的dx微元,是一个将均匀分布映射回x分布的过程。

例子:在圆形内按面积随机

现在我们随机生成一些点,这些点在半径为R的圆形中均匀分布。

我们先用均匀分布的半径与均匀分布的角度生成一遍:

    public void RandomRadioAndAngel()
    {
        for (int i = 0; i < 5000; i++)
        {
            float radio = Random.Range(0f, R);
            float angel = Random.Range(0f, 360f);

            Vector2 offset = Quaternion.Euler(0, 0, angel) * Vector2.right * radio;
            //生成点的方法
            InstanceCell(offset);
        }
    }

 生成结束后(图-1 左),可以发现越靠近圆心的地方密度越大,这是因为我们需要的沿半径的概率分布并非均匀分布。

圆形的半径r处,dr所对应的面积是2\pi rdr,并不是均匀分布,这里的概率密度函数是

f(r) = \frac{1}{2R^2}r         r\in \left ( 0,R \right )

累积概率分布函数为概率密度函数的积分:

F\left ( r \right ) = {\int_{0}^{r}}f\left ( r \right )        r\in \left ( 0,R \right )

F\left ( r \right ) = \frac{1}{R^2}r^{2}        r\in \left ( 0,R \right )

累积概率分布函数的反函数(注意这里是开区间):

F^{-1}\left (F\left ( r\right ) \right ) = R*\sqrt{F\left ( r\right ) }        F\left ( r\right ) \in \left ( 0,1 )

接下来按照这个函数重新随机:

    public void RandomCircleArea()
    {
        for (int i = 0; i < 5000; i++)
        {
            float radio = R * Mathf.Pow(Random.Range(0f, 1f), 0.5f);
            float angel = Random.Range(0f, 360f);

            Vector2 offset = Quaternion.Euler(0, 0, angel) * Vector2.right * radio;
            //生成点的方法
            InstanceCell(offset);
        }
    }
图 - 1

 

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值