蒙特卡罗使用C找到pi的方法

问题描述 投票:5回答:4

我编写了一个函数,它接受一个很长的值n并将其用作迭代次数。该函数应该给出一个很好的pi估计值,然而,大n的所有值都趋向于3.000,而不是3.1415,所以我不确定发生了什么?

有什么我做错了吗?

这是我的代码:

double estimate_pi(long long n){
    double randomx, randomy, equation, pi;
    long long i, incircle = 0;

    for(i = 0; i < n; i++){
        randomx = (double)(rand() % (1+1-0) + 0);
        randomy = (double)(rand() % (1+1-0) + 0);

        equation = randomx * randomx + randomy * randomy;

        if(equation <= 1){
            incircle++;
        }
    }

    pi = (long double)4 * (long double)incircle / (long double)n;

    return pi;
}

在main函数中,打印10个pi的值:

int main(void){

    long long N;
    double pi_approx;
    int i;

    printf("Input a value of N: ");
    if(scanf("%ld", &N) != 1){
        printf("Error, input must be an integer!\n");
        exit(EXIT_SUCCESS);
    } 
    if(N < 1){
        printf("Error, the integer must be positive!\n");
        exit(EXIT_SUCCESS); 
    }

    srand(time(NULL));
    for(i = 0; i < 10; i++){
        pi_approx = estimate_pi(N);
        printf("%.10f\n", pi_approx);
    }
    return 0;
}
c montecarlo pi
4个回答
5
投票

您需要使用浮点随机化,否则使用半径非常大的圆。

而不是

    randomx = (double)(rand() % (1+1-0) + 0);
    randomy = (double)(rand() % (1+1-0) + 0);

你用

    randomx = rand();
    randomy = rand();

并考虑它是否落在半径为RAND_MAX的圆内

   #define RMAX ((double)RAND_MAX*(double)RAND_MAX)
   equation <= RMAX;

你做的细节。阅读man 3 rand以查看rand()返回整数。


6
投票

它的工作原理应该如此。问题是实施。

C rand()函数returns an integer在0到RAND_MAX的范围内。关键字有整数。

然后计算整数模2的结果,可以是0或1.这将为您留下4个可能的点:(0,0),(0,1),(1,0),(1,1)。

在这4个点中,只有1个位于半径1的圆外:(1,1)。也就是说,在4个可能的点中,3个位于圆圈中。

您应该替换该代码以使用浮点值而不是整数,因此您可以计算圆内外的点的比例。


3
投票

您的randomxrandomy变量被约束为整数值,因为rand()函数返回一个整数。

现场直播here

因此,你的两个变量中的每一个都是1或0,所以你的点将是(0,0),(1,0),(0,1),(1,1)中的一个,它有一个3:4进入圈子的可能性。因此你的结果是3。

如果你想要一个0到1之间的随机数,你可以查找How to generate random float number in C


2
投票

对于您的工作方法,您需要生成在区间[0,1](或大致如此)上从均匀分布绘制的double值。而是生成从双元素集{0,1}中绘制的随机整数,并将它们转换为类型double。这不会产生任何远程,就像您为了您的目的所需的分发。

© www.soinside.com 2019 - 2024. All rights reserved.