目录
【建模算法】蒙特卡罗模拟法
01 算法用途
蒙特卡罗(Monte Carlo)方法,也称为随机模拟(random simulation)。
基本思想:为了解决数学、物理、工程技术等方面的问题,首先建立一个概率模型或随机过程,使它的参数等于问题的解;然后通过对模型或过程的观察或抽样试验来计算所求参数的统计特征,最后给出所求解的近似值。
02 实例分析
本文将以简单案例的形式介绍蒙特卡罗的用法
-
模拟寻求近似圆周率
-
用蒙特卡罗法估算定积分
03 模拟求近似圆周率
绘制单位圆和外接正方形,正方形ABCD的面积为: ,圆的面积为:
,现在模拟产生在正方形ABCD中均匀分布的点n个,如果这n个点中有m个点在该圆内,则圆的面积与正方形ABCD的面积之比可近似为m/n;
即:
模拟图:
运行时间是: 14.61761s Python源码:
#模拟求近似圆周率
import numpy as np
from random import random
from time import perf_counter
import matplotlib.pyplot as plt
start=perf_counter() #计时开始
num=np.arange(0,20000,10) #抛点数序列
mypi=np.ones((1,len(num)))
mypi=mypi[0] #模拟值
for j in range(1,len(num)):
n=num[j]
m=0
for i in range(1,n+1):
if (-1+2*random())**2+(-1+2*random())**2<=1:
m=m+1 #统计落在圆内点数
mypi[j]=4*m/n
#作图
plt.figure(figsize=(18, 8))
plt.rcParams['font.sans-serif'] = 'SimHei' # 设置中文显示
plt.rcParams['axes.unicode_minus'] = False
plt.xlim(0, 2500)
plt.ylim(0, 4)
plt.plot(mypi)
plt.plot([0,len(num)*1.1],[np.pi,np.pi],color='r')
plt.text(0,np.pi,'${\pi}$',color='r',fontsize=16)
plt.legend(['模拟π','实际π'])
plt.grid(visible='True') #在notebook里需要添加此句
plt.grid(linestyle=":", color="r")
plt.show()
print("运行时间是: {:.5f}s".format(perf_counter()-start))
04用蒙特卡罗法估算定积分
利用蒙特卡洛原理求: 的定积分
思想:对于 ,如果f(x)>0 ,则可以通过模拟的方法计算其定积分.
构造一个矩形包含了曲边梯形d>max(a,b),产生n(足够大)个在矩形区域内的点,如果落在由函数f(x)构成的曲边梯形内的点为m个,则所求定积分为:
模拟图:
运行时间是: 5.82076s
Python源码:
import numpy as np
from random import random
from time import perf_counter
import matplotlib.pyplot as plt
start=perf_counter() #计时开始
num=np.arange(0,10**5,500) #抛点数序列
s=np.ones((1,len(num)))
s=s[0] #模拟值
for j in range(1,len(num)):
n=num[j]
a,b=0,1
d=max(a,b)+1
m=0
for i in range(1,n+1):
x=a+random()*(b-a)
y=d*random()
if y<=x**2:
m=m+1
s[j]=m/n*d*(b-a)
#作图
plt.figure(figsize=(18, 8))
plt.rcParams['font.sans-serif'] = 'SimHei' # 设置中文显示
plt.rcParams['axes.unicode_minus'] = False
plt.xlim(0, 250)
plt.ylim(0, 0.4)
plt.plot(s)
plt.plot([0 ,len(num)*1.1],[1/3,1/3],color='r')
plt.text(0,1/3,'1/3',color='r',fontsize=16)
plt.legend(['模拟','实际1/3'])
plt.grid(visible='True') #在notebook里需要添加此句
plt.grid(linestyle=":", color="r")
plt.show()
print("运行时间是: {:.5f}s".format(perf_counter()-start))