python实现蒙特卡洛模拟_随机模拟——蒙特卡洛算法及Python实现

随机模拟——蒙特卡洛算法及Python实现

irony • 2020 年 04 月 24 日

蒙特卡洛算法介绍蒙特卡洛算法(Monte Carlo method)也称统计模拟算法,是一种以概率统计理论为指导的数值计算方法方法。是指使用随机数来解决很多计算问题的方法。

蒙特卡洛方法基本思想

通常蒙特卡洛算法可以分为两种:

1,一种是所求解的问题本身具有内在随机性,借助计算机的运算能力可以直接模拟这种随机的过程。

2,另一种是所求解的问题可以转化为某种随机分布的特征数,比如随机事件出现的概率,或者随机变量的期望值。通过随机抽样的方法,以随机事件出现的频率估计其概率,或者以抽样的数字特征估算随机变量的数字特征,并将其作为问题的解。这种方法多用于求解复杂的多维积分的问题。

蒙特卡洛方法的理论依据是大数定理,即重复试验多次,随机事件的频率近似于它的概率。

论文中利用蒙特卡洛法求定积分

蒙特卡洛一个重要的应用就是求定积分,例子如下:

假设曲线函数为$f(x)$,则易得阴影部分面积:

$$ \int_{a}^{b} f(x)\, dx $$

然后通过牛顿莱布尼兹公式进行积分求解,而蒙特卡洛算法则运用不同的思想。当我们在$[a,b]$之间随机取一点$x$时,它对应的函数值就是$f(x)$。接下来我们就可以用$f(x) * (b-a)$来估计曲线下方的面积,也就是积分值,但是很显然这种估计方式是非常粗略的。

在上图中,做了四次随机采样,得到了四个随机样本$x_1,x_2,x_3,x_4$,并且得到了这四个样本的$f(x_i)$的值分别为$f(x_1),f(x_2),f(x_3),f(x_4)$。对于这四个样本,每个样本都可求取一个近似的面积值,大小为$f(x_i)*(b-a)$。然后求取所有面积的平均值就完成了蒙特卡洛求积分的过程。

用以下公式表述上述过程:

$$

\begin{array}{lcr}

S = \frac{1}{4}(b-a)(f(x_1)+f(x_2)+f(x_3)+f(x_4))\\

\quad = \frac{1}{4}(b-a)\sum_{i=1}^4 f(x_i)

\end{array}

$$

蒙特卡洛Python实现

1,求取圆周率$\pi$

代码如下:import random

def cal_pai():

n = 1000000

r = 1

a, b = (0, 0)

# 求投点的上下界

x_low, x_up = a - r, a + r

y_low, y_up = b - r, b + r

# 记录落于圆内的点数

count = 0

for i in range(0, n):

x = random.uniform(x_low, x_up)

y = random.uniform(y_low, y_up)

if x**2 + y**2 <= r**2:

count += 1

return (count / n) * 4

if __name__ == '__main__':

print(cal_pai())

简单介绍一下算法思路:利用投点法,在边长为2的正方形内部找到内接圆,内接圆的半径为1,所以易得内接圆于外接正方形的面积比为$\frac{\pi}{4}$。现在向正方形内部投点,并计算点与圆心的距离。其中$n$为投点的总数,$count$为投在圆内的投点个数,则$\pi$可以由以下格式求出:

$$ \pi = \frac{count}{n} * 4 $$

代码运行结果:$3.140748$,每次运行结果不同。依据大数定理,n越大,$\pi$值越准确。

2,求定积分$\int_{0}^{1} x^2\, dx$

代码如下:import random

def integral():

n = 1000000

x_min, x_max = 0, 1

S = 0

for i in range(0, n):

x = random.uniform(x_min, x_max)

y = x ** 2

S += (x_max - x_min) * y

return 1 / n * S

if __name__ == '__main__':

print(integral())

代码运行结果:$0.33371372617627443$

你可能感兴趣的:(python实现蒙特卡洛模拟)