实验目的:
深入理解蒙特卡洛随机模拟算法
掌握使用蒙特卡洛算法编程计算pi
实验内容:
- 熟悉蒙特卡洛随机模拟算法
- 掌握蒙特卡洛算法进行pi的计算
- 分析随机点的多少对模拟值的影响
实验原理及算法:
蒙特卡洛方法,或称计算机随机模拟算法,是一种基于“随机数”的计算方法。利用事件的“频率”来近似事件的“概率”,再利用计算机进行大量迅速的事件模拟。根据圆面积公式S=pi*R^2,当R=1时,S=pi。由于圆的方程是:x^2+y^2=1,因此1/4圆面积为x轴、y轴和上述方程所包围的部分。如果在1*1的正方形中均匀地落入随机点,则落入1/4圆中的点的概率就是1/4圆的面积,其四倍就是圆面积。由于半径为1,该面积的值为pi的值。
实验环境:
python3.9 matplotlib3.6.2 pycharm64
实验参考代码:
## 函数get_one_pi:利用蒙特卡洛方法获得一个pi值
## num_of_position:随机点的个数 show:是否展示图形
## return:计算得到的pi值
def get_one_pi(num_of_position,show):
M = 0
for i in range(num_of_position):
x,y=random.random(), random.random()
if math.sqrt(pow(x, 2) + pow(y, 2))<=1:
M+=1
if show:
plt.scatter(x, y, color='red',s=10)
if show:
x = np.arange(0, 1, 0.0001)
y = np.sqrt(1 - x ** 2)
plt.xlim(0, 1)
plt.ylim(0, 1)
plt.plot(x, y)
plt.show()
result = 4 * M / num_of_position
return result
## 函数get_pi:重复进行预测pi
## num_of_position:随机点的个数 num_of_times:重复预测次数
## return:pi预测的平均值与预测方差
def get_pi(num_of_position, num_of_times):
l_ = []
for i in range(num_of_times):
l_.append(get_one_pi(num_of_position,False))
return sum(l_) / len(l_),np.var(l_)
## 绘制随机点的个数与预测误差与预测方差图形 1-1000
ls_error,ls_var=[],[]
for i in range(1000):
print(i)
result = get_pi(i+1, 100)
ls_error.append(abs(np.pi-result[0]))
ls_var.append(result[1])
plt.plot(range(1000), ls_error, label='error')
plt.show()
plt.plot(range(1000), ls_var, label='var')
plt.show()
## 绘制随机点的个数与预测误差与预测方差图形 1000-2000
ls_error,ls_var=[],[]
for i in range(1000,2000,1):
print(i)
result = get_pi(i, 100)
ls_error.append(abs(np.pi-result[0]))
ls_var.append(result[1])
plt.plot(range(1000,2000,1), ls_error, label='error')
plt.show()
plt.plot(range(1000,2000,1), ls_var, label='var')
plt.show()
结果分析:
图形如下:
模拟误差与模拟值的关系:
在一定范围内(模拟值很小时),模拟值越大,模拟误差越小,预测值越准确。
当模拟值很大时,由于随机函数的伪随机性质,模拟值的增加并不会使预测值进一步准确。
模拟方差与模拟值的关系:
模拟值越大,模拟方差越小,每次预测的值的差异越小。
当模拟值很大时, 模拟值越大,模拟方差也越小,每次预测的值的差异越小。但此时预测精度不会提高,证明了随机函数的伪随机性质,也说明随机点不是越多越好。