使用C語言產生正太分佈的隨機數之四
一、平均分佈隨機數的產生
double AverageRandom(double min,double max)
{
int minInteger = (int)(min*10000);
int maxInteger = (int)(max*10000);
int randInteger = rand()*rand();
int diffInteger = maxInteger - minInteger;
int resultInteger = randInteger % diffInteger + minInteger;
return resultInteger/10000.0;
}
但是有一個值得注意的問題,隨機數的產生需要有一個隨機的種子,因為用計算機產生的隨機數是通過遞推的方法得來的,必須有一個初始值,也就是通常所說的隨機種子,如果不對隨機種子進行初始化,那麼計算機有一個確省的隨機種子,這樣每次遞推的結果就完全相同了,因此需要在每次程式執行時對隨機種子進行初始化,在vc中的方法是呼叫srand(int)這個函式,其引數就是隨機種子,但是如果給一個常量,則得到的隨機序列就完全相同了,因此可以使用系統的時間來作為隨機種子,因為系統時間可以保證它的隨機性。
呼叫方法是srand((unsigned)time(NULL));但是又不能在每次呼叫rand()的時候都用srand((unsigned)time(NULL)); 來初始化,因為現在計算機執行時間比較快,當連續呼叫rand()時,系統的時間還沒有更新,所以得到的隨機種子在一段時間內是完全相同的,因此一般只在進行一次大批隨機數產生之前進行一次隨機種子的初始化。
二、任意分佈隨機數的產生(這裡以正態分佈為例)
double Normal(double x, double miu, double sigma) //概率密度函式
{
return 1.0/sqrt(2*PI*sigma) * exp(-1*(x-miu)*(x-miu)/(2*sigma*sigma));
}
/* 引數說明:
double miu:μ,正態函式的數學期望
double sigma:σ,正態函式的均方差
double min, double max,表明產生的隨機數的範圍 */
double NormalRandom(double miu, double sigma, double min, double max) //產生正態分佈隨機數
{
double x;
double dScope;
double y;
do {
x = AverageRandom(min, max);
y = Normal(x, miu, sigma);
dScope = AverageRandom(0, Normal(miu, miu, sigma));
}while(dScope > y);
return x;
}
網上搜到還有兩種演算法可以實現:
演算法一產生12個(0,1)平均分佈的隨機函式,用大數定理可以模擬出正態分佈.;
演算法二用到了數學中的雅可比變換,直接生成正態分佈,但此演算法在計算很大規模的數時會出現溢位錯誤;
這個留待以後考證了。