蒙特·卡罗方法(Monte Carlo method),也称统计模拟方法,是二十世纪四十年代中期由于科学技术的发展和电子计算机的发明,而被提出的一种以概率统计理论为指导的一类非常重要的数值计算方法。是指使用随机数(或更常见的伪随机数)来解决很多计算问题的方法。与它对应的是确定性算法。蒙特·卡罗方法在金融工程学,宏观经济学,计算物理学(如粒子输运计算、量子热力学计算、空气动力学计算)等领域应用广泛。
内容来源:蒙特卡罗算法百度百科
--------------------相关摘录:内容来源于网络----------------------
最简单的例子就是算,随机产生点集
,
,
蒙特卡罗也只是刚开始随机进行预测,但后面的每步迭代都有权重不同。
蒙特卡罗算法和蒙特卡罗方法有一些微妙的不同。本质上蒙特卡罗都指的是Monte Carlo,也就是一个很有名的大赌场,在概率论里边的意思近似等同于“随机”。下边简称为MC。
MC方法指的是用随机来计算一些确定性算法(deterministic algorithm)算起来麻烦/慢的东西。举一个例子,如果你要测量一只猫的体积,但是猫的表面那个曲线非常难以积分(...),而且这只猫高冷地拒绝了你想要把它泡到水里的请求,所以你选择了另一种途径:用一个能在空间中随机(uniformly)产生一种标志粒子的机器,让这个机器在一个包含了猫的正方体内随机产生粒子。假设粒子如果正好在猫的体内或者表皮(在数学上表皮体积为0所以你要去掉表皮也可以)的话,那么这个粒子就无法被观测到,否则就可以被观测到。假设正方体的体积为1立方米,而你在空间中产生了一万个点,最后观测到了9950个点,那么这只猫的体积就可以用这个MC算法测算为5立方分米。
当然了,除了测量猫的体积(?),MC方法还有很多其他的用途。一类非常常见的算法叫Markov Chain Monte Carlo(MCMC)。假设你要求一个概率分布的一些性质(比如均值,方差等等),但是这个概率分布没办法直接算,但是你可以构造一个Markov Chain,而这个Markov Chain的equilibrium distribution就是你想要算的那个概率分布。这时候,你只需要直接让这个Markov Chain跑一定的步数,然后进入equilibrium distribution,这时候你随机取一些作为样本,当抽取的数量足够的时候,就可以用这些样本来模拟最开始要算的概率分布,而你想要算的那些东西可以直接用样本分布来算。
计算机科学里边也有一类MC算法。很多用途广泛的算法是NP甚至复杂度更高的,这时候你想要算出一个确定性的解的话,需要的计算量非常的大,常常超出了你导师/上司能容忍的范围(...),有一些情况下,比如一些算一个数字是不是质数,或者是一些其他的决策问题,就可以用一个MC算法,用少很多的计算时间,来得到一个正确概率足够大(比如90%多一些,但是严格小于1)的解。
-
import numpy as np
-
import matplotlib.pyplot as plt
-
import matplotlib.patches as mpatches
-
import scipy.integrate as integrate
-
-
'''''
-
Monte Carlo method (蒙特卡洛方法,也有翻译成“蒙特卡罗方法”)是以概率和统计的理论、方法为基础的一种数值计算方法,
-
将所求解的问题同一定的概率模型相联系,用计算机实现统计模拟或抽样,以获得问题的近似解,故又称随机抽样法或统计试验法。
-
上述就是蒙特卡洛方法的基本概念,比较抽象,下面结合实际工作中的理解,谈一谈对蒙特卡洛方法的一些认识。
-
-
(1)数学家冯·诺伊曼(计算机之父)在20世纪40年代中期用驰名世界的赌城摩纳哥的蒙特卡洛来命名这种方法,
-
说明该方法与赌博中的随机性、概率性有着天然而密切的联系。几乎涉及到概率相关的复杂数值计算的领域(计算物理、经济金融、统计学、机器学习等)。
-
-
(2)蒙特卡洛是一种方法或者说策略,没有什么高深的理论支撑(如果有理论也就只有概率论或统计学中的大数定律了)。
-
蒙特卡洛的基本原理简单描述是先大量模拟,然后计算一个事件发生的次数,再通过这个发生次数除以总模拟次数,得到想要的结果。
-
例如模拟投N次(随机样本数),统计同时出现6的次数C(C/N即是计算结果)。
-
-
(3)蒙特卡洛方法可应用在很多场合(求的是近似解)。模拟样本数越大,越接近与真实值,同时样本数增加会带来计算量的大幅上升。
-
-
实例:蒙特卡洛方法求函数y=x^2在[0,2]区间的积分(即求面积)。
-
备注:直接用数学中的定积分公式算更简单精确。
-
该红色区域在一个2×4的正方形里面。使用蒙特卡洛方法,随机在这个正方形里面产生大量随机点(数量为N),
-
计算有多少点(数量为count)落在红色区域内(判断条件为y<x2),count/N就是所要求的积分值,也即红色区域的面积。
-
'''
-
np.random.seed( 12345)
-
x = np.linspace( 0, 2, 1000) # 绘制曲线
-
y = x ** 2
-
plt.plot(x, y)
-
plt.fill_between(x, y, where=(y > 0), color= 'red', alpha= 0.5) # 填充颜色
-
# plt.show()
-
-
#模拟1000个随机点
-
N = 1000
-
points = [[xy[ 0] * 2, xy[ 1] * 4] for xy in np.random.rand(N, 2)]
-
plt.scatter([x[ 0] for x in points], [x[ 1] for x in points], s= 5, c=np.random.rand(N), alpha= 0.5)
-
plt.show()
-
-
#计算落在红色区域的比重
-
count = 0
-
for xy in points:
-
if xy[ 1] < xy[ 0] ** 2:
-
count += 1
-
print((count / N) * ( 2 * 4)) # 2.752
-
print(integrate.quad( lambda x: x ** 2, 0, 2)[ 0])
-
-
'''''
-
蒙特卡洛方法有一定的误差,误差的大小与模拟的样本大小直接相关,模拟样本越大,误差越小,但计算量也会大幅上升。
-
对于简单问题来说,蒙特卡洛是个“笨”办法。
-
但对于涉及复杂、不可解析函数或概率分布的模拟及计算,蒙特卡洛方法是个有效的方法,有时甚至是唯一可行的方法。
-
'''
-
-
'''''
-
实例2:套圈圈的游戏,想过为什么你总是套不上吗?用蒙特卡洛方法来算一算。
-
1.设物品中心点坐标为(0,0),物品半径为5cm。
-
'''
-
#
-
circle_target = mpatches.Circle([ 0, 0], radius= 5, edgecolor= 'r', fill= False)
-
plt.xlim( -80, 80)
-
plt.ylim( -80, 80)
-
plt.axes().add_patch(circle_target)
-
# plt.show()
-
-
'''''
-
2.设投圈半径8cm,投圈中心点围绕物品中心点呈二维正态分布,均值μ=0cm,标准差σ=20cm,模拟1000次投圈过程。
-
上图中红圈为物品,散点图为模拟1000次投圈过程中,投圈中心点的位置散布。
-
3.计算1000次投圈过程中,投圈套住物品的占比情况。
-
'''
-
N = 1000
-
u, sigma = 0, 20
-
points = sigma * np.random.randn(N, 2) + u
-
plt.scatter([x[ 0] for x in points], [x[ 1] for x in points], c=np.random.rand(N), alpha= 0.5)
-
plt.show()
-
-
print(len([xy for xy in points if xy[ 0] ** 2 + xy[ 1] ** 2 < ( 8 - 5) ** 2]) / N)
-
#输出结果:0.009,即投1000次,有9次能够套住物品,是小概率事件,知道你为什么套不住了吧。
-
'''''
-
蒙特卡洛方法本身不是优化方法,
-
与遗传算法、粒子群算法等智能优化算法有相似之处,比如都属于随机近似方法,都不能保证得到最优解等,
-
但它们也有着本质的差别。
-
一是层次不一样,蒙特卡洛只能称之为方法,遗传算法等则属于仿生智能算法,比蒙特卡洛方法要复杂。
-
二是应用领域不同,蒙特卡洛是一种模拟统计方法,如果问题可描述成某种统计量的形式,就可以用蒙特卡洛方法解决;
-
遗传算法等适用于大规模的组合优化问题(选址问题、排班问题、管理调度、路线优化)等,及复杂函数求最值、参数优化等。
-
'''
可以参考阅读的帖子:蒙特卡罗算法是什么?
code - python - MC蒙特卡洛方法