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


    介绍

    这个东西网上已经有很多相关的内容了, 我只是对这个过程感兴趣, 所以自己来做了一个. 网上, 大多数纯粹计算的, 对于我这种视觉型的人来说, 还是要看一下比较好. 这里我加入了 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}")
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    效果

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

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

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

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

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

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

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

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

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

  • 相关阅读:
    软件测试面试技巧有哪些?这几点你得知道,不然后悔都来不及
    2022 RedisDays 内容揭秘
    mysql8.0从安装部署到使用
    原型制作与图解
    基于Python实现的吃豆人游戏设计
    3D视觉应用案例:引导板件定位抓取
    OpenGL ES EGL 简介
    C++ 11:多线程相关问题
    Linux kali redhat debin centos ubuntu 修改 找回 重置 root用户密码 --最简单的方法
    对连续傅里叶变换和离散傅里叶变换中有关频率理解
  • 原文地址:https://blog.csdn.net/qq_40734247/article/details/127589539