mwultong Blog ... 프로그래밍 / 계산기

컴퓨터 엑셀 워드 포토샵 구글어스 WINDOWS JAVASCRIPT JAVA C++

 
Tuesday, October 03, 2006

C언어] 정규분포, 가우스(Gaussian) 랜덤(난수) 발생 - Gaussian Random Numbers 출력 예제


gaussianRandom() 은, "Marsaglia and Bray"의 "A Convenient Method for Generating Normal Variables (1964년)"라는 책 혹은 논문에 있는 함수입니다.

함수의 원래 이름은 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;
}



위의 예제는, 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





버그 하나를 고쳤습니다. 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++)

1 Comments:
At June 16, 2010 at 11:39 AM, Blogger kang said...

랜덤 노이즈 발생 - 평균, 분산 구하기

check 사항
1. 노이즈 2가지 구하기(가우시안,포아송 등)
2. 평균, 분산 구하기


이것도 간단하게 작성가능한가요???

좀 부탁드리겠습니다 .

 

<< Home RSS 2.0 feed

구글 Google 에서 제공하는 무료 블로그 서비스인 블로거 Blogger 의 인터넷 주소는 www.blogger.com 입니다. Blogger 에 블로그를 만들면, blogspot.com 이라는 주소에 블로그가 생성됩니다.
블로그를 직접 방문하지 않고도 최신 게시물을 구독하려면 RSS 2.0 feed 주소를 리더기에 등록하시면 됩니다.
Previous Posts
Monthly Archives
Top