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

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

 
Sunday, November 26, 2006

C언어 VC++] 가우시안 랜덤 난수 발생; 가우스 분포 Gaussian Random Number


C언어로 특수한 난수발생기를 만드는 예제 소스 코드입니다.


▶▶ C언어] 정규분포, 가우스(Gaussian) 랜덤(난수) 발생 - Gaussian Random Numbers 출력 예제 여기에 있는 가우스 함수를 좀 간단하게 만든 것이, 이 게시물입니다. 결과는 똑같습니다.


정규 분포 랜덤 난수 발생 함수; (Gaussian Random; Gauss)


소스 파일명: 0.cpp
#include <stdio.h>
#include <math.h>
#include <Windows.h>

double gaussianRandom(void);


int main(void) {
  srand(GetTickCount());

  for (int i = 1; i <= 50; i++)
    printf("%.17f\n", gaussianRandom());

  return 0;
}




double gaussianRandom(void) {
  double v1, v2, s;

  do {
    v1 =  2 * ((double) rand() / RAND_MAX) - 1;      // -1.0 ~ 1.0 까지의 값
    v2 =  2 * ((double) rand() / RAND_MAX) - 1;      // -1.0 ~ 1.0 까지의 값
    s = v1 * v1 + v2 * v2;
  } while (s >= 1 || s == 0);

  s = sqrt( (-2 * log(s)) / s );

  return v1 * s;
}



컴파일 및 실행 결과:
D:\Z>cl 0.cpp && 0.exe
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

0.cpp
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:0.exe
0.obj
0.97245226306248322
0.24682554742988275
0.03399690543556370
-1.92099484722249510
0.02775523712314788
0.40535296910299418
1.24989706616340790
-0.03605704597324999
-1.46928951594857750
-0.69524409783095309
0.22335936128451783
-0.71284728214546456
-0.30582161643288203
0.82690960662654422
0.26541871437854253
2.53888204555763860
0.48826125405237963
1.63857615499787410
-1.23917152856907230
-0.74766075931809939
0.06904525622692098
-0.02590554346444064

... 이하 생략 ...





다른 언어로, 정규 분포 난수 구하기: ▶▶ 가우시안/가우스 랜덤/정규 분포 난수 구하기 함수 예제; C-자바-Perl-VBA; Gauss Random


일반 난수 구하는 법: ▶▶ C언어] 랜덤 숫자 (난수 정수) 출력 - Random Numbers rand srand 함수






업데이트:

이것은, 평균과 표준편차를 사용자 지정하여 난수를 구하도록 약간 수정한 소스입니다. 아래와 같습니다:

#include <stdio.h>
#include <math.h>
#include <Windows.h>

double gaussianRandom(double average, double stdev);


int main(void) {
  srand(GetTickCount());

  for (int i = 1; i <= 50; i++)
    // 평균은 -3.6 이고, 표준편차는 0.5 의 경우
    printf("%.17f\n", gaussianRandom(-3.6, 0.5));
  return 0;
}


double gaussianRandom(double average, double stdev) {
  double v1, v2, s, temp;

  do {
    v1 =  2 * ((double) rand() / RAND_MAX) - 1;      // -1.0 ~ 1.0 까지의 값
    v2 =  2 * ((double) rand() / RAND_MAX) - 1;      // -1.0 ~ 1.0 까지의 값
    s = v1 * v1 + v2 * v2;
  } while (s >= 1 || s == 0);

  s = sqrt( (-2 * log(s)) / s );

  temp = v1 * s;
  temp = (stdev * temp) + average;

  return temp;
}





tag: cpp
C언어 | C/C++ (Visual C++)

12 Comments:
At January 28, 2010 at 11:00 AM, Blogger Unknown said...

평균값과 표준편차값을 다르게 가져가고 싶으면 어느부분을 수정해야 하나요...잠시 들여다 보고 있는데 잘 모르겠습니다...정규분포 난수 발생기 만드신거 보면 잘되더라구요...어디를 수정해야 할까요...예를들면 평균은 -3.6, 표준편차는 0.5 이렇게 하고싶거든요...

 
At January 28, 2010 at 12:10 PM, Blogger mwultong said...

말씀하신 기능을 추가한 소스를 방금 업로드했습니다. 원래의 게시물 끝부분에 업데이트 형식으로 붙여 놓았습니다. ^_^

 
At January 28, 2010 at 12:29 PM, Blogger Unknown said...

완전 감사합니다. 큰도움이 되었습니다. 수고하세요~!!!

 
At June 16, 2010 at 11:36 AM, Blogger kang said...

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

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

이것도 C/C++로 작성가능한가요??

고수님들 부탁좀 드리겠습니다.

 
At June 16, 2010 at 11:36 AM, Blogger kang said...

11

 
At June 16, 2010 at 11:53 AM, Blogger mwultong said...

평균 구하기 함수

표준편차 구하기 함수

표준편차 = 분산의 제곱근
분산 = 표준편차의 제곱

따라서 표준편차 구하기 함수만 있으면 될 것 같군요 ^_^

 
At August 31, 2010 at 9:41 PM, Blogger Unknown said...

혹시 최소값을 정해서 그 이상의 수로만 가우시안 분포 구할 수 있을까요?
예를 들자면...
double Gausian(double ave, double std, double min)

 
At August 31, 2010 at 11:16 PM, Blogger mwultong said...

함수의 반환값이 최소값보다 작을 때는, 다시 구하는 루프를 만들면 될 것 같군요..

 
At April 28, 2012 at 2:55 PM, Blogger Jack Kim said...

혹시 평균을 입력하면 그에따른 포아송 분포를 만족하는 수들을 출력하는 함수도 구현해 주실 수 있나요??ㅠㅠ

 
At April 28, 2012 at 3:18 PM, Blogger mwultong said...

포아송 분포는 잘 모르겠군요 *^_^*
다만 C소스는 영문판 구글에 있습니다.

구글에서 푸아송 분포(포아송 분포) 소스 찾기

 
At March 8, 2017 at 5:18 PM, Blogger Unknown said...

코딩에서

s = sqrt( (-2 * log(s)) / s );

return v1 * s;

왜 이렇게 들어가는지 알고싶습니다!

 
At March 8, 2017 at 7:31 PM, Blogger mwultong said...

제가 만든 코드가 아니고요, "Marsaglia Polar Method"라는 것인데,
"Marsaglia and Bray"의 "A Convenient Method for Generating Normal Variables (1964년)"라는 책 혹은 논문에 있는 함수입니다.

수학적인 수식은 아래의 위키백과 영문판에 있습니다:

https://en.wikipedia.org/wiki/Marsaglia_polar_method

 

<< Home RSS 2.0 feed

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