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


    介绍

    这个东西网上已经有很多相关的内容了, 我只是对这个过程感兴趣, 所以自己来做了一个. 网上, 大多数纯粹计算的, 对于我这种视觉型的人来说, 还是要看一下比较好. 这里我加入了 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
    在这里插入图片描述

  • 相关阅读:
    CompletableFuture异步编排(两任务组合——其中一个任务执行)
    【基础知识系列】用示例一窥字节序-大小端
    《铸梦之路》Untiy高性能自动化UI管理框架ZMUIFramework
    Representative Routes Discovery From Massive Trajectories
    一、网络基础知识
    KLEE简单使用
    Pandas数据库大揭秘:read_sql、to_sql 参数详解与实战篇【第81篇—Pandas数据库】
    redis运维(八)数据类型(一)字符串
    微软宣布即将停止对 Visual Studio 旧版本的支持
    NLP之Bert多分类实现案例(数据获取与处理)
  • 原文地址:https://blog.csdn.net/qq_40734247/article/details/127589539