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
的第一次调用正确设置种子)。
至于你的循环问题 - 你永远不会在那里更改 x
或 y
的值。您应该在每次迭代时调用 throwDart
以获得 x
和 y
:
的新值
for (int i = 0; i < N; i++)
{
throwDart(&x, &y);
if (y <= Fun(x))
c++;
}
首先,您需要为随机数生成器设置种子。您可以通过在 main()
.
的顶部调用 sranddev()
来完成此操作
其次,x
和 y
在循环的每次迭代中都保持相同的值,因此到程序结束时 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 时种子都会改变,你总是得到不同的数字
注意,我是个 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
的第一次调用正确设置种子)。
至于你的循环问题 - 你永远不会在那里更改 x
或 y
的值。您应该在每次迭代时调用 throwDart
以获得 x
和 y
:
for (int i = 0; i < N; i++)
{
throwDart(&x, &y);
if (y <= Fun(x))
c++;
}
首先,您需要为随机数生成器设置种子。您可以通过在 main()
.
sranddev()
来完成此操作
其次,x
和 y
在循环的每次迭代中都保持相同的值,因此到程序结束时 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 时种子都会改变,你总是得到不同的数字