You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

蒙特卡洛法估算圆周率π时重复次数上升σ异常升高问题求助

蒙特卡洛法估算π的异常结果排查

问题背景

我正在使用Python完成习题3.1,题目如下:
题目图示

实现代码

我编写的可正常运行的代码如下:

#NUMERICAL ESTIMATE OF PI
import numpy as np               # 数值计算库
import matplotlib.pyplot as plt  # 绘图库
from scipy.stats import norm     # 高斯拟合依赖库
  
#*******************************************************************************
M = 10**2                               # 估算π的重复次数
N = 10**4                               # 单次估算生成的随机点数量
mean_pi=[]                              # 存储每次估算π值的空列表
for i in range(M):
    x=np.random.uniform(-1,1,N)         # 生成[-1,1)区间均匀分布的x坐标数组
    y=np.random.uniform(-1,1,N)         # 生成[-1,1)区间均匀分布的y坐标数组
    x_sel=x[(x**2+y**2)<=1]             # 筛选落在单位圆内的x坐标
    y_sel=y[(x**2+y**2)<=1]             # 筛选落在单位圆内的y坐标
    mean_pi+=[4*len(x_sel)/len(x)]      # 计算本次估算的π值存入列表
#*******************************************************************************
plt.figure(figsize=(8,3))
# 绘制直方图,将分箱范围存入bins变量
_,bins,_=plt.hist(mean_pi,bins=int(np.sqrt(N)),density=True, color="skyblue")
mu, sigma = norm.fit(mean_pi)                                     # 拟合得到数据的均值和标准差
k = sigma*np.sqrt(N)                                              # 计算k参数
best_fit_line = norm.pdf(bins, mu, sigma)                         # 生成拟合曲线数据
print("\nTime of repetitions:", M, ". The mean of the distribution is: ", mu, ". The standard deviation is:", sigma, ". The k parameters is:", k ,". \n")
#*******************************************************************************
plt.plot(bins, best_fit_line, color="red")
plt.grid()
plt.xlabel('Bins',fontweight='bold')
plt.ylabel('Pi',fontweight='bold')
plt.title("Histogram for Pi vs. bins")
plt.show()
print("\n")
#*******************************************************************************
M = 10**3                               # 调整重复次数为1000
N = 10**4                               # 单次随机点数量保持不变
mean_pi=[]
for i in range(M):
    x=np.random.uniform(-1,1,N)
    y=np.random.uniform(-1,1,N)
    x_sel=x[(x**2+y**2)<=1]
    y_sel=y[(x**2+y**2)<=1]
    mean_pi+=[4*len(x_sel)/len(x)]
#*******************************************************************************
plt.figure(figsize=(8,3))
_,bins,_=plt.hist(mean_pi,bins=int(np.sqrt(N)),density=True, color="skyblue")
mu, sigma = norm.fit(mean_pi)
k = sigma*np.sqrt(N)
best_fit_line = norm.pdf(bins, mu, sigma)
print("Time of repetitions:", M, ". The mean of the distribution is: ", mu, ". The standard deviation is:", sigma, ". The k parameters is:", k ,". \n")
#*******************************************************************************
plt.plot(bins, best_fit_line, color="red")
plt.grid()
plt.xlabel('Bins',fontweight='bold')
plt.ylabel('Pi',fontweight='bold')
plt.title("Histogram for Pi vs. bins")
plt.show()
print("\n")
#*******************************************************************************
M = 5*10**3                             # 调整重复次数为5000
N = 10**4                               # 单次随机点数量保持不变
mean_pi=[]
for i in range(M):
    x=np.random.uniform(-1,1,N)
    y=np.random.uniform(-1,1,N)
    x_sel=x[(x**2+y**2)<=1]
    y_sel=y[(x**2+y**2)<=1]
    mean_pi+=[4*len(x_sel)/len(x)]
#*******************************************************************************
plt.figure(figsize=(8,3))
_,bins,_=plt.hist(mean_pi,bins=int(np.sqrt(N)),density=True, color="skyblue")
mu, sigma = norm.fit(mean_pi)
k = sigma*np.sqrt(N)
best_fit_line = norm.pdf(bins, mu, sigma)
print("Time of repetitions:", M, ". The mean of the distribution is: ", mu, ". The standard deviation is:", sigma, ". The k parameters is:", k ,". \n")
#*******************************************************************************
plt.plot(bins, best_fit_line, color="red")
plt.grid()
plt.xlabel('Bins',fontweight='bold')
plt.ylabel('Pi',fontweight='bold')
plt.title("Histogram for Pi vs. bins")
plt.show()
#*******************************************************************************
print("\n How many couples N you need to estimate pi at better than 0.0001? The number of couples N is:", (k**2)*10**8 ,".")
#*******************************************************************************

运行结果

运行输出结果如下图:
运行输出图示

问题描述

运行结果和预期不符:随着估算π的重复次数M从100提升到1000、5000,拟合得到的π值分布标准差σ反而上升,按照预期重复次数越多σ应该越小。尝试增大单次运行生成的随机点数量N,结果也没有改善,需要排查错误原因。

排查结论

  • 核心问题是统计概念混淆:你计算的σ是单次π估算值的分布标准差,这个值的理论值仅和单次估算的随机点数量N有关,和重复次数M没有关系。对于蒙特卡洛估算π的场景,单次估算的标准差理论值约为$\frac{1.64}{\sqrt{N}}$,当N固定为1e4时,这个值约为0.0164。你观测到的σ随M增大轻微上升只是小样本下的统计波动,当M足够大时,你计算得到的σ会收敛到这个固定的理论值,而不会下降。
  • 你预期会随M增大下降的是M次估算结果均值的标准差(标准误),这个值的计算公式是$\frac{\sigma}{\sqrt{M}}$,确实会随M增大而减小,但它和你当前计算的单次分布标准差σ不是同一个统计量。
  • 代码本身的计算逻辑没有问题,你可以尝试计算每组M次实验得到的mean_pi的均值,会发现这个均值的波动随M增大明显变小,符合你最初的预期。

内容的提问来源于stack exchange,提问作者J.Snowden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 00:00:01