2013-05-08 1 views
0

는 내가 코드를 원본과 약간의 수정 된 웹 사이트 http://math60082.blogspot.ca/2013/03/c-coding-random-numbers-and-monte-carlo.html임의하지 몬테 카를로에 대한

에 따라이 분산을 계산하므로, 몬테카를로 방법을 사용하여 정규 분포의 값을 생성하기 위해 노력하고 의미하고 메소드가 별도로 테스트하지 않고 작동하는지 확인하기 위해 직접 생성 된 숫자 (동일한 차이가 있지만 실제로는 머리가 맞지 않음).

에 관계없이 내가하는 일의 질문, 분산은 위의 방법 1이고 평균이 0이 아닌. 생성 된 의사 난수가 충분히 랜덤하지 않을 수도 있습니까?

코드

위의 특정 웹 사이트의 저자는 사용자가 지적하는 코드

#include <cstdlib> 
#include <cmath> 
#include <ctime> 
#include <iostream> 
using namespace std; 
// return a uniformly distributed random number 
double uniformRandom() 
{ 
    return ((double)(rand()) + 1.)/((double)(RAND_MAX) + 1.); 
} 

// return a normally distributed random number 
double normalRandom() 
{ 
    double u1=uniformRandom(); 
    double u2=uniformRandom(); 
    return cos(8.*atan(1.)*u2)*sqrt(-2.*log(u1)); 
} 

int main() 
{ 
    double z; 
    int N=1000; 
    double array[N]; 
    double mean=0 ,variance=0; 
    srand(time(NULL)); 

    for(int i=0;i<N;i++) 
    { 
     z=normalRandom(); 
     cout << i << "->"<< z<< endl; 
     mean+=z; 
     array[i]=z; 
    } 

    mean=mean/N ; 
    cout << " mean = " << mean << endl; 

    for(int i=0;i<N;i++) 
    { 
     variance = variance + (mean - array[i])*(mean - array[i]); 
    } 
    variance = variance/N; 
    cout << " variance = " << variance << endl; 

    return 0; 
} 

UPDATE 분명히

을 작성한 사람이므로주의 해주십시오, 나는 어리석은 실수로 프로그램이 작동하지 않고 망쳐 버렸습니다.

+0

내가 균일 한 랜덤에서 무작위로 정규 분포를 생성하는 일반적으로 특히 정확하지 않은 것을 과거에 읽은 - 더는 정규 분포 RNG를 사용합니다. (정확히 어디에서 하나를 찾을 지 모르겠지만, C++에 대해서는 모른다.) –

+0

@HotLicks : 내가 읽은 곳을 모르지만, 그것은 매우 불안정하다. 정규 분포가 정규 분포를 이루는 것은 꽤 일반적입니다 (http://en.wikipedia.org/wiki/Marsaglia_polar_method) [thing] (http://en.wikipedia.org/wiki/Box%E2%80) % 93Muller_transform). * 그러나 *, (rand()와 같이) 불규칙한 uniform generator를 사용하면 정규 분포가 좋지 않습니다. –

+0

@HotLicks Noted, 분명히 내가 이것을하고있는 친구는 그것이 몬테 카를로 방법이되기를 바란다. –

답변

3

mean이 잘못 계산 된 것 같습니다. meanN을 평균해야하며 모든 배열 요소에 대해서만 합산해야합니다. 현재 mean은 실제로 sum입니다.

mean = mean /N 
+0

그 점을 지적 해 주셔서 고맙습니다. 분산이 아직 1 근처에 있지 않습니다. –

+2

@nerorevenge 2000 이상의 rand 번호를 생성하고 분산이 1에 가까워 지는지 확인할 수 있습니까?rand() 좋은 난수 생성기 (내 야생 추측) 않을 수 있습니다. – taocp

+1

@nerorevenge : 틀렸어. 잘못된 평균 값은 분산 값에 영향을줍니다. 평균값을 수정하면 코드의 모든 문제가 해결됩니다. – carlosdc

2

rand()은 대부분의 구현에서 매우 낮은 품질의 난수 생성기입니다. 일부 Linux 버전은 커널 엔트로피 풀에서 가치를 얻을 수 있지만 플랫폼 (예 : Windows)에서 보장되지는 않습니다. 대신 Mersenne Twister를 사용하십시오. Boost 라이브러리는이를 구현합니다.

EDIT : taocp answer는 코딩 문제를 강조 표시하지만 RNG 문제는 계속 적용됩니다.

+0

Noted, 코드가 리눅스 컴퓨터에서 실행되고 있으므로 귀하의 답이 맞을 수도 있습니다. –

+0

Gback? 어쨌든 모든 리눅스 libc가 실제로 엔트로피 풀을 사용하는 것은 아닙니다. 나는 무엇을하고 어떤 것을하지 못하는지를 말할 수는 없지만,'랜드 (rand) '는 통계 분석이나 암호 작성을 위해서가 아니라 PC에 대해 "내 번호를 추측 해"놀기에 좋다. –

+1

gcc의 최신 버전을 사용하고 있다면이 기능을 향상시킬 필요가 없습니다. 이제 ''에이 모든 기능이 포함됩니다. – Yuushi

관련 문제