2013-05-08 59 views
0

我试图生成使用蒙特卡洛方法从一个正态分布值,按照该网站http://math60082.blogspot.ca/2013/03/c-coding-random-numbers-and-monte-carlo.html没有足够的随机蒙特卡罗

我修改了代码从原来的一个位,所以它计算出方差和平均对于直接生成的数字来检查方法是否正在工作,而不是单独进行测试(同样的差异真的,但只是一个正面)。

问题不管我做什么

,方差为远高于1,平均不为零。是否有可能产生的伪随机数不够随机?

代码

请注意,上面给出的网站的作者是人谁写的代码

#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++。) – 2013-05-08 00:41:28

+0

@HotLicks:我不知道你在哪里阅读,但这是一个非常不稳定的说法。生成正态分布形成一个统一的分布是相当普遍的(http://en.wikipedia.org/wiki/Marsaglia_polar_method)[thing](http://en.wikipedia.org/wiki/Box%E2%80 %93Muller_transform)。 *然而*,使用一个可怜的统一生成器(比如'rand()')会导致很差的正态分布。 – 2013-05-08 00:42:52

+0

@HotLicks注意到,显然是我这样做的朋友,希望它成为蒙特卡洛方法。 – 2013-05-08 00:44:19

回答

3

您似乎以错误的方式计算了meanmean应该在N之间进行平均,而您只能求和所有数组元素。目前mean实际上是sum

mean = mean /N 
+0

感谢您指出了这一点.B方差仍然没有接近1. – 2013-05-08 00:38:04

+2

@nerorevenge您可能会尝试生成超过2000个rand数并查看方差是否接近1?rand()可能不是一个好的随机数生成器(只是我疯狂的猜测)。 – taocp 2013-05-08 00:40:38

+1

@nerorevenge:你错了。平均值的不正确值会影响方差的值。修复平均值后,修复代码中的所有问题。 – carlosdc 2013-05-08 00:46:26

2

rand()是大多数实现中的质量非常低的随机数生成器。有些Linux版本会从内核熵池中获取价值,但不能保证跨平台(例如,在Windows上)使用Mersenne Twister。 Boost库实现了一个。

编辑:taocp答案突出显示了一个编码问题,但RNG问题仍然适用。

+0

注意到了,代码正在linux机器上运行,所以你的答案可能是正确的,让我给你gback。 – 2013-05-08 00:40:43

+0

Gback?无论如何,并不是所有的Linux libc都使用熵池。我无法分辨哪些是做什么,哪些不做,但我非常确定'rand'对于在PC上播放“猜测我的号码”非常有用,而不是进行统计分析或密码学。 – 2013-05-08 00:45:08

+1

如果您使用的是最新版本的gcc,则不需要增加此功能。 ''现在具有所有这些功能。 – Yuushi 2013-05-08 02:20:19