使用数字配方的带有C的随机数

Random numbers with C using a numerical recipe

我想得到一个服从正态分布的随机数矩阵,我编写了这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#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\
"
,x[i][j]);
    }
  }
  free(x);
  return 0;
}

为了获得令人满意的随机数,我使用了《数字食谱》一书的食谱,并按照正态分布获取随机数,我编写了函数RANDN()。每次该函数的种子都应该不同,因此我只将C的典型随机函数作为种子。

问题在于,每次执行代码时,我都会得到相同的数字。我没有新的随机数列表。可能是什么问题?


函数RANDN接受int,但是使用函数rnd将其传递给double。从该函数返回的double在[0.0,1.0]范围内。然后将2与该值相加,结果被截断为int,始终1将值2传递给RANDN

由于此值用作种子,因此即使程序每次执行时使用新值初始化srand,种子也将始终相同。

1由于获取范围的公式是(double) rand() / (double) RAND_MAX;,因此函数rnd可以返回值1.0,这将导致将3而不是2传递给RANDN。这种情况很少发生。