A. 如何用c語言生成一個正態分布的樣本
調試程序時,隨機數種子可以設常數,例如srand(54321);
用 rand() 產生均勻分布隨機數 x1,x2
利用瑞利分布得正態分布隨機數 y1,y2
再按要求線性縮放一下到[0.01,2] 區間。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
main(){
#define N 100
double rd[N];
double x1,x2,y1,y2;
double pi2=6.28318530728,mx,mi,ave=0;
int i;
//srand(54321);
srand(time(NULL));
for (i=0;i<=N-2;i=i+2){
x1=1.0*rand()/RAND_MAX;
x2=1.0*rand()/RAND_MAX;
y1= sqrt((-2.0*log(x1))) * cos(pi2*x2);
y2= sqrt((-2.0*log(x1))) * sin(pi2*x2);
rd[i]=y1;
rd[i+1]=y2;
}
mx=rd[0];mi=rd[0];
for (i=0;i<N;i++){
if (rd[i]>mx)mx=rd[i];
if (rd[i]<mi)mi=rd[i];
}
//printf("mi=%lf mx=%lf\n",mi,mx);
for (i=0;i<N;i++) rd[i] = (rd[i]-mi)/(mx-mi+0.001) * (2.0-0.01) + 0.01;
for (i=0;i<N-2;i=i+2) printf("%lf %lf\n",rd[i],rd[i+1]);
return 0;
}
B. 如何在C語言中生成正態分布的隨機數,要源代碼~謝謝
隨機生成一百個1至100的隨機數。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 100
int main(int argc, char *argv[])
{
int i;
int a[N];
srand(time(NULL));
for(i=0;i<N;i++)
a[i]=rand()%100+1;
printf("生成的隨機數為:\n");
for(i=0;i<N;i++)
{
printf("%5d",a[i]);
if((i+1)%10==0)
printf("\n");
}
system("PAUSE");
return 0;
}
輸出結果如下:
生成的隨機數為:
41 15 82 1 23 51 16 96 92 17
86 71 87 69 74 5 50 18 42 52
46 34 52 18 40 74 79 35 22 36
65 94 80 91 18 72 61 79 4 11
61 30 95 55 11 19 38 87 78 52
95 30 99 53 99 99 10 79 70 33
91 85 10 99 47 58 93 41 19 71
56 60 10 24 73 87 18 38 13 73
57 22 91 4 37 60 67 58 85 48
46 7 57 100 73 96 60 44 24 23
請按任意鍵繼續. . .
C. 正態分布函數
正態分布最早是由一位數學家從二項分布在n趨近於無窮大時的近似而推導出來的。 二項分布的概率密度C(m,n)*p^m*(1-p)^(n-m),考慮此函數在n趨近於無窮大,m在n/2附近時的近似。 求近似時,關鍵的一步是用斯特靈公式:N!約等於N的N次方乘以根號下2πN再除以e的N次方,當N非常大時。在具體推導中,對於n,n-m,m都可以適用此近似。 另一個關鍵步驟是,推導中用d^2=np(1-p)來代換,也就是說,二項分布的分散,對於二項分布的近似,仍然是一個有意義的有限的值。
D. 怎麼調用c語言中的標准正態分布函數
摘要:
隨機數在實際運用中非常之多,如游戲設計,信號處理,通常我們很容易得到平均分布的隨機數。但如何根據平均分布的隨機數進而產生其它分布的隨機數呢?本文提出了一種基於幾何直觀面積的方法,以正態分布隨機數的產生為例討論了任意分布的隨機數的產生方法。
大家都知道,隨機數在各個方面都有很大的作用,在vc的環境下,為我們提供了庫函數rand()來產生一個隨機的整數。該隨機數是平均在0~RAND_MAX之間平均分布的,RAND_MAX是一個常量,在VC6.0環境下是這樣定義的:
#define RAND_MAX 0x7fff
它是一個short 型數據的最大值,如果要產生一個浮點型的隨機數,可以將rand()/1000.0這樣就得到一個0~32.767之間平均分布的隨機浮點數。如果要使得范圍大一點,那麼可以通過產生幾個隨機數的線性組合來實現任意范圍內的平均分布的隨機數。例如要產生-1000~1000之間的精度為四位小數的平均分布的隨機數可以這樣來實現。先產生一個0到10000之間的隨機整數。方法如下 :
int a = rand()%10000;
然後保留四位小數產生0~1之間的隨機小數:
double b = (double)a/10000.0;
然後通過線性組合就可以實現任意范圍內的隨機數的產生,要實現-1000~1000內的平均分布的隨機數可以這樣做:
double dValue = (rand()%10000)/10000.0*1000-(rand()%10000)/10000.0*1000;
則dValue就是所要的值。
到現在為止,你或許以為一切工作都已經完成了,其實不然,仔細一看,你會發現有問題的,上面的式子化簡後就變為:
double dValue = (rand()%10000)/10.0-(rand()%10000)/10.0;
這樣一來,產生的隨機數范圍是正確的,但是精度不正確了,變成了只有一位正確的小數的隨機數了,後面三位的小數都是零,顯然不是我們要求的,什麼原因呢,又怎麼辦呢。
先找原因,rand()產生的隨機數解析度為32767,兩個就是65534,而經過求余後分辨度還要減小為10000,兩個就是20000而要求的解析度為1000*10000*2=20000000,顯然遠遠不夠。下面提供的方法可以實現正確的結果:
double a = (rand()%10000) * (rand()%1000)/10000.0;
double b = (rand()%10000) * (rand()%1000)/10000.0;
double dValue = a-b;
則dValue就是所要求的結果。在下面的函數中可以實現產生一個在一個區間之內的平均分布的隨機數,精度是4位小數。
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(GetTickCount()),但是又不能在每次調用rand()的時候都用srand(GetTickCount())來初始化,因為現在計算機運行時間比較快,當連續調用rand()時,系統的時間還沒有更新,所以得到的隨機種子在一段時間內是完全相同的,因此一般只在進行一次大批隨機數產生之前進行一次隨機種子的初始化。下面的代碼產生了400個在-1~1之間的平均分布的隨機數。
double dValue[400];
srand(GetTickCount());
for(int i= 0;i < 400; i++)
{
double dValue[i] = AverageRandom(-1,1);
}
E. 標准正態分布函數的c語言代碼 謝啦
double gaussian(double u) //用Box_Muller演算法產生高斯分布的隨機數
{
double r,t,z,x;
double s1,s2;
s1=(1.0+rand())/(RAND_MAX+1.0);
s2=(1.0+rand())/(RAND_MAX+1.0);
r=sqrt(-2*log(s2)/log(e));
t=2*pi*s1;
z=r*cos(t);
x=u+z*N;
return x;
}
以前寫的一個函數,u是均值,N是方差
F. 如何用c語言生成一個正態分布的樣本
不用加分,我做過,用來產生圖像的高斯雜訊,也就是你要的正態分布.
1.首先你的樣本應該是有一定范圍的吧,我假設它是從1-255
2.根據你的方差和期望,把樣本代進去,算出該樣本出現的概率
3.然後根據概率知識,你做一個累積概率
4.接著你用隨機數產生一個0-1之間的均勻分布
5.看這個數落在哪個累積概率區間
6.按你要的樣本數重復4-5
代碼這里我給個matlab程序你參考一下,很好懂的
function [dest] = GeneGauss(expectation,deviation,width,height)
dest=zeros(width,height);
pz=zeros(256);
tempConst1=1/(sqrt(2*pi)*deviation);
tempConst2=2*deviation*deviation;
for i=1:256
pz(i)=tempConst1*exp(-(i-1-expectation)^2/tempConst2);
end
f=zeros(256);
f(1)=pz(1);
for i=2:256
f(i) = f(i-1)+pz(i);
end
for i=1:width
for j=1:height
n=rand;
for k=1:256
if(n<f(k))
dest(i,j)=k-1;
break;
end
end
end
end
end
G. 高手進,c語言中如何得到服從正態分布的隨機數
最好尋求專門演算法
如果不行的話,也可以用大量隨機數來模擬,譬如生成1000次0或1,然後求其平均數,可以得到很接近正態分布的.
如果有連續的隨機函數,也可以直接求正態分部的積分函數,根據積分函數的反函數來確定位置
H. 求大神給出用C語言編程生成正態分布隨機數的程序,要不是標准正態分布的
一般有兩種演算法:
演算法一產生12個(0,1)平均分布的隨機函數,用大數定理可以模擬出正態分布。
演算法二用到了數學中的雅可比變換,直接生成正態分布,但此演算法在計算很大規模的數時
會出現溢出錯誤。
測試程序:
#include <math.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
double _random(void)
{
int a;
double r;
a=rand()%32767;
r=(a+0.00)/32767.00;
return r;
}
double _sta(double mu,double sigma)
{
int i;
double r,sum=0.0;
if(sigma<=0.0) { printf("Sigma<=0.0 in _sta!"); exit(1); }
for(i=1;i<=12;i++)
sum = sum + _random();
r=(sum-6.00)*sigma+mu;
return r;
}
double _sta2(double mu,double sigma)
{
double r1,r2;
r1=_random();
r2=_random();
return sqrt(-2*log(r1))*cos(2*M_PI*r2)*sigma+mu ;
}
int main()
{
int i;
double mu,sigma;
srand( (unsigned)time( NULL ) );
mu=0.0;
sigma=1.0;
printf("Algorithm 1:\n");
for(i=0;i<10;i++)
printf("%lf\t",_sta(mu,sigma));
printf("Algorithm 2:\n");
for(i=0;i<10;i++)
printf("%lf\t",_sta2(mu,sigma));
return 0;
}
//由均勻分布的隨機數得到正態分布的隨機數
#include <math.h>
float gasdev(im)
int *im;
{
static int iset=0;
static float gset;
float fac,r,v1,v2;
float ran1();//產生均勻分布的隨機數,可利用系統函數改寫
if (iset == 0) {
do {
v1=2.0*ran1(im)-1.0;
v2=2.0*ran1(im)-1.0;
r=v1*v1+v2*v2;
} while (r >= 1.0);
fac=sqrt(-2.0*log(r)/r);
gset=v1*fac;
iset=1;
return v2*fac;
} else {
iset=0;
return gset;
}
}
原理可找本數值演算法方面的書看看。
I. C語言中調用標准正態分布函數
C++中有,記得是boost的random庫,用起來很簡單的。