使用蒙特卡洛法估算π值异常:迭代次数增加仍无法得到正确结果
蒙特卡洛法估算π值的代码错误分析与修正
问题根源
你的代码核心错误在于随机点的生成范围错误:
- 当前生成的
x和y是[0, 2]区间的随机数,对应边长为2、面积为4的正方形。 - 但判断条件
x² + y² ≤ 1仅覆盖该正方形中[0,1]×[0,1]的小区域(圆心在原点、半径1的四分之一圆),其面积为π/4。 - 此时点落在目标区域的概率为
(π/4)/4 = π/16,乘以4后得到的结果自然是π/4 ≈ 0.785,和你得到的0.8左右的结果一致。
修正方案
两种标准修正方式任选其一即可:
方式一:使用[0,1]区间的正方形(对应四分之一圆)
将随机数生成范围改为[0,1],此时正方形面积为1,四分之一圆面积为π/4,用4 * (inside/max_iteration)即可正确估算π:
#include <stdio.h> #include <stdlib.h> #include <time.h> double getRandomNumber(double lower_limit, double upper_limit){ double random = ((double)rand())/RAND_MAX; double range = (upper_limit - lower_limit) * random; return (range + lower_limit); } double calculatePi(int max_iteration){ int inside = 0; double x = 0; double y = 0; for(int i = 0; i < max_iteration; i++){ x = getRandomNumber(0, 1); // 修改为0到1区间 y = getRandomNumber(0, 1); // 修改为0到1区间 if(x*x + y*y <= 1){ inside++; } } return (4.0 * inside) / max_iteration; } int main(){ srand(time(NULL)); printf("Mean Value of 10000 Estimated Pi's = %lf\n", calculatePi(10000)); // 增加迭代次数提升精度 return 0; }
方式二:使用[-1,1]区间的正方形(对应完整圆)
将随机数生成范围改为[-1,1],此时正方形面积为4,完整圆面积为π,同样用4 * (inside/max_iteration)估算π:
#include <stdio.h> #include <stdlib.h> #include <time.h> double getRandomNumber(double lower_limit, double upper_limit){ double random = ((double)rand())/RAND_MAX; double range = (upper_limit - lower_limit) * random; return (range + lower_limit); } double calculatePi(int max_iteration){ int inside = 0; double x = 0; double y = 0; for(int i = 0; i < max_iteration; i++){ x = getRandomNumber(-1, 1); // 修改为-1到1区间 y = getRandomNumber(-1, 1); // 修改为-1到1区间 if(x*x + y*y <= 1){ inside++; } } return (4.0 * inside) / max_iteration; } int main(){ srand(time(NULL)); printf("Mean Value of 10000 Estimated Pi's = %lf\n", calculatePi(10000)); return 0; }
额外提示
- 迭代次数建议增加到10000以上,100次样本量太小,估算结果波动极大,很难接近真实π值。
- 变量
vector命名不够直观,改为distance_squared(距离平方)会更易读。
内容的提问来源于stack exchange,提问作者ello
相关产品推荐
相关产品推荐

