【隨機數】根據概率密度生成隨機數

前言

程序中常見的隨機數函數通常都是均勻分佈的,有時我們需要按照一個非均勻的概率來生成數字。

對於離散隨機而言,可以通過分區實現,本文只討論連續型隨機變量的逆變換法。

這裏所說的均勻與非均勻實際上指的是概率密度函數:

概率密度函數

連續型隨機變量中,概率密度函數是一個描述這個隨機變量的輸出值在某個確定的取值點附近的可能性的函數。

累積概率分佈

是一個隨機變量,是任意實數,函數

稱爲的累積概率分佈函數,該函數具有以下性質:

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

 

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