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

前言

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

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

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

概率密度函数

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

累积概率分布

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

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

1.有界性

2.单调性

3.右连续性

根据概率密度函数生成随机数

已有均匀分布的随机数,需要获得一个按指定概率密度分布的随机数;

根据累积概率分布函数的性质,我们已有的其实是在0-1区间(对应F\left ( x \right )有界区间)上服从均匀分布的随机数F\left ( x \right ),我们想得到的是x的分布,所以我们需要的便是将均匀分布随机数的值带入累计概率密度的反函数(对于连续型随机变量,F(x)在区间(0,1)的反函数一定存在),x = F^{-1}\left ( F\left ( x \right ) \right )就是我们需要的。

简单点说,就是将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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章