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

介绍

这个东西网上已经有很多相关的内容了, 我只是对这个过程感兴趣, 所以自己来做了一个. 网上, 大多数纯粹计算的, 对于我这种视觉型的人来说, 还是要看一下比较好. 这里我加入了 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 次试验结果:
使用蒙特卡罗方法计算圆周率_第1张图片
注: 推荐只做 7 次, 因为第 8 次已经耗费了将近 20 分钟了, 7 次的话, 一分钟之内结果就全部出来了.

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

试验次数: 10, 命中: 10
使用蒙特卡罗方法计算圆周率_第2张图片

试验次数: 100, 命中: 85
使用蒙特卡罗方法计算圆周率_第3张图片

试验次数: 1000, 命中: 789
使用蒙特卡罗方法计算圆周率_第4张图片

试验次数: 10000, 命中: 7855
使用蒙特卡罗方法计算圆周率_第5张图片

试验次数: 100000, 命中: 78444
使用蒙特卡罗方法计算圆周率_第6张图片

试验次数: 1000000, 命中: 785977
使用蒙特卡罗方法计算圆周率_第7张图片

试验次数: 10000000, 命中: 7852334
使用蒙特卡罗方法计算圆周率_第8张图片

你可能感兴趣的:(python,matplotlib,python)