大家好,欢迎来到IT知识分享网。
微实践 – 发现圆周率
本书同名免费MOOC《Python编程基础及应用》在哔哩哔哩(B站)热播,作者带着你学。
版权声明:本文内容引用自作者的图书《Python编程基础及应用》(高等教育出版社)。本文可以在互联网上转载传播,但必须包含文中的版权声明;本文不可以以纸质出版为目的进行摘抄或改编。
在历史的长河里,从古至今的数学家们尝试了无数种计算圆周率的方法。 其中,法国数学家布冯(1707-1788)和拉普拉斯(1749-1827)提出的方法比较有趣。
在边长为2的正方形内有一个直径为2半径为1的内切圆。根据圆的面积公式,内切圆的面积 s = πr2 ,由于r=1,所以π = 内切圆的面积。边长为2的正方形面积为4。在已知正方形的面积为4的情况下,如何求得内切圆的面积呢? 布冯提出了投针的方法。假设10000根针“均匀随机”地垂直落在正方形上,每根针在正方形上形成一个“投点”。那么落入圆内的投点数量与圆的面积正相关:
简单推导,可得:
假设有8000根针落在了圆内,其余的2000根落在了圆外。此时,内切圆面积 ≈ 4 x 8000 / 10000 = 4 x 0.8 = 3.2,即圆周率π ≈ 3.2。
下述代码模拟了将数量众多的针投射到正方形,然后通过估算内切圆面积求得π的过程。
#picalc.py
import random #随机数模块
N,nHits = 10000,0 #总投点数,圆内投点数
xs,ys = [],[] #投点的x,y坐标列表
for i in range(N): #N次投点
x = random.random()*2-1 #随机数取投点坐标
y = random.random()*2-1
xs.append(x) #投点坐标存入列表
ys.append(y)
if x*x+y*y <= 1: #投点位于内切圆内
nHits += 1 #圆内投点数 + 1
pi = 4*nHits/N #通过计算圆面积估算圆周率
print("pi =",pi)
import matplotlib.pyplot as plt #绘图展现投点落在正方形/圆内的情况
from matplotlib.patches import Circle
fig = plt.figure(figsize=(6,6))
plt.plot(xs, ys,'o', color='black', markersize = 1)
c = Circle(xy=(0,0), radius=1, alpha=0.4, color="black")
plt.gca().add_patch(c)
plt.show()
执行结果
pi = 3.1908
注:因为随机数的参数,读者执行的结果很可能会不同。
代码说明
- – N = 10000规定了投针的总次数;通过for循环,将投针N次。
- – random.random()返回取值区间为0-1的均匀分布的随机数;random.random()*2-1得到取值区间为-1到+1的随机数。
- – 循环内的x,y通过随机数取值,(x,y)代表了本次投针的落点坐标。每次投完针,都把坐标x,y存入对应的列表xs,ys,用于后续绘图。
- – x*x+y*y <= 1用于判断针的落点是否在内切圆内。这里事实上应用了点到原点的距离公式,当落点距离原点的距离不大于1时,说明该落点位于圆内,圆内投点数nHits增加1。这里需要注意,求点到原点的距离并没有进行开平方运算,因为不必要。
- – pi = 4 * nHits / N 应用前述推导公式计算内切圆的面积,也就是圆周率。
代码的后续部分使用matplotlib绘图库描绘了落针在正方形/圆形内形成的投点情况,如后图。程序的运行需要安装matplotlib库,其安装方法详见本书第14章。读者也可以先注释掉绘图相关的代码,这部分代码只管绘图,不影响前述投针估计过程。
读者可能还觉得上述圆周率的估计值3.1908不够准确。请修改N值,增加投针数量,再试一试。
本文节选高等教育出版社,《Pyton编程基础及应用》:
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/37867.html