利用蒙特卡洛(Monte Carlo)方法计算π值[ 转载]
部分转载自:https://blog.csdn.net/daniel960601/article/details/79121055
圆周率π是一个无理数,没有任何一个精确公式能够计算π值,π的计算只能采用近似算法。
国际公认的π值计算采用蒙特卡洛方法。
一、蒙特卡洛方法
蒙特卡洛(Monte Carlo)方法,又称随机抽样或统计试验方法。当所求解的问题是某种事件出现的概率,或某随机变量的期望值时,可以通过某种“试验”方法求解。
简单说,蒙特卡洛是利用随机试验求解问题的方法。
二、π值的计算
构造一个单位正方形和一个单位圆的1/4,往整个区域内随机投入点,根据点到原点的距离判断点是落在1/4的圆内还是在圆外,从而根据落在两个不同区域的点的数目,求出两个区域的比值。如此一来,就可以求出1/4单位圆的面积,从而求出圆周率π。

1. 简化版PI 求解的Python实现(示例一):
# pi.py
from random import random
from math import sqrt
from time import clock
DARTS = 12000 # 总的实验次数
hits = 0
clock()
for i in range(1, DARTS):
x, y = random(), random();
dist = sqrt(x**2 + y**2)
if dist <= 1.0:
hits = hits + 1
pi = 4 * (hits/DARTS)
print('Value of PI is %s' % pi)
print('Total runtime : %-5.5ss' % clock())
代码中用到了random和math库的random()函数和sqrt()函数,为了统计时间,还用到了time库的clock()函数。
投入的点越多,计算值越精确。
2. 另一个改进版的 Python 程序(示例二):
用正方形及其内接圆开展投针实验
# PI-pro2.py
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
# 投针次数
n = 10000
# 圆的信息
r = 1.0 # 半径
a, b = (0., 0.) # 圆心
# 正方形区域边界
x_min, x_max = a-r, a+r
y_min, y_max = b-r, b+r
# 在正方形区域内随机投点,(x,y)构成 n 个点
x = np.random.uniform(x_min, x_max, n) # 均匀分布
y = np.random.uniform(y_min, y_max, n)
# 计算 点到圆心的距离
d = np.sqrt((x-a)**2 + (y-b)**2)
# 统计 落在圆内的点的数目
res = sum(np.where(d < r, 1, 0))
# 计算 PI 的近似值(Monte Carlo方法的精髓:用统计值去近似真实值)
pi = 4 * res / n
print('pi: ', pi)
# 画个图看看
fig = plt.figure()
axes = fig.add_subplot(111)
axes.plot(x, y,'ro',markersize = 1)
plt.axis('equal') # 防止图像变形
circle = Circle(xy=(a,b), radius=r, alpha=0.5)
axes.add_patch(circle)
plt.show()
示例二次运行截图:

3. 另一个改进版的 Python 程序(示例三):
改进了示例二的图形显示:
- (1)圆内外的点采用不同颜色显示;
- (2)增加了图的标题,用于展示 PI的计算结果
# PI-pro3.py
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
# 投点次数
n = 5000
# 圆的信息
r = 1.0 # 半径
a, b = (0., 0.) # 圆心
# 正方形区域边界
x_min, x_max = a-r, a+r
y_min, y_max = b-r, b+r
# 在正方形区域内随机投点
x = np.random.uniform(x_min, x_max, n) # 均匀分布
y = np.random.uniform(y_min, y_max, n)
# 计算 点到圆心的距离
d = np.sqrt((x-a)**2 + (y-b)**2)
# 统计 落在圆内的点的数目
ind = np.where(d <= r, 1, 0)
res = sum(ind)
# 计算 pi 的近似值(Monte Carlo方法的精髓:用统计值去近似真实值)
pi = 4 * res / n
print('pi: ', pi)
# 画个图看看,画图比较耗费时间
fig = plt.figure()
axes = fig.add_subplot(111)
axes.set_title('PI is: %f' %pi) # 在图中标题栏显示计算的 PI值
for i in range(len(ind)):
if ind[i] == 1:
axes.plot(x[i], y[i],'ro',markersize = 2,color='r') # 圆内一种颜色
else:
axes.plot(x[i], y[i],'ro',markersize = 2,color='g') # 圆外另一种颜色
plt.axis('equal') # 防止图像变形
circle = Circle(xy=(a,b), radius=r, alpha=0.5)
axes.add_patch(circle)
plt.show()
示例三次运行截图:

三、结语
蒙特卡洛方法提供了一个利用计算机中随机数和随机试验来解决现实中无法用公式求解问题的思路,广泛应用在金融工程学、宏观经济学、计算物理学等领域。
四、Uniform 均匀分布投针方法
我采用均匀布点的方法,投针,计算弧线内的点数 N,全部投针数比值的4倍近似求 PI
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
# 初始化
N = 0
K = 0
step = 1
r = 100 # 半径
# 画图
fig = plt.figure()
axes = fig.add_subplot(111)
for x in range(0,r,step):
for y in range(0,r,step):
if (x**2+y**2 <= r**2):
N = N +1
axes.plot(x, y,'ro',markersize = 2,color='r') # 圆内一种颜色
else:
K = K +1
axes.plot(x, y,'ro',markersize = 2,color='g') # 圆外一种颜色
PI = 4 * N / (N+K)
print('PI : ', PI)
axes.set_title('PI is: %f' %PI) # 在图中标题栏显示计算的 PI值
plt.axis('equal') # 防止图像变形
plt.show()
示例 投10000个针,运行截图:

从上图可以看出,Monte Carlo 方法投5000针计算所得的精度高于 uniform 投针10000次的进度。
利用蒙特卡洛(Monte Carlo)方法计算π值[ 转载]的更多相关文章
- Monte Carlo方法简介(转载)
Monte Carlo方法简介(转载) 今天向大家介绍一下我现在主要做的这个东东. Monte Carlo方法又称为随机抽样技巧或统计实验方法,属于计算数学的一个分支,它是在上世纪四十年代 ...
- [其他] 蒙特卡洛(Monte Carlo)模拟手把手教基于EXCEL与Crystal Ball的蒙特卡洛成本模拟过程实例:
http://www.cqt8.com/soft/html/723.html下载,官网下载 (转帖)1.定义: 蒙特卡洛(Monte Carlo)模拟是一种通过设定随机过程,反复生成时间序列,计算参数 ...
- 蒙特卡罗(Monte Carlo)方法简介
蒙特卡罗(Monte Carlo)方法,也称为计算机随机模拟方法,是一种基于"随机数"的计算方法. 二 解决问题的基本思路 Monte Carlo方法的基本思想很早以前就被人们所发 ...
- 基于Monte Carlo方法的2048 A.I.
2048 A.I. 在 stackoverflow 上有个讨论:http://stackoverflow.com/questions/22342854/what-is-the-optimal-algo ...
- Java泛型:利用泛型动态确认方法返回值类型
根据泛型类型动态返回对象 public <T extends PackObject> T unPackMessage(String interfaceCode, String respVa ...
- 蒙特卡罗方法、蒙特卡洛树搜索(Monte Carlo Tree Search,MCTS)初探
1. 蒙特卡罗方法(Monte Carlo method) 0x1:从布丰投针实验说起 - 只要实验次数够多,我就能直到上帝的意图 18世纪,布丰提出以下问题:设我们有一个以平行且等距木纹铺成的地板( ...
- 增强学习(四) ----- 蒙特卡罗方法(Monte Carlo Methods)
1. 蒙特卡罗方法的基本思想 蒙特卡罗方法又叫统计模拟方法,它使用随机数(或伪随机数)来解决计算的问题,是一类重要的数值计算方法.该方法的名字来源于世界著名的赌城蒙特卡罗,而蒙特卡罗方法正是以概率为基 ...
- Monte carlo
转载 http://blog.sciencenet.cn/blog-324394-292355.html 蒙特卡罗(Monte Carlo)方法,也称为计算机随机模拟方法,是一种基于"随机数 ...
- FAST MONTE CARLO ALGORITHMS FOR MATRICES II (快速的矩阵分解策略)
目录 问题 算法 LINEARTIMESVD 算法 CONSTANTTIMESVD 算法 理论 算法1的理论 算法2 的理论 代码 Drineas P, Kannan R, Mahoney M W, ...
随机推荐
- How to solve “Dynamic Web Module 3.1 requires Java 1.7 or newer” in Eclipse
How to solve “Dynamic Web Module 3.1 requires Java 1.7 or newer” in Eclipse Last updated on June 20t ...
- GIL计算python 2 和 python 3 计算密集型
首先我画了一张图来表示GIL运行的方式: Python 3执行如下计算代码:#-*-conding:utf-8-*-import threading import timedef add(): n = ...
- 使用Nexus2搭建Maven本地仓库
由于OS为WindowsXP,而Nexus3forWindows为x64版本,只能选择安装nexus2了. Windows(x86)平台,Nexus Repository Manager OSS 2. ...
- elasticsearch-权威指南笔记-基础部分
参考这里的文档es权威指南 话说这个坑爹的文档是2.x版本的es,英文版本也是,所以就没啥好抱怨的了. 官方教程中有很多坑 例如,需要启动text上的索引. 还有就是get这个是不能带json的,所以 ...
- 微软microsoft word的api文档地址
https://docs.microsoft.com/en-us/previous-versions/office/developer/office-2003/aa172758(v%3doffice. ...
- MQ队列堵塞无法读取经验总结
问题现象: 1号发生本地来帐队列无法读取消息的问题,导致来帐报文均无法正常处理. 原因分析: 应用系统没有修改或上包,昨天交易和消息读取还是一切正常,mbfe的状态也是正常,mq的状态正常,以上正常可 ...
- Python SMTP发送邮件
import smtplibfrom email.mime.text import MIMEText # 引入smtplib和MIMEText host = 'smtp.163.com' # 设置 ...
- AltiumDesigner印制导线的走向及形状
印制导线的走向及形状.在PCB布线时,相邻层的走线方向成正交结构,应避免将不同的信号线在相邻走成同一方向,以减少不必要的层间窜扰.当PCB布线受到结构限制(如某种背板)难以避免出现平行布线时,特别是当 ...
- c#: 任务栏进度显示(TaskbarManager)
Win7及以上系统支持任务栏进度条,为有进度类应用显示进度于任务栏,甚为方便. 以c#之WinForm实现其,大多采用Windows API Code Pack这个方案,加多引用,比较繁琐,而我总也打 ...
- React-router4 简单总结
官方文档读到这里,大概明白了React-router是专门为单页面设计的,,我只能说多页面格外的不方便 首先这个是基本的套路 import React from 'react' import Reac ...