使用python实现布丰投针法

对于π的值,直到1946年的时候,人类才能将π的值精确计算到小数点后2037位,而现在的超级计算机的能力可以精确的计算到小数点后几十亿位,然而在计算机发明之前,还是使用这里的布丰投针法来计算π值,是最实用的方法。

使用代码来模拟这个过程,首先是程序设计思路的基本路程:


import  math
import  numpy as np
from  numpy import random
import  matplotlib.pyplot as plt
import  matplotlib.lines as mlines

然后根据代码设计的流程图实现代码:

UPDATE_FREQ = 500  #每模拟投针500次后就将结果绘制出来
BOUND = 10  #图形绘制区域的长和宽
BORDER = 0.05 * 10  #绘制区域边缘宽度
NEEDLES=  10000  #投针的次数
NEEDLE_LENGTH = 1  #针的长度
FLOORBOARD_WIDTH = 2  #两条平行线之间的距离
FLOORBOARD_COLOR = 'black'  #两条平行线的颜色
NEEDLE_INTERSECTING_COLOR = 'red'  #铁针与线相交时的颜色
NEEDLE_NON_INTERSECTING_COLOR = 'green'  #铁针与直线不相交时的颜色
class Needle:
    def  __init__(self, x = None, y = None, theta = None, length = NEEDLE_LENGTH):
        '''
        x, y 作为铁针的中点,由于图像绘制区域的宽度为BOUND,因此我们可以把中点坐标设置在宽度内的任何地方,
        theta是铁针与水平方向的夹角,在分析时我们将该值限制在0和Pi/2之间,考虑这个区间是因为我们确定哪个平行线
        与铁针跟接近的情况下。如果不考虑这个前提条件,那么夹角的值就可以限定在0和pi之间。我们模拟时不事先考虑那条线与
        针的距离更近,因此我们对夹角区间采用0和pi之间
        '''
        if x is None:
            x = random.uniform(0, BOUND)
        if y is None:
            y = random.uniform(0, BOUND)
        if theta is None:
            theta = random.uniform(0, math.pi)
        self.center = np.array([x, y])  #设置铁针中心点坐标
        self.comp = np.array([length/2 * math.cos(theta), length/2 * math.sin(theta)])  #根据铁针与水平方向的夹角,计算中心在水平方向和竖直方向的距离
        self.endPoints = np.array([np.add(self.center, -1 * self.comp),
                                  np.add(self.center, self.comp)])  #根据中心与水平方向和竖直方向的距离运算铁针两头的坐标
    def  intersectsY(self, y):
        return  self.endPoints[0][1] < y and self.endPoints[1][1] > y  #y是平行线在竖直方向上的坐标
class Buffon_Sim:  #启动模拟进程
    def  __init__(self):
        self.floorboards = []  #存储平行线在竖直方向上的y坐标
        self.boards = int ((BOUND / FLOORBOARD_WIDTH) + 1)  #计算平行线在绘制区域内的数量
        self.needles = []  #存储模拟的铁针
        self.intersections = 0  #记录铁针与平行线相交的数量
        window = "Buffon"
        title = "Buffon Needle Simulation"
        desc = (str(NEEDLES) + " needles of length " + str(NEEDLE_LENGTH) + 
               " uniformly distributed over a " + str(BOUND) + " by " + str(BOUND) + 
               " area" + " with floorboards of width " + str(FLOORBOARD_WIDTH))  #描述当前模拟情况
        self.fig = plt.figure(figsize = (8,8))
        self.fig.canvas.set_window_title(window)
        self.fig.suptitle(title, size = 16, ha = 'center')
        self.buffon = plt.subplot()  #将模拟投针绘制出来
        self.buffon.set_title(desc, style = 'italic', size = 9, pad = 5)
        self.results_text = self.fig.text(0, 0, self.updateResults(), size = 10)  #将投针情况绘制成图像
        self.buffon.set_xlim(0 - BORDER, BOUND + BORDER)
        self.buffon.set_ylim(0 - BORDER, BOUND + BORDER)
        plt.gca().set_aspect('equal')  
    def  plotFloorboards(self):
        for j in range(self.boards):
            self.floorboards.append(0 + j * FLOORBOARD_WIDTH)  #绘制平行线
            self.buffon.hlines(y = self.floorboards[j], xmin = 0,
                              xmax = BOUND, color = FLOORBOARD_COLOR, linestyle = '--', linewidth = 2.0)
    def  tossNeedle(self):  #模拟投针过程
        needle = Needle()
        self.needles.append(needle)
        p1 = [needle.endPoints[0][0], needle.endPoints[1][0]]  #获取铁针两个端点的x坐标
        p2 = [needle.endPoints[0][1], needle.endPoints[1][1]]  #获取铁针两个端点的y坐标
        for k in range(self.boards):  #检测铁针是否与平行线相交
            if needle.intersectsY(self.floorboards[k]):
                self.intersections += 1
                self.buffon.plot(p1, p2, color = NEEDLE_INTERSECTING_COLOR, linewidth = 0.5)  #将相交的铁针用红色线条表示
                return 
        self.buffon.plot(p1, p2, color = NEEDLE_NON_INTERSECTING_COLOR, linewidth = 0.5)  #不相交的铁针用绿色线条表示
       
        
    def  plotNeedles(self):
        
        for i in range(NEEDLES):
            self.tossNeedle()
            self.results_text.set_text(self.updateResults(i + 1))
            if (i + 1) % UPDATE_FREQ == 0:  #连续模拟指定次数投针后把结果绘制出来
                plt.pause(0.0001)     
    def  updateResults(self, needlesToTossed = 0):
        if self.intersections == 0:
            sim_pi = 0
        else :
            sim_pi = (2 * NEEDLE_LENGTH * needlesToTossed) / (FLOORBOARD_WIDTH * self.intersections)  #根据公式(4)计算Pi值
        error = abs(((math.pi - sim_pi) / math.pi) * 100)  #计算模拟结果与真实结果的误差
        s = ("Intersections: " + str(self.intersections) + \
               "\nTotal Needles: " + str(needlesToTossed) + \
               "\nApproximation of pi: " + str(sim_pi) + "\nError: " + str(error) + "%")
        return s
    def  plot(self):
        legend_lines = [mlines.Line2D([], [], color = FLOORBOARD_COLOR, linestyle = '--', lw = 2),
                       mlines.Line2D([], [], color = NEEDLE_INTERSECTING_COLOR, lw = 1),
                       mlines.Line2D([], [], color = NEEDLE_NON_INTERSECTING_COLOR, lw = 1)]
        self.buffon.legend(legend_lines, ['floorboard', 'intersecting needle', 'non-intersecting needle'],
                          loc = 1, framealpha = 0.9)
        self.plotFloorboards()
         
        self.plotNeedles()
        plt.show()
      
        
bsim = Buffon_Sim()
bsim.plot()

使用的公式以及代码运行的结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/485839.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

React antd中下拉框联动没有清除上一次选中的内容

bug&#xff1a; 第一次&#xff1a; 第二次&#xff1a; 解决方法&#xff1a; <Fotm.item> <SelectshowSearchplaceholder"请输入单位名称"filterOption{selectFilterOption}options{bmSelectOptions}onChange{handleDwmcChange}/></F…

非平坦地形下运动规划相关理论

1.SVD平面拟合方法 空间中的离散点得到拟合平面&#xff0c;其实就是一个最优化的过程。即求这些点到某个平面距离和最小的问题。我们知道一个先验消息&#xff0c;那就是该平面一定会过众散点的平均值。接着我们需要做的工作就是求这个平面的法向量。 根据协方差矩阵的SVD变换…

WiFi已连接却不可上网是什么原因?

很多使用wifi上网的用户都遇到过这样的问题,就是电脑已经连接了wifi,但就是上不了网。着到底是怎么回事呢?今天,极客狗带大家一起来找找WiFi已连接却不可上网是什么原因,并给出对应的解决方。 原因分析: 可能是ip地址冲突所导致,也有可能是宽带出先故障,不妨试试下面的…

MySQL:数据类型

文章目录 数据类型分类数值类型越界访问bit类型小数类型floatdecimal 字符串类型charvarchar 日期enum和set 数据类型分类 在MySQL数据库中&#xff0c;存在各种各样的数据类型&#xff1a; 针对于上述的这么多类型&#xff0c;本篇就对于这些类型的数据进行一一解释&#xff…

五分钟快速搭建个人游戏网站(1Panel)

五分钟快速搭建个人游戏网站&#xff08;1Panel&#xff09; 环境要求&#xff1a;主流 Linux 发行版本&#xff08;基于 Debian / RedHat&#xff0c;包括国产操作系统&#xff09;&#xff1b; 如果是Windows OS的可以通过WSL来实现安装。 1 介绍 1Panel 是一个基于 Web 的 L…

SSR910Q系列高性价比NVR解决方案

一、方案描述 SSR910Q&#xff0c;主芯片内核为A53双核64位最高主频为1.2Ghz处理器&#xff0c;内置2Gb DDR3&#xff0c;最高速率可支持2133Mb/s。高性能H.265/H.264/MJPEG视频编解码&#xff0c;智能处理单元&#xff08;IPU&#xff09;。支持高速I/O接口&#xff0c;如USB…

包含多个段的程序

文章目录 包含多个段的程序在代码段中使用数据在代码段中使用栈将数据、代码、栈放入不同的段 包含多个段的程序 在代码段中使用数据 考虑这样一个问题&#xff0c;编程计算以下8个数据的和&#xff0c;结果存在ax 寄存器中&#xff1a;0123H&#xff0c;0456H&#xff0c;07…

FaceBook广告账号验证教程

1.登录facebook账号,点击左边的ads manager。 2.点击Create ad创建广告。 3.选择广告投放意向。 4.填写广告信息。 5.创建广告后选择付款方式&#xff0c;这里我是使用信用卡付款。这里我是使用Fomepay的虚拟卡进行绑定的。 6.填写信用卡的持卡人姓名 卡号 有效期 安全码 7.填写…

Negative Sampling with Adaptive DenoisingMixup for Knowledge Graph Embedding

摘要 知识图嵌入(Knowledge graph embedding, KGE)的目的是通过对比正负三元组&#xff0c;将知识图中的实体和关系映射到一个低维、密集的向量空间中。在kge的训练过程中&#xff0c;由于kge只包含正三元组&#xff0c;因此负采样对于找到高质量的负三元组至关重要。大多数现…

【Redis】Redis特性

Redis 认识redisRedis特性在内存中存储数据可编程可扩展性持久化Clustering高可用性 认识redis Redis&#xff0c;英文全称是Remote Dictionary Server&#xff08;远程字典服务&#xff09;&#xff0c;是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志…

时间对比投资:衡量5天与10天六西格玛绿带培训的价值

六西格玛绿带培训专为希望提高其业务流程改进技能的专业人员设计。绿带培训通常涵盖六西格玛的基础知识、DMAIC(定义、测量、分析、改进、控制)方法论、以及各种质量管理工具和技巧。绿带受训者通常在他们的工作职责中负责领导小型项目或作为黑带项目团队的成员&#xff0c;下面…

(附源码)基于Spring Boot + Vue的招聘平台设计与实现

前言 &#x1f497;博主介绍&#xff1a;✌专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅&#x1f447;&#x1f3fb; 2024年Java精品实战案例《100套》 &#x1f345;文末获取源码联系&#x1f345; &#x1f31…

使用Django实现信号与消息通知系统【第154篇—Django】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 使用Django实现信号与消息通知系统 在Web应用程序中&#xff0c;实现消息通知系统是至关重…

【JAVA】数组的定义和使用

JAVA的数组和c语言的相似但是在创建上略有不同 数组的创建及初始化 T[] 数组名 new T[N]; T&#xff1a;表示数组中存放元素的类型 T[]&#xff1a;表示数组的类型 N&#xff1a;表示数组的长度 动态初始化 int[] array new int[10]; 静态初始化 int[] array1 new …

边缘计算基础介绍及AKamai-linode产品分析

1、背景 随着互联网的发展&#xff0c;我们进入了大数据时代&#xff0c;这个时代也是移动互联网的时代&#xff0c;而且这个时代&#xff0c;大量的线下服务走到线上&#xff0c;随之而来的&#xff0c;比如外卖、叫车……于是&#xff0c;有各种各样的 App 和设备在收集你的…

基于DWT(离散小波变换)的图像水印算法,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

nodejs+vue高校师资管理系统python-flask-django-php

快速发展的社会中&#xff0c;人们的生活水平都在提高&#xff0c;生活节奏也在逐渐加快。为了节省时间和提高工作效率&#xff0c;越来越多的人选择利用互联网进行线上打理各种事务&#xff0c;然后线上管理系统也就相继涌现。与此同时&#xff0c;人们开始接受方便的生活方式…

nginx: [emerg] stream directive is duplicate in /etc/nginx/nginx.conf:56

背景&#xff1a; 在维护paas平台的时候发现一个web前端容器服务运行报错&#xff0c;提示如下&#xff1a; 问题分析&#xff1a; 根据日志的内容&#xff0c;发现是nginx.conf配置文件的stream模块配置存在问题导致的。需要查看一下nginx.conf配置文件的内容&#xff1a; 注…

Soybean Admin:基于 Vue3、Vite3、TypeScript、NaiveUI、Pinia 和 UnoCSS 的清新优雅的中后台模版

一、引言 随着互联网技术的快速发展&#xff0c;前端开发领域也在不断演进。Soybean Admin 作为一个基于最新前端技术栈的中后台模版&#xff0c;为开发者提供了一个高效、规范、灵活的解决方案。本文将深入探讨 Soybean Admin 的技术特性及其在中后台前端开发中的优势。 二、…

android h5理财(记账)管理系统eclipse开发mysql数据库编程服务端java计算机程序设计

一、源码特点 android h5理财管理系统是一套完善的WEBandroid设计系统&#xff0c;对理解JSP java&#xff0c;安卓app编程开发语言有帮助&#xff08;系统采用web服务端APP端 综合模式进行设计开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要…
最新文章