问我如何生成具有正态或高斯分布的随机数?
答有许多方法可以做到这一点。
#include <stdlib.h> #include <math.h> #define NSUM 25 double gaussrand() { double x = 0; int i; for(i = 0; i < NSUM; i++) x += (double)rand() / RAND_MAX; x -= NSUM / 2.0; x /= sqrt(NSUM / 12.0); return x; }(但请注意sqrt(NSUM / 12.)修正,尽管很容易无意中忽略,尤其是在NSUM为 12 时。)
#include <stdlib.h> #include <math.h> #define PI 3.141592654 double gaussrand() { static double U, V; static int phase = 0; double Z; if(phase == 0) { U = (rand() + 1.) / (RAND_MAX + 2.); V = rand() / (RAND_MAX + 1.); Z = sqrt(-2 * log(U)) * sin(2 * PI * V); } else Z = sqrt(-2 * log(U)) * cos(2 * PI * V); phase = 1 - phase; return Z; }
#include <stdlib.h> #include <math.h> double gaussrand() { static double V1, V2, S; static int phase = 0; double X; if(phase == 0) { do { double U1 = (double)rand() / RAND_MAX; double U2 = (double)rand() / RAND_MAX; V1 = 2 * U1 - 1; V2 = 2 * U2 - 1; S = V1 * V1 + V2 * V2; } while(S >= 1 || S == 0); X = V1 * sqrt(-2 * log(S) / S); } else X = V2 * sqrt(-2 * log(S) / S); phase = 1 - phase; return X; }
参考文献:Knuth 第 3.4.1 节 p. 117
Box 和 Muller,《关于生成随机正态偏差的注记》
Marsaglia 和 Bray,“生成正态变量的便捷方法”
Abramowitz 和 Stegun,《数学函数手册》
Press 等,《C 语言数值导论》第 7.2 节 pp. 288-290