无法在 Python 上准确计算圆周率
Can't accurately calculate pi on Python
我是这里的新成员,我将直接投入其中,因为我整个星期天都在努力解决这个问题。
我是 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=Circumference/diameter。 (我有点被骗了,因为编码中有一个 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 的值将变得太大而无法处理,并且代码崩溃了。我该如何解决这个问题?)
谢谢!
您的第一个版本的算法应该更像这样:
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
以更接近圆周率。
algorithm只考虑单位圆的四分之一,即半径为1
。
四分之一圆的面积公式为:
area_c = (pi * r **2) / 4
包含这个圆的正方形的面积:
area_s = r **2
其中 r
是圆的半径。
现在比例是:
area_c / area_s
代入上面的等式,re-arange 得到:
pi = 4 * (area_c / area_s)
即将 Monte Carlo,只需用代表它们的非常大的数字替换这两个区域。通常,这里使用随机投掷飞镖的比喻。
对于第一个,你的计算应该是
pi = incircle/1000000*4 # 3.145376..
这是落在圆圈内的点数超过总点数(在我的 运行 上约为 0.785671)。
半径为 1 (random.uniform(-1,1)
),总面积为 4,因此如果将 4 乘以落在圆内的点的比率,您将得到正确答案。
我是这里的新成员,我将直接投入其中,因为我整个星期天都在努力解决这个问题。
我是 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=Circumference/diameter。 (我有点被骗了,因为编码中有一个 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 的值将变得太大而无法处理,并且代码崩溃了。我该如何解决这个问题?)
谢谢!
您的第一个版本的算法应该更像这样:
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
以更接近圆周率。
algorithm只考虑单位圆的四分之一,即半径为1
。
四分之一圆的面积公式为:
area_c = (pi * r **2) / 4
包含这个圆的正方形的面积:
area_s = r **2
其中 r
是圆的半径。
现在比例是:
area_c / area_s
代入上面的等式,re-arange 得到:
pi = 4 * (area_c / area_s)
即将 Monte Carlo,只需用代表它们的非常大的数字替换这两个区域。通常,这里使用随机投掷飞镖的比喻。
对于第一个,你的计算应该是
pi = incircle/1000000*4 # 3.145376..
这是落在圆圈内的点数超过总点数(在我的 运行 上约为 0.785671)。
半径为 1 (random.uniform(-1,1)
),总面积为 4,因此如果将 4 乘以落在圆内的点的比率,您将得到正确答案。