C - 蒙特卡洛积分 - Randoms不是随机的,数不算数?

时间:2015-02-28 01:36:25

标签: c random integration

抬头,我是一个C新手:P

我试图找出为什么我的程序没有按预期运行。

首先,它应该返回0.0到10.0范围内的x和y值,但是每次运行后都不应该重置randoms吗?我每次运行程序时都得到相同的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");

}

3 个答案:

答案 0 :(得分:1)

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

srand(time(NULL));

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

关于您的循环问题 - 您永远不会更改xy的值。您应该在每次迭代时调用throwDart以获取xy的新值:

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

答案 1 :(得分:0)

首先,您需要为随机数生成器播种。您可以通过调用sranddev()顶部的main()来完成此操作。

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

答案 2 :(得分:0)

随机数生成器不是真正随机的,它们被称为伪随机数,或者假冒&#39;随机的,因为一台计算机不能提出一个值,你需要给它一个种子值,这个值可以用来返回一个看似随机的数字,通常可以完成工作

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

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

#import <time.h>

正如所说的更远,每次调用它时随机数生成器播种

srand(time(NULL));

这种情况下的时间是自20年前启动时钟以来的秒数,所以如果你每秒调用一次rand函数,你将继续获得相同的数字,这将在for循环中发生,所以我建议改为

srand(time(NULL) + i);

在循环内部,因此每次调用rand时种子都会更改,并且您总是得到不同的数字