Tuesday, October 03, 2006
C언어] 정규분포, 가우스(Gaussian) 랜덤(난수) 발생 - Gaussian Random Numbers 출력 예제
gaussianRandom() 은, "Marsaglia and Bray"의 "A Convenient Method for Generating Normal Variables (1964년)"라는 책 혹은 논문에 있는 함수입니다.
함수의 원래 이름은 gaussrand() 이지만, 알기 쉽게 자바 스타일로 바꾸었습니다.
예제 소스 파일명: 0.cpp
위의 예제는, Gauss(가우스) 분포의 double형 난수 1000개를 생성하여 화면에 출력합니다.
50개만 만든 후, 엑셀로 정렬한 결과:
버그 하나를 고쳤습니다. srand()가 없어서, 난수 발생기가 초기화되지 않아, 항상 같은 난수가 나오는 심각한 문제가 있었습니다.
그래서 srand(GetTickCount()); 이런 줄을 추가하고, Windows.h 파일도 인클루드했습니다.
GetTickCount()는 비주얼C++용입니다. 이렇게 하지 않으면 제대로 된 난수가 발생하지 않습니다. (▶▶ C언어] 랜덤(Random)하게 숫자(정수) 출력, srand(), rand(), randomize() - Visual C++ 참고)
다른 컴파일러라면, time.h 를 추가해 주고,
srand((unsigned) time(NULL));
이렇게 해주면 될 것입니다.
업데이트:
위의 함수를 좀더 간결하게 만들어 보았습니다: ▶▶ C언어 VC++] 가우시안 랜덤 난수 발생; 가우스 분포 Gaussian Random Number
참고: ▶▶ 자바/Java] 정규분포, 가우스(Gaussian) 랜덤(난수) 발생 - Gaussian Random Numbers 출력 예제
함수의 원래 이름은 gaussrand() 이지만, 알기 쉽게 자바 스타일로 바꾸었습니다.
가우시안 분포 랜덤 생성 함수/알고리즘
예제 소스 파일명: 0.cpp
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <Windows.h>
double gaussianRandom(void);
void main(void) {
srand(GetTickCount());
for (int i = 1; i <= 1000; i++)
printf("%.17f\n", gaussianRandom());
}
double gaussianRandom(void) {
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;
}
#include <stdlib.h>
#include <math.h>
#include <Windows.h>
double gaussianRandom(void);
void main(void) {
srand(GetTickCount());
for (int i = 1; i <= 1000; i++)
printf("%.17f\n", gaussianRandom());
}
double gaussianRandom(void) {
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;
}
위의 예제는, Gauss(가우스) 분포의 double형 난수 1000개를 생성하여 화면에 출력합니다.
50개만 만든 후, 엑셀로 정렬한 결과:
-1.728912365
-1.554865906
-1.510491742
-1.321481501
-1.228210265
-1.114015373
-1.052424575
-0.668513135
-0.658040225
-0.585850803
-0.328124108
-0.325623216
-0.294021839
-0.289287819
-0.281507388
-0.280250798
-0.27211744
-0.22408658
-0.206039686
-0.154466228
-0.151188728
-0.145078739
-0.082000756
-0.070316243
-0.056154676
-0.029801638
-0.021061001
-0.020166214
-0.015427861
-0.00513745
0.014130328
0.049525363
0.073987525
0.105464546
0.216741125
0.233494976
0.234902525
0.345435489
0.485725735
0.495800705
0.511489072
0.659265378
0.701519594
0.880388888
0.882629521
0.976491214
1.291791823
1.347197109
1.723446981
2.591491108
-1.554865906
-1.510491742
-1.321481501
-1.228210265
-1.114015373
-1.052424575
-0.668513135
-0.658040225
-0.585850803
-0.328124108
-0.325623216
-0.294021839
-0.289287819
-0.281507388
-0.280250798
-0.27211744
-0.22408658
-0.206039686
-0.154466228
-0.151188728
-0.145078739
-0.082000756
-0.070316243
-0.056154676
-0.029801638
-0.021061001
-0.020166214
-0.015427861
-0.00513745
0.014130328
0.049525363
0.073987525
0.105464546
0.216741125
0.233494976
0.234902525
0.345435489
0.485725735
0.495800705
0.511489072
0.659265378
0.701519594
0.880388888
0.882629521
0.976491214
1.291791823
1.347197109
1.723446981
2.591491108
버그 하나를 고쳤습니다. srand()가 없어서, 난수 발생기가 초기화되지 않아, 항상 같은 난수가 나오는 심각한 문제가 있었습니다.
그래서 srand(GetTickCount()); 이런 줄을 추가하고, Windows.h 파일도 인클루드했습니다.
GetTickCount()는 비주얼C++용입니다. 이렇게 하지 않으면 제대로 된 난수가 발생하지 않습니다. (▶▶ C언어] 랜덤(Random)하게 숫자(정수) 출력, srand(), rand(), randomize() - Visual C++ 참고)
다른 컴파일러라면, time.h 를 추가해 주고,
srand((unsigned) time(NULL));
이렇게 해주면 될 것입니다.
업데이트:
위의 함수를 좀더 간결하게 만들어 보았습니다: ▶▶ C언어 VC++] 가우시안 랜덤 난수 발생; 가우스 분포 Gaussian Random Number
참고: ▶▶ 자바/Java] 정규분포, 가우스(Gaussian) 랜덤(난수) 발생 - Gaussian Random Numbers 출력 예제
tag: cpp
C언어 | C/C++ (Visual C++)
랜덤 노이즈 발생 - 평균, 분산 구하기
check 사항
1. 노이즈 2가지 구하기(가우시안,포아송 등)
2. 평균, 분산 구하기
이것도 간단하게 작성가능한가요???
좀 부탁드리겠습니다 .
<< Home