我是这里的新成员,我会直接开车,因为我整个星期天都在努力让我的头脑绕过它。
我是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
它本质上是两个轴上-1到+1平面上随机(x,y)坐标的生成器。然后,如果x ^ 2 + y ^ 2 <= 1,我们知道该点位于由坐标轴形成的框内的半径为1的圆内。
根据点的位置,incircle
或outcircle
的计数器会增加。
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
我记得,在做我的C ++课程时,被告知问题是一个常见的问题并不是由于数学问题,而是因为编码中存在某些问题,但我记不起来了。它可能与随机数生成,或使用浮点数的限制,或......真的有关。它甚至可能只是我的数学......
谁能想到问题是什么?
TL; DR:尝试计算Pi,无论我做了多少迭代,我都能接近它,但从未非常准确。
(哦和另一点 - 在第二个代码中有一行说S = 2.0 ** k。如果我将'n'设置为高于2000的任何值,则S的值变得太大而无法处理并且代码崩溃。我该如何解决这个问题?)
谢谢!
答案 0 :(得分: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)
打印:
3.14699146991
这更接近。增加n
以更接近pi。
algorithm仅考虑单位圆的四分之一,即半径为1
。
四分之一圆的面积公式为:
area_c = (pi * r **2) / 4
包含此圆圈的方块区域:
area_s = r **2
其中r
是圆的半径。
现在的比例是:
area_c / area_s
替换上面的等式,重新排列,你得到:
pi = 4 * (area_c / area_s)
去蒙特卡洛,只需用代表它们的非常高的数字替换这两个区域。通常,这里使用随机投掷的飞镖的类比。
答案 1 :(得分:2)
对于第一个,您的计算应该是
pi = incircle/1000000*4 # 3.145376..
这是在圆圈内落到总点数上的点数(我跑步时约为0.785671)。
如果半径为1(random.uniform(-1,1)
),则总面积为4,因此如果按照落入圆圈内的点的比例多次4,则会得到正确的答案。