C - Monte Carlo 积分 - 随机数不随机且计数不计数?

C - Monte Carlo Integration - Randoms not random and count not counting?

注意,我是个 C 新手 :P

我想弄清楚为什么我的程序没有按预期 运行ning。

首先,假设 return x 和 y 值在 0.0 到 10.0 范围内,确实如此,但随机数不应该在每次 运行 后重置吗?每次我 运行 程序时,我都会得到相同的 X 和 Y 值。

其次,我的循环似乎没有做任何事情。计数根本没有增加,我不知道为什么 - 我假设这是固定的,我应该开始看到一些正确的结果。

#include <stdio.h>
#include <stdlib.h>

void throwDart(double *x, double *y)
{
    double min = 0.0, max = 10.0;

    *x = (max - min) * ((double)rand() / (RAND_MAX)) + min; //don't nec. need min - example format
    *y = (max - min) * ((double)rand() / (RAND_MAX)) + min; //^same
}

double Fun(double x)
{
    return ((0.3*x*x) - (0.2*x) - 5); //estimate value of definite integral using this function
}

int main()
{
    double x, y, P; //(x,y) is location, P is number of darts that hit below the curve/total thrown
    int N, e; //N is number of darts, e is area under curve
    int c = 0; //initialize count of darts that hit below the curve

    throwDart(&x, &y);

    printf("How many darts would you like to throw?\n");
    scanf("%d", &N);

    for (int i = 0; i < N; i++)
    {
        if (y <= Fun(x))        
        c++;    
    }

    P = c/N;
    e = 100.00 * P;

    //most of the following prints just to see what is and isn't working
    printf("X is %lf\n", x);
    printf("Y is %lf\n", y);
    printf("N is %d\n", N);
    printf("c is %d\n", c);
    printf("P is %d\n", P);
    printf("Area under the curve is %d\n", e);

    system("Pause");

}

random使用的算法是-随机。它取决于一个名为 seed 的值——如果您可以在每次程序启动时将其设置为不同的值,您将获得其他系列的随机数。默认情况下 seed 设置为 1,因此系列不会更改。比较流行的方法是使用自纪元以来的秒数作为种子:

srand(time(NULL));

srand 将伪随机生成器的种子更改为给定值,time returns 自纪元以来的时间(以秒为单位),因此它在每次调用时始终使用不同的系列该程序。 srand 应该只调用一次,最好是在 main 开始的某个地方(以确保为 rand 的第一次调用正确设置种子)。

至于你的循环问题 - 你永远不会在那里更改 xy 的值。您应该在每次迭代时调用 throwDart 以获得 xy:

的新值
for (int i = 0; i < N; i++)
{
    throwDart(&x, &y);
    if (y <= Fun(x))        
    c++;    
}

首先,您需要为随机数生成器设置种子。您可以通过在 main().

的顶部调用 sranddev() 来完成此操作

其次,xy 在循环的每次迭代中都保持相同的值,因此到程序结束时 c 将是 10 或 0。如果你为您的随机数生成器播种,您会看到这种情况发生。

随机数生成器并不是真正随机的,它们是所谓的伪随机,或 'fake' 随机,因为计算机不能只给出一个值,您需要给它一个种子值被插入算法以 return 返回一个看似随机的数字,通常可以完成工作

对于 C 和 C++,随机数生成器需要一个明确的种子值,如果你不给它一个,它只会每次都选择相同的值,因此你得到相同的 x 和每次都是。

所以每次程序运行你都需要给它一个不同的种子,最简单的方法是使用time.h文件

#import <time.h>

如前所述,每次调用随机数生成器时都为它播种

srand(time(NULL));

time 在这种情况下是自大约 20 年前时钟启动以来的秒数,因此如果您每秒多次调用 rand 函数,您将继续获得相同的数字,这将发生在for 循环,所以我建议改为这样做

srand(time(NULL) + i);

在循环中,所以每次调用 rand 时种子都会改变,你总是得到不同的数字