使用蒙特卡罗方法计算圆周率

介绍

这个东西网上已经有很多相关的内容了, 我只是对这个过程感兴趣, 所以自己来做了一个. 网上, 大多数纯粹计算的, 对于我这种视觉型的人来说, 还是要看一下比较好. 这里我加入了 matplotlib 绘制散点图 (临时学的简单用法), 把这个过程用图片表示出来. 虽然已经理解了它计算的原理, 但是真的看到自己画出来的图示, 还是感觉满有意思的. 果然一图胜千言, 哈哈.

代码

# 使用蒙特卡洛算法计算圆周率

import random
from typing import Tuple
import matplotlib.pyplot as plt


def generateCoords() -> Tuple[float, float]:
    """随机生成范围内的坐标"""
    return random.uniform(-1.0, 1.0), \
        random.uniform(-1.0, 1.0)


def is_in_round(x: float, y: float):
    """判断给定坐标是否在圆内"""
    return (x**2 + y**2) <= 1.0


if __name__ == "__main__":
    sum = 7        # 试验总次数
    total = 1      # 一次试验总次数x
    hint = 0       # 命中次数
    hint_x_coords = []     # 命中坐标 x
    hint_y_coords = []     # 命中坐标 y

    no_hint_x_coords = []  # 未命中坐标 x
    no_hint_y_coords = []  # 未命中坐标 y
    # 单位圆半径 1, 正方形边长为 2
    for s in range(1, sum+1):
        total = 10*total
        hint = 0
        for i in range(0, total):
            x, y = generateCoords()
            if is_in_round(x, y):
                hint += 1
                hint_x_coords.append(x)
                hint_y_coords.append(y)
            else:
                no_hint_x_coords.append(x)
                no_hint_y_coords.append(y)

        # 计算圆周率
        PI = 4.0*hint/total
        # 绘制散点图, 首先要清空图片
        plt.clf()
        # 设置 x y 等长, 不然最终结果像是椭圆了
        plt.axis("equal")
        # 绘制命中的点
        plt.scatter(hint_x_coords, hint_y_coords)
        # 绘制未命中的点
        plt.scatter(no_hint_x_coords, no_hint_y_coords)
        # 保存图片
        plt.savefig(f"{s}_{hint}_{total}.png")

        print(f"{s}th Total: {total}, hint times: {hint}, PI = {PI}")


效果

7 次试验结果:
在这里插入图片描述
注: 推荐只做 7 次, 因为第 8 次已经耗费了将近 20 分钟了, 7 次的话, 一分钟之内结果就全部出来了.

这里可以看出来, 计算的结果是在逐渐逼近圆周率的, 但是感觉继续提高试验次数, 对于精度的提升并不是很明显. 不知道是代码是问题, 还是这个方法的问题. 而且, 我也不能一直提高精度, 毕竟在计算的时间上是不可接受的.

试验次数: 10, 命中: 10
在这里插入图片描述

试验次数: 100, 命中: 85
在这里插入图片描述

试验次数: 1000, 命中: 789
在这里插入图片描述

试验次数: 10000, 命中: 7855
在这里插入图片描述

试验次数: 100000, 命中: 78444
在这里插入图片描述

试验次数: 1000000, 命中: 785977
在这里插入图片描述

试验次数: 10000000, 命中: 7852334
在这里插入图片描述

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值