各种求圆周率π的算法(蒙特卡洛法的Java实现)
什么是算法?简单地说,算法就是有穷规则构成的用于解决某一类问题的运算序列或执行步骤。在《算法之美:隐匿在数据结构背后的原理》第1章中我们讲到要解决一个问题可能会有不同的方法,当时所举的例子就是求圆周率π的近似值。对于这个问题你能想到多少种算法呢?
探秘算法世界,求索数据结构之道;
汇集经典问题,畅享编程技法之趣;
点拨求职热点,敲开业界名企之门。
本书内容简介及勘误表请参见《算法之美隆重上市欢迎关注(另附勘误表在此)》。
方法(1):首先根据微积分中的泰勒公式,可以使用下面这个公式来求π的近似值
方法(2):其次可以还可以利用下面这个马青公式来求解π的近似值:
马青公式由英国天文学家约翰·马青(John Machin,1686 –1751)于1706年发现,他利用这个公式计算到了100位的圆周率。此外,上式中的反三角函数可以领用下面这个泰来展开式进行计算:
方法(3):最后,也是我们准备来动手实践一下的就是利用蒙特卡洛法。这个方法背后的理论基础是概率论中的伯努利大数定律。众所周知,圆的面积公式为 S = πr2,当 r = 1 时,S = π。如果在一个边长为1的正方形中有一个内切圆,那么该圆的面积就是π/4。利用这一原理,可以假设有大量的随机点等概率均匀地落入此正方形中。若正方形的面积为S',内切圆的面积为S,如果落入正方形中的点数为 N',落入内切圆的面积为N,这时便有 S'/S = N'/N,所以可据此求得π = 4×N/N'。
下面就编写一个Java程序来实现蒙特卡洛法求π的近似值:
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- public class MonteCarloPi {
- public static void main(String[] args) throws Exception{
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- System.out.print("How many darts shoud I toss at the board?\n");
- String s = br.readLine();
- int numberOfDarts = Integer.parseInt(s.trim());
- double radius = 1.0;
- Dartboard d = new Dartboard(radius);
- for(int i=1; i<=numberOfDarts; i++){
- Toss t = Toss.getRandom(radius);
- d.strike(t);
- }
- double fractionIn = d.getFractionIn();
- double pi = 4.0 * fractionIn;
- System.out.println("Pi is approximately "+pi);
- }
- }
- class Dartboard{
- private double radius;
- private int insideCircle, outsideCircle;
- public Dartboard(double radius){
- this.radius = radius;
- insideCircle = 0;
- outsideCircle = 0;
- }
- public void strike(Toss toss){
- double x = toss.getX();
- double y = toss.getY();
- if(Math.sqrt(x*x + y*y) < radius)
- insideCircle++;
- else
- outsideCircle++;
- }
- public double getFractionIn() {
- double total = (double) (insideCircle + outsideCircle);
- return (double) insideCircle/total;
- }
- }
- class Toss{
- private double x,y;
- public Toss(double x, double y){
- this.x = x;
- this.y = y;
- }
- public double getX(){return x;}
- public double getY(){return y;}
- public static Toss getRandom(double radius){
- double x,y;
- double size = Math.random();
- double sign = Math.random();
- size = size * radius;
- if(sign > 0.5)
- x = size;
- else
- x = -size;
- size = Math.random();
- sign = Math.random();
- size = size * radius;
- if(sign > 0.5)
- y = size;
- else
- y = -size;
- return new Toss(x,y);
- }
- }
执行一下上述代码,然后我们来验证一下其效果如何...
- How many darts shoud I toss at the board?
- 1000000
- Pi is approximately 3.142028
可见所得到的结果较好地近似于圆周率 π 。
(本文完)
各种求圆周率π的算法(蒙特卡洛法的Java实现)相关推荐
- java迭代法求圆周率用梯形_java第二阶段作业总结
0.前言 第二阶段的作业共包含三次作业.第一次作业包含三道题目,第一道题目考查了使用java中的字符串处理类以及正则表达式对输入的字符串数据进行合法性校验及计算,第二道题目考查了使用蒙特卡洛仿真方法求 ...
- 蒙特卡洛法求圆周率 c语言,c++蒙特卡洛法求圆周率
在linux下用 g++ pi.cpp -o pi -lm 编译. //蒙特卡洛法求圆周率 #include #include #include #include using namespace st ...
- JAVA:实现求StandardDeviation标准差算法(附完整源码)
JAVA:实现求StandardDeviation标准差算法 package com.thealgorithms.maths;public class StandardDeviation {publi ...
- 蒙特卡洛求圆周率c语言代码,蒙特卡洛法求圆周率
利用蒙特卡洛算法求圆周率是一个概率的方法,关于这方面的内容很多,而且也很容易理解,更多具体分析过程可以参考如下文章: http://blog.csdn.net/zzhflyqh/article/det ...
- 求圆周率算法(割圆术)c语言实现
1.算法设计原理分析 利用周长为1的圆的周长为2Π,采用割圆术,从开始的正六边形(周长为6),循环切割求正12边形.正24边形--的边长(勾股定理),从而求出正多边形的周长,来近似求解出2Π的值. 整 ...
- 求取众数及重数的算法实现(Java)
求取众数及重数的算法实现(Java) – 给定含有n个元素的多重集合S,每个元素在S中出现 的次数称为该元素的重数. – 多重集S中重数最大的元素称为众数. – 例如,S={1,2,2,2,3,5}. ...
- 〖数学算法〗求圆周率的几种算法
圆周率大家都不陌生,最早由欧几里德<几何原本>中提到圆周率是常数,第一个用寻求圆周率数值的人是阿基米德,中国数学家刘徽,和后来大名鼎鼎的祖冲之分别对圆周率进行了计算,从古到今对圆周率的计算 ...
- java 求圆周率π
1. 什么是圆周率: 圆的周长除以圆的直径,祖冲之采用内切圆的方式将圆周率精确到了3.1415926. 2.什么是内切圆求圆周: · 如图:随着切割次数的增加多边形的周长会无限接近圆的周长 ...
- 7-3 蒙特卡罗方法求圆周率 (15 分)(Java)
7-3 蒙特卡罗方法求圆周率 (15 分)(Java) 可算写出来了 使用蒙特卡洛仿真方法求圆周率.(具体要求见作业指导书 2020-OO第05次作业-2指导书V1.0.pdf ) 输入格式: 从键盘 ...
最新文章
- Alternative PHP Cache ( APC )
- Spring4 MVC表单验证代码示例
- jsr-303 参数校验-学习(转)
- 程序员再也不担心请不到假了!
- 论HTML5 Audio 标签歌词同步的实现
- git提交emoji_Emoji-Log:一种编写Git提交消息的新方法
- 华为Mate 40系列或首发屏下摄像头:全球首个量产级别方案
- qt获取窗口的右上角位置_智能座舱QT应用实例 -- Mode/View
- 转] 两种自定义表单设计方案
- iteritems python3_python3 items() 与 python2 中iteritems()的区别
- java cpt_1、第十 - WEB开发进阶 - JavaSricpt 正则表达式
- 十八、完成登录与注册页面的前端
- jquery点击按钮删除文本框的内容
- HUAWER 华为5G无线数据终端 和 TP-LINK路由器AX6000连接及注意事项
- linux 修改路由表 永久,CentOS 6.9永久设置静态路由表以及路由表常用设置
- 平安新一贷怎么被拒了及原因是什么?你都知道吗?
- 1142:单词的长度
- v-model的radio checkbox以及键盘修饰符使用
- 华为手表 GT3训练计划怎么用?
- 本地时间(北京时间)和“GMT+8”时区时间的区别?
热门文章
- CentOS 8安装Python3.7.0
- 新概念英语(第一册)复习(原文及全文翻译)——Lesson 31 - Lesson 60
- WPF真入门教程20--数据排序
- Red Hat 向开发者免费提供企业版Red Hat Linux
- js实现排行榜(根据我微信小程序项目所分享)完整版
- Struts2 鲜为人知的调试技巧
- python 抓取lol主播排行
- burn suite启动_Microsoft计划(最终)启动Web Office Suite
- 一键读图OCR 轻松搞定任意网页上出现的文字提取
- ​川希:互联网创业赚钱就是抄抄抄,越抄越赚钱!