Python学习笔记(一)蒙特卡罗算法求圆周率π

发布时间 2023-11-01 10:29:23作者: 风过无痕RPG

绪论

\(\pi\)(圆周率)是数学和物理学普遍存在的常数之一,可以被定义为圆周长和直径之比或者圆的面积与半径平方之比(\(l=2\pi r\)\(S=\pi r^2\))。\(\pi\)是一个无理数,下面将用蒙特卡罗算法求\(\pi\)的数值近似。

要求

1.要求能算到小数点后面越多越好‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬。
‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪2.并用进度条提示算的进度,能给出多种进度条越好。
‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬3.要求给出算圆周率Pi具体公式或者算法说明。

代码

Ptthon代码实现
from math import sqrt
from random import random
from time import perf_counter

DARTS =1000000
hits =0.0
start = perf_counter()
for i in range(1,DARTS+1):

    x,y =random(),random()
    dist =sqrt(x**2+y**2)
    if dist <=1.0:
        hits =hits+1
pi = 4*(hits/DARTS)
print("Pi值为:{}.".format(pi))
print("运行时间是:{:.5f}s".format(perf_counter()-start))

输出

image

算法

这是一个几何概型,有一个外切圆形的正方形,直径和边长均为1,此时正方形和圆的面积之比为\(\pi\),假设有无穷多的点随机落在该图形内,概率的期望值等于\(\pi\)
image

蒙特卡罗算法的基本思想就是利用概率分布代替问题都求解。当然,这里我们不可能取到无穷的点,由大数定律,可以通过取尽可能多的点来逼近期望值。
调用标准库random和math,计算每个点到圆心的距离,统计在圆内的点数,for循环即可。

复杂度

单从算法实现来看,可以算出空间复杂度为\(O(1)\),而时间复杂度为\(O(N^2)\),如果当样本数的数量级大起来,所花时间也是相当大,如果说要追求精确度的话,蒙特卡罗算法不是一个很好的算法。
不过,蒙特卡罗算法理解和实现都很容易,对于实践而言,对于数值求解往往不需要很精确,只需要控制在一个合理的数量级。