我想在正态分布后得到一个随机数的矩阵,我写了这段代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define T 1
#define dt 0.2
#define iter (T/dt)
#define TWOPI (6.2831853071795864769252867665590057683943387987502)
/*See page 306 of 949 Numerical Recipes.*/
#define IM1 2147483563
#define IM2 2147483399
#define AM (1.0/IM1)
#define IMM1 (IM1-1)
#define IA1 40014
#define IA2 40692
#define IQ1 53668
#define IQ2 52774
#define IR1 12211
#define IR2 3791
#define NTAB 32
#define NDIV (1+IMM1/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
float ran2(int *idum){
int j;
long k;
static long idum2=123456789;
static long iy=0;
static long iv[NTAB];
float temp;
if (*idum <= 0) {
if (-(*idum) < 1) *idum=1;
else *idum = -(*idum);
idum2=(*idum);
for (j=NTAB+7;j>=0;j--) {
k=(*idum)/IQ1;
*idum=IA1*(*idum-k*IQ1)-k*IR1;
if (*idum < 0) *idum += IM1;
if (j < NTAB) iv[j] = *idum;
}
iy=iv[0];
}
k=(*idum)/IQ1;
*idum=IA1*(*idum-k*IQ1)-k*IR1;
if (*idum < 0) *idum += IM1;
k=idum2/IQ2;
idum2=IA2*(idum2-k*IQ2)-k*IR2;
if (idum2 < 0) idum2 += IM2;
j=iy/NDIV;
iy=iv[j]-idum2;
iv[j] = *idum;
if (iy < 1) iy += IMM1;
if ((temp=AM*iy) > RNMX) return RNMX;
else return temp;
}
/*End of the recipe.*/
double RANDN(int seed){
return sqrt(-2.0*log(ran2(&seed)))*cos(TWOPI*ran2(&seed));
}
double rnd(){
return (double) rand() / (double) RAND_MAX;
}
int main(){
int i,j,k;
double **x;
x=(double **)malloc(2*sizeof(double*));
for(k=0; k<2; k++){
x[k]=(double*)malloc(iter*sizeof(double));
}
srand(time(NULL));
for(i=0; i<2; i++){
for(j=0; j<10; j++){
x[i][j]=RANDN(rnd()+2);
printf("%lf\n",x[i][j]);
}
}
free(x);
return 0;
}
为了获得令人满意的随机数,我使用了数字食谱这本书的配方,并且为了得到正态分布后的随机数,我写了函数RANDN()。这个函数的种子每次都应该是不同的,所以我把它作为种子只是C的典型随机函数。
问题在于每次执行代码时都会得到相同的数字。我没有得到一个新的随机数列表。可能是什么问题?
答案 0 :(得分:4)
函数RANDN
使用int
,然后使用函数double
传递rnd
。从该函数返回的double
在[0.0,1.0]范围内。然后将2添加到该值,结果将被截断为int
,始终 1 将值2传递给RANDN
。
由于此值用作种子,因此即使在每次执行程序时使用新值初始化srand,种子也将始终相同。
1 由于获取范围的公式为(double) rand() / (double) RAND_MAX;
,函数rnd
可能返回值1.0,这将导致将{而不是2}传递给{ {1}}。这种情况很少发生。