【发布时间】:2017-10-28 16:31:37
【问题描述】:
我正在写一个小程序来逼近高斯函数f(x) = exp(-x^2/2)的定积分,我的代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double gaussian(double x) {
return exp((-pow(x,2))/2);
}
int main(void) {
srand(0);
double valIntegral, yReal = 0, xRand, yRand, yBound;
int xMin, xMax, numTrials, countY = 0;
do {
printf("Please enter the number of trials (n): ");
scanf("%d", &numTrials);
if (numTrials < 1) {
printf("Exiting.\n");
return 0;
}
printf("Enter the interval of integration (a b): ");
scanf("%d %d", &xMin, &xMax);
while (xMin > xMax) { //keeps looping until a valid interval is entered
printf("Invalid interval!\n");
printf("Enter the interval of integration (a b): ");
scanf("%d %d", &xMin, &xMax);
}
//check real y upper bound
if (gaussian((double)xMax) > gaussian((double)xMin))
yBound = gaussian((double)xMax);
else
yBound = gaussian((double)xMin);
for (int i = 0; i < numTrials; i++) {
xRand = (rand()% ((xMax-xMin)*1000 + 1))/1000.00 + xMin; //generate random x value between xMin and xMax to 3 decimal places
yRand = (rand()% (int)(yBound*1000 + 1))/1000.00; //generate random y value between 0 and yBound to 3 decimal places
yReal = gaussian(xRand);
if (yRand < yReal)
countY++;
}
valIntegral = (xMax-xMin)*((double)countY/numTrials);
printf("Integral of exp(-x^2/2) on [%.3lf, %.3lf] with n = %d trials is: %.3lf\n\n", (double)xMin, (double)xMax, numTrials, valIntegral);
countY = 0; //reset countY to 0 for the next run
} while (numTrials >= 1);
return 0;
}
但是,我的代码输出与解决方案不匹配。我尝试调试并打印出 100 次试验的所有 xRand、yRand 和 yReal 值(并使用 Matlab 使用特定 xRand 值检查 yReal 值,以防我有任何拼写错误),并且这些值似乎没有超出范围无论如何...我不知道我的错误在哪里。
[0, 1] 上 # of trial = 100 的正确输出是 0.810,而我的是 0.880; [-1, 0] 上 # of trial = 50 的正确输出为 0.900,而我的为 0.940。谁能找到我做错的地方?非常感谢。
另一个问题是,我找不到使用以下代码的参考:
double randomNumber = rand() / (double) RAND MAX;
但是是导师提供的,他说会生成一个从0到1的随机数。为什么"rand()"后面用'/'而不是'%'?
【问题讨论】:
-
rand()是一个糟糕的随机数生成器,您可能希望添加一个选项以使用不同的种子选项运行试验到srand()。还使用:rand() % ...对随机值引入了偏差。考虑使用常规骰子从1..4和dice() % 4 + 1中查找值。您不会得到随机分布 -2和3会更频繁地出现。
标签: c random integration montecarlo