蒙特·卡罗方法(Monte Carlo method),也称统计模拟方法,是二十世纪四十年代中期由于科学技术的发展和电子计算机的发明,而被提出的一种以概率统计理论为指导的一类非常重要的数值计算方法。是指使用随机数(或更常见的伪随机数)来解决很多计算问题的方法。与它对应的是确定性算法。蒙特·卡罗方法在金融工程学,宏观经济学,计算物理学(如粒子输运计算、量子热力学计算、空气动力学计算)等领域应用广泛。
MC方法通过随机模拟来解决问题,先想象一个圆心为(0.5,0.5),半径为0.5的圆,面积为π/4,设为S1,还有一个外切的正方形,面积为1,设为S2,现向正方形内随机掷点,假设掷点总数为N,其中落入圆内部的点的总数为M,那么落入圆内的概率为M/N。由几何概型,点落入圆内部的概率为S1/S2,那么由M/N=S1/S2即可推出π=4M/N。
首先模拟生成在正方形区域的随机点
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
def get_random_points(N):
np.random.seed(42)
random_points = np.random.rand(N, 2)
return random_points
这里的 np.random.seed(42) 是一个随机数种子,接下来定义一个估计圆周率的函数,分割为圆内和圆外两部分
# 计算pi的值,并将圆内外的点分开,方便做图
def cal_pi(random_points):
inCircle_points = [] # 圆内部点
outCircle_points = [] # 外部点(以及边上的点)
for point in random_points:
x = point[0]
y = point[1]
if (x - 0.5) ** 2 + (y - 0.5) ** 2 < 0.25:
inCircle_points.append([x, y])
else:
outCircle_points.append([x, y])
ratio = len(inCircle_points) / len(random_points)
pi = 4 * ratio
return pi, inCircle_points, outCircle_points
最后计算出估计值并进行可视化
def plot_data(random_points):
pi_estimation, inCircle_points, outCircle_points = cal_pi(random_points)
print('估计的pi值为:', pi_estimation)
fig1 = plt.figure()
# 绘制圆的轮廓
ax1 = fig1.add_subplot(111, aspect='equal')
ax1.add_patch(
patches.Circle((0.5, 0.5), 0.5, fill=False, lw=2))
# 绘制圆内外的点
ax1.plot(np.array(inCircle_points)[:, 0], np.array(inCircle_points)[:, 1],
'go', alpha=0.3, markersize=0.5)
ax1.plot(np.array(outCircle_points)[:, 0], np.array(outCircle_points)[:, 1], 'ro', alpha=0.3, markersize=0.5)
plt.axis([0, 1, 0, 1]) # 座标轴范围约束
plt.title('$\pi\\approx' + str(pi_estimation) + '$')
plt.show()
选取N为30000进行测试
if __name__ == '__main__':
N = 30000
random_points = get_random_points(N)
plot_data(random_points)
运行结果及效果图如下
估计的pi值为: 3.1470666666666665