隨機數生成器

Park和MIller提供的“最小標準”隨機數生成器

#define a 16807
#define m 2147483647    // 2^31 -1
#define q (m / a)
#define r (m % a)

static long int seed = 1;

/*
   X <-- (aX + c) mod m;  (c = 0)
   return [1, 2147483647]隨機數
*/
long int PMrand()
{
    long int hi = seed / q;
    long int lo = seed % q;
    long int test = a * lo - r * hi;
    if(test > 0)    seed = test;
    else     seed = test + m;
    
    return seed;
}

/*
   X <-- (aX + c) mod m;  (c = 0)
   return [0, 1]隨機數
*/
double PMrandDouble()
{
    long int hi = seed / q;
    long int lo = seed % q;
    long int test = a * lo - r * hi;
    if(test > 0)    seed = test;
    else     seed = test + m;
    
    return (double)seed / m;
}

正態分佈或高斯分佈隨機數:

方法一:運用中心極限定理(大數定律)將幾個平均分佈的隨機數加起來

#include <stdlib.h>
#include <math.h>
#define NSUM 25

double GaussRand()
{
    double x = 0;
    for(int i = 0; i < NSUM; i ++){
         x += (double)rand() / RAND_MAX;
    }
    x -= NSUM / 2.0;
    x /= sqrt(NSUM / 12.0);
    
    return x;
}

方法二:由Box和Muller提供的,在Knuth的網上討論過的方法

#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.0) / (RAND_MAX + 2.0);
        V = rand() / (RAND_MAX + 1.0);
        Z = sqrt(-2 * log(U)) * sin(2 * PI * V);
    }
    else{
        Z = sqrt(-2 * log(U)) * cos(2 * PI * V);
    }
    phase = 1 - phase;

    return Z;
}
方法三:最初由Marsaglia提供的方法

#include <stdlib.h>
#include <math.h>

double GaussRand()
{
    static doubel 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;
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章