蒙地卡羅方法

蒙特卡罗方法（），也称统计模拟方法，是1940年代中期由于科学技术的发展和电子计算机的发明，而提出的一种以概率统计理论为指导的数值计算方法。是指使用随机数（或更常见的伪随机数）来解决很多计算问题的方法。

20世纪40年代，在科學家冯·诺伊曼、斯塔尼斯拉夫·烏拉姆和尼古拉斯·梅特罗波利斯於洛斯阿拉莫斯国家实验室为核武器计划工作时，发明了蒙特卡罗方法。因为烏拉姆的叔叔经常在摩納哥的蒙特卡洛赌场输钱得名，而蒙特卡罗方法正是以概率为基础的方法。

与它对应的是确定性算法。

蒙特卡罗方法在金融工程学、宏观经济学、生物医学、计算物理学（如粒子输运计算、量子热力学计算、空气动力学计算）、机器学习等领域应用广泛。

基本概念
通常蒙特卡罗方法可以粗略地分成两类：一类是所求解的问题本身具有内在的随机性，借助计算机的运算能力可以直接模拟这种随机的过程。例如在核物理研究中，分析中子在反应堆中的传输过程。中子与原子核作用受到量子力学规律的制约，人们只能知道它们相互作用发生的概率，却无法准确获得中子与原子核作用时的位置以及裂变产生的新中子的行进速率和方向。科学家依据其概率进行随机抽样得到裂变位置、速度和方向，这样模拟大量中子的行为后，经过统计就能获得中子传输的范围，作为反应堆设计的依据。

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

假设我们要计算一个不规则图形的面积，那么图形的不规则程度和分析性计算（比如，积分）的复杂程度是成正比的。蒙特卡罗方法基于这样的想法：假設你有一袋豆子，把豆子均匀地朝这个图形上撒，然后数这个图形之中有多少颗豆子，这个豆子的数目就是图形的面积。当你的豆子越小，撒的越多的时候，结果就越精确。借助计算机程序可以生成大量均匀分布坐标点，然后统计出图形内的点数，透過它們占總點數的比例和坐标点生成范围的面积就可以求出图形面积。

工作过程
在解决实际问题的时候应用蒙特卡罗方法主要有两部分工作：
用蒙特卡罗方法模拟某一过程时，需要产生各种概率分布的随机变量。
用统计方法把模型的数字特征估计出来，从而得到实际问题的数值解。

分子模拟计算的步骤
使用蒙特卡罗方法进行分子模拟计算是按照以下步骤进行的：
使用随机数生成器产生一个随机的分子构型。
对此分子构型的其中粒子坐标做无规则的改变，产生一个新的分子构型。
计算新的分子构型的能量。
比较新的分子构型与改变前的分子构型的能量变化，判断是否接受该构型。
若新的分子构型能量低于原分子构型的能量，则接受新的构型，使用这个构型重复再做下一次迭代。
若新的分子构型能量高于原分子构型的能量，则計算玻尔兹曼因子，并产生一个随机数。
若这个随机数大于所计算出的玻尔兹曼因子，则放弃这个构型，重新计算。
若这个随机数小于所计算出的玻尔兹曼因子，则接受这个构型，使用这个构型重复再做下一次迭代。
如此进行迭代计算，直至最后搜索出低于所给能量条件的分子构型结束。

在数学中的应用
通常蒙特卡罗方法透過构造符合一定规则的随机数来解决数学上的各种问题。对于那些由于计算过于复杂而难以得到解析解或者根本没有解析解的问题，蒙特卡罗方法是一种有效的求出数值解的方法。一般蒙特卡罗方法在数学中最常见的应用就是蒙特卡罗积分。下面是蒙特卡罗方法的两个简单应用：

积分
非权重蒙特卡罗积分，也称确定性抽样，是对被积函数变量区间进行随机均匀抽样，然后对抽样点的函数值求平均，从而可以得到函数积分的近似值。此种方法的正确性是基于概率论的中心极限定理。当抽样点数为m时，使用此种方法所得近似解的统计误差只与m有关（与正相关），不随积分维数的改变而改变。因此当积分维度较高时，蒙特卡罗方法相对于其他数值解法更优。

圆周率
蒙特卡罗方法可用于近似计算圆周率：让计算机每次随机生成两个0到1之间的数，看以这两个实数为横纵坐标的点是否在单位圆内。生成一系列随机点，统计单位圆内的点数与总点数，（圓面積和正方形面積之比為PI:4，PI為圓周率），当随机点取得越多时，其结果越接近于圆周率（然而準確度仍有爭議：即使取10的9次方个随机点时，其结果也仅在前4位与圆周率吻合，以下Python程式碼可提供測試）。用蒙特卡罗方法近似计算圆周率的先天不足是：计算机产生的随机数是受到存储格式的限制的，是离散的，并不能产生连续的任意实数；上述做法将平面分割成一个个网格，在空间也不是连续的，由此计算出来的面积当然与圆或多或少有差距。
import numpy as np

# 生成10的9次方個隨機點
num_points = 10**9
points = np.random.rand(num_points, 2)

# 計算點到原點的距離
distances = np.sqrt(points[:,0]**2 + points[:,1]**2)

# 計算落在單位圓內的點的數量
points_inside_circle = np.sum(distances <= 1)

# 蒙地卡羅方法計算圓周率
pi_estimate = 4 * points_inside_circle / num_points

print(pi_estimate)

 在机器学习中的应用
蒙特卡洛方法也常用于机器学习，特别是强化学习的算法中。一般情况下，针对得到的样本数据集建立相对模糊的模型，透過蒙特卡洛方法对于模型中的参数进行选取，使之于原始数据的残差尽可能的小。从而达到建立模型拟合样本的目的。

 参见 

 遗传算法
 粒子濾波器
 拟蒙特卡罗方法
 布豐投針問題

 注释 

 参考 



Category:数值分析
Category:统计力学
Category:计算物理学
Category:抽样技术
Category:统计近似
Category:随机化模拟
Category:随机化算法
Category:风险分析方法