部分转载自: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)方法计算π值[ 转载]的更多相关文章

  1. Monte Carlo方法简介(转载)

    Monte Carlo方法简介(转载)       今天向大家介绍一下我现在主要做的这个东东. Monte Carlo方法又称为随机抽样技巧或统计实验方法,属于计算数学的一个分支,它是在上世纪四十年代 ...

  2. [其他] 蒙特卡洛(Monte Carlo)模拟手把手教基于EXCEL与Crystal Ball的蒙特卡洛成本模拟过程实例:

    http://www.cqt8.com/soft/html/723.html下载,官网下载 (转帖)1.定义: 蒙特卡洛(Monte Carlo)模拟是一种通过设定随机过程,反复生成时间序列,计算参数 ...

  3. 蒙特卡罗(Monte Carlo)方法简介

    蒙特卡罗(Monte Carlo)方法,也称为计算机随机模拟方法,是一种基于"随机数"的计算方法. 二 解决问题的基本思路 Monte Carlo方法的基本思想很早以前就被人们所发 ...

  4. 基于Monte Carlo方法的2048 A.I.

    2048 A.I. 在 stackoverflow 上有个讨论:http://stackoverflow.com/questions/22342854/what-is-the-optimal-algo ...

  5. Java泛型:利用泛型动态确认方法返回值类型

    根据泛型类型动态返回对象 public <T extends PackObject> T unPackMessage(String interfaceCode, String respVa ...

  6. 蒙特卡罗方法、蒙特卡洛树搜索(Monte Carlo Tree Search,MCTS)初探

    1. 蒙特卡罗方法(Monte Carlo method) 0x1:从布丰投针实验说起 - 只要实验次数够多,我就能直到上帝的意图 18世纪,布丰提出以下问题:设我们有一个以平行且等距木纹铺成的地板( ...

  7. 增强学习(四) ----- 蒙特卡罗方法(Monte Carlo Methods)

    1. 蒙特卡罗方法的基本思想 蒙特卡罗方法又叫统计模拟方法,它使用随机数(或伪随机数)来解决计算的问题,是一类重要的数值计算方法.该方法的名字来源于世界著名的赌城蒙特卡罗,而蒙特卡罗方法正是以概率为基 ...

  8. Monte carlo

    转载 http://blog.sciencenet.cn/blog-324394-292355.html 蒙特卡罗(Monte Carlo)方法,也称为计算机随机模拟方法,是一种基于"随机数 ...

  9. FAST MONTE CARLO ALGORITHMS FOR MATRICES II (快速的矩阵分解策略)

    目录 问题 算法 LINEARTIMESVD 算法 CONSTANTTIMESVD 算法 理论 算法1的理论 算法2 的理论 代码 Drineas P, Kannan R, Mahoney M W, ...

随机推荐

  1. input输入限制

    1:只能输入两位小数点:function keepTwoPointNum(that){ var val=that.value; if(isNaN(val)){ $(that).val(''); ret ...

  2. python中subprocess模块

    subprocess  模块 subprocess称之为子进程,进程是一个正在进行的程序 子进程是由另一个正在运行的程序启动的程序,例如QQ聊天点击一个链接,打开了浏览器,那么浏览器称之为QQ的子进程 ...

  3. 高并发高负载系统架构-php篇

    首先呢,我罗列一下文章的目录,让大家有个整体轮廓的了解! 1.为什么要进行高并发和高负载的研究 2.高并发和高负载的约束条件 3.解决之道——硬件篇 4.解决之道——部署篇 5.解决之道——环境篇 6 ...

  4. 使用PandoraBox时的软件源配置

    src/gz 18.12_core http://downloads.pangubox.com:6380/pandorabox/18.12/targets/ralink/mt7621/packages ...

  5. Hibernate 再接触 悲观锁和乐观锁

    为什么取1248 二进制 CRUD 移位效率高 在并发和效率选择一个平衡点 一般不会考虑幻读 因为我们不会再一个事务里查询两次,(只能设置为seralizable) 悲观锁和乐观锁的前提是read-u ...

  6. # 20175213 2018-2019-2 《Java程序设计》第2周学习总结

    ## 教材学习内容总结 在第二周的学习过程中,我学习了第二章和第三章的内容.第二章中,我学习了基本数据类型和类型转换运算以及与C语言有着相同和不同的数组.标识符由字母,下划线,美元符号和数字组成,并且 ...

  7. win10 下安装 neo4j(转)

    1.neo4j介绍 neo4j是基于Java语言编写图形数据库.图是一组节点和连接这些节点的关系.图形数据库也被称为图形数据库管理系统或GDBMS.详细介绍可看Neo4j 教程 2.安装Java jd ...

  8. MFC笔记8

    1.在循环使用数组时需要清理数组 CString str; memset(str,0,strlen(str)); 判断两个字符串包含数字大小是否相等 CString str="22" ...

  9. php 获取数组深度的值

    匿名函数(闭包) $val = array(); array_walk_recursive($array, function ($x) use (&$val) { $val[] = $x; } ...

  10. Appium 学习一:环境搭建问题

    1.安装Android-sdk http://tools.android-studio.org/index.php/sdk 问题1:下载 android-sdk_r24.4.1-windows.zip ...