C++における疑似乱数の生成プログラムについてのメモです。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
double urand(){
double m, a;
m = RAND_MAX + 1;
a = (rand() + 0.5)/m;
a = (rand() + a)/m;
return (rand() + a)/m;
}
int main(){
int i;
srand((unsigned int)time(NULL));
for(i=0; i<10; i++){
printf("%f\n", urand());
}
return 0;
}
#include <stdint.h>
uint32_t xorshift(){
static uint32_t x = 123456789;
static uint32_t y = 362436069;
static uint32_t z = 521288629;
static uint32_t w = 88675123;
uint32_t t;
t = x ^ (x<<11);
x = y; y = z; z = w;
w ^= t ^ (t>>8) ^ (w>>19);
return w;
}
#include <stdint.h>
#include <stdio.h>
#include <time.h>
static uint32_t xorsft_x = 123456789;
static uint32_t xorsft_y = 362436069;
static uint32_t xorsft_z = 521288629;
static uint32_t xorsft_w = 88675123;
void initrand(uint32_t seed){
do {
seed = seed*1812433253 + 1; seed ^= seed<<13; seed ^= seed>>17;
xorsft_x = 123464980 ^ seed;
seed = seed*1812433253 + 1; seed ^= seed<<13; seed ^= seed>>17;
xorsft_y = 3447902351 ^ seed;
seed = seed*1812433253 + 1; seed ^= seed<<13; seed ^= seed>>17;
xorsft_z = 2859490775 ^ seed;
seed = seed*1812433253 + 1; seed ^= seed<<13; seed ^= seed>>17;
xorsft_w = 47621719 ^ seed;
} while(xorsft_x==0 && xorsft_y==0 && xorsft_z==0 && xorsft_w==0);
}
double urand(){
uint32_t t;
t = xorsft_x ^ (xorsft_x<<11);
xorsft_x = xorsft_y;
xorsft_y = xorsft_z;
xorsft_z = xorsft_w;
xorsft_w ^= t ^ (t>>8) ^ (xorsft_w>>19);
return ((xorsft_x+0.5) / 4294967296.0 + xorsft_w) / 4294967296.0;
}
int main(){
int i;
initrand((unsigned int)time(NULL));
for(i=0; i<10; i++){
printf("%f\n", urand());
}
return 0;
}
#include <math.h>
#include <stdio.h>
double normrand(){
return sqrt(-2*log(urand()))*cos(2*M_PI*urand());
}
int main(){
int i;
initrand((unsigned int)time(NULL));
for(i=0; i<10; i++){
printf("%f\n", normrand());
}
return 0;
}
#include <math.h>
#include <stdio.h>
double normrand(){
double x, y, r;
do{
x = 2*urand() - 1;
y = 2*urand() - 1;
r = x*x + y*y;
} while(r>=1);
return sqrt(-2*log(r)/r)*x;
}
int main(){
int i;
initrand((unsigned int)time(NULL));
for(i=0; i<10; i++){
printf("%f\n", normrand());
}
return 0;
}
#include <math.h>
#include <stdio.h>
double exprand(double lambda){
return -lambda*log(urand());
}
int main(){
int i;
initrand((unsigned int)time(NULL));
for(i=0; i<10; i++){
printf("%f\n", exprand(1.0));
}
return 0;
}
#include <math.h>
#include <stdio.h>
int porand(double lambda){
double a, b;
int k = 0;
a = urand();
b = exp(-lambda);
while(a>=b){
a *= urand();
k++;
}
return k;
}
int main(){
int i;
initrand((unsigned int)time(NULL));
for(i=0; i<10; i++){
printf("%d\n", porand(1.0));
}
return 0;
}
#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
static uint32_t xorsft_x = 123456789;
static uint32_t xorsft_y = 362436069;
static uint32_t xorsft_z = 521288629;
static uint32_t xorsft_w = 88675123;
// 乱数系列初期化
void initrand(uint32_t seed){
do {
seed = seed*1812433253 + 1; seed ^= seed<<13; seed ^= seed>>17;
xorsft_x = 123464980 ^ seed;
seed = seed*1812433253 + 1; seed ^= seed<<13; seed ^= seed>>17;
xorsft_y = 3447902351 ^ seed;
seed = seed*1812433253 + 1; seed ^= seed<<13; seed ^= seed>>17;
xorsft_z = 2859490775 ^ seed;
seed = seed*1812433253 + 1; seed ^= seed<<13; seed ^= seed>>17;
xorsft_w = 47621719 ^ seed;
} while(xorsft_x==0 && xorsft_y==0 && xorsft_z==0 && xorsft_w==0);
}
// 一様乱数
double urand(){
uint32_t t;
t = xorsft_x ^ (xorsft_x<<11);
xorsft_x = xorsft_y;
xorsft_y = xorsft_z;
xorsft_z = xorsft_w;
xorsft_w ^= t ^ (t>>8) ^ (xorsft_w>>19);
return ((xorsft_x+0.5) / 4294967296.0 + xorsft_w) / 4294967296.0;
}
// 正規乱数
double normrand(){
return sqrt(-2*log(urand()))*cos(2*M_PI*urand());
}
// 指数分布に従う乱数
double exprand(double lambda){
return -lambda*log(urand());
}
// ポアソン分布に従う乱数
int porand(double lambda){
double a, b;
int k = 0;
a = urand();
b = exp(-lambda);
while(a>=b){
a *= urand();
k++;
}
return k;
}
int main(){
int i;
initrand((unsigned int)time(NULL));
printf("一様乱数\n");
for(i=0; i<10; i++){
printf("%f\n", urand());
}
printf("正規乱数\n");
for(i=0; i<10; i++){
printf("%f\n", normrand());
}
printf("指数分布に従う乱数\n");
for(i=0; i<10; i++){
printf("%f\n", exprand(1.0));
}
printf("ポアソン分布に従う乱数\n");
for(i=0; i<10; i++){
printf("%d\n", porand(1.0));
}
return 0;
}