无法准确计算Python上的pi

Stu*_*ken 7 python pi numeric montecarlo python-2.7

我是这里的新成员,我会直接进入这个,因为我整个星期天都试图绕过它.

我是Python的新手,以前在C++上学习了基础中级编码(这是一个为期10周的大学模块).

我正在尝试一些迭代技术来计算Pi,但两者都有些不准确,我不知道为什么.

我在大学教的第一种方法 - 我相信你们中的一些人之前已经看过它.

x=0.0
y=0.0
incircle = 0.0
outcircle = 0.0
pi = 0.0
i = 0
while (i<100000):
    x = random.uniform(-1,1)
    y = random.uniform(-1,1)
    if (x*x+y*y<=1):
        incircle=incircle+1
    else:
        outcircle=outcircle+1
    i=i+1
pi = (incircle/outcircle)
print pi
Run Code Online (Sandbox Code Playgroud)

它本质上是两个轴上-1到+1平面上随机(x,y)坐标的生成器.然后,如果x ^ 2 + y ^ 2 <= 1,我们知道该点位于由坐标轴形成的框内的半径为1的圆内.

根据点的位置,计数器增加incircleoutcircle.

然后,pi的值是圆圈内外的值的比率.坐标是随机生成的,所以它应该是均匀的.

但是,即使在非常高的迭代值下,我对Pi的结果总是在3.65左右.

第二种方法是另一次迭代,它计算多边形的周长,边数增加,直到多边形几乎是一个圆,然后,Pi =圆周/直径.(我有点被骗,因为编码有一个math.cos(Pi)术语,所以看起来我正在使用Pi来找到Pi,但这只是因为你不能轻易地使用度来表示Python上的角度).但即使是高迭代,最终结果似乎也在3.20左右结束,这也是错误的.代码在这里:

S = 0.0
C = 0.0
L = 1.0

n = 2.0
k = 3.0
while (n<2000):
    S = 2.0**k
    L = L/(2.0*math.cos((math.pi)/(4.0*n)))
    C = S*L
    n=n+2.0
    k=k+1.0

pi = C/math.sqrt(2.0)
print pi
Run Code Online (Sandbox Code Playgroud)

我记得,在做我的C++课程时,被告知问题是一个常见的问题,并不是由于数学问题,而是因为编码中存在某些问题,但我记不起来了.它可能与随机数生成,或使用浮点数的限制,或......真的有关.它甚至可能只是我的数学......

谁能想到问题是什么?

TL; DR:尝试计算Pi,无论我做了多少迭代,我都能接近它,但从未非常准确.

(哦和另一点 - 在第二个代码中有一行说S = 2.0**k.如果我将'n'设置为高于2000的任何值,则S的值变得太大而无法处理并且代码崩溃.我怎么能解决这个问题?)

谢谢!

Mik*_*ler 7

您的第一个版本的算法看起来应该更像这样:

from __future__ import division, print_function

import sys
if sys.version_info.major < 3:
    range = xrange

import random 


incircle = 0
n = 100000
for n in range(n):
    x = random.random()
    y = random.random()
    if (x*x + y*y <= 1):
        incircle += 1
pi = (incircle / n) * 4
print(pi)
Run Code Online (Sandbox Code Playgroud)

打印:

3.14699146991
Run Code Online (Sandbox Code Playgroud)

这更接近了.增加n以更接近pi.

算法仅考虑单位圆的四分之一,即半径为1.

四分之一圆的面积公式为:

area_c = (pi * r **2) / 4
Run Code Online (Sandbox Code Playgroud)

对于包含此圆圈的方块区域:

area_s = r **2
Run Code Online (Sandbox Code Playgroud)

r圆的半径在哪里.

现在的比例是:

area_c / area_s
Run Code Online (Sandbox Code Playgroud)

替换上面的等式,重新安排,你得到:

pi = 4 * (area_c / area_s)
Run Code Online (Sandbox Code Playgroud)

去蒙特卡洛,只需用代表它们的非常高的数字替换这两个区域.通常,这里使用随机投掷的飞镖的类比.