为什么不是';难道我的python程序不能收敛到pi吗?

为什么不是';难道我的python程序不能收敛到pi吗?,python,random,statistics,pi,Python,Random,Statistics,Pi,我写了这个方法: def approx_pi(n, p): """ Approximates Pi by putting dots in a square and counting the dots in the max possible circle in that square. :param n: Number of dots :param p: Precision used for urandom :return: Approximatio

我写了这个方法:

def approx_pi(n, p):
    """
    Approximates Pi by putting dots in a square and counting
    the dots in the max possible circle in that square.
    :param n: Number of dots
    :param p: Precision used for urandom
    :return: Approximation of Pi
    """
    in_circle = 0
    k = 100
    max_int = (2**(8*p)-1)
    for i in range(n):
        # get two random Numbers between 0 and 1
        x = int.from_bytes(os.urandom(p), byteorder='big')/max_int
        y = int.from_bytes(os.urandom(p), byteorder='big')/max_int

        if x ** 2 + y ** 2 <= 1:
            in_circle += 1

        # Just for debugging
        if (i+1) % k == 0:
            k = int(k*1.01)
            print(i, '\t',4*in_circle/i)
            sys.stdout.flush()

    return 4*in_circle/n
def近似值(n,p):
"""
通过将点放在正方形中并计数来近似Pi
正方形中最大可能圆中的点。
:参数n:点数
:param p:用于Uradom的精度
:return:Pi的近似值
"""
圆内=0
k=100
最大整数=(2**(8*p)-1)
对于范围(n)中的i:
#获取两个介于0和1之间的随机数
x=int.from_字节(os.uradom(p),byteorder='big')/max_int
y=int.from_字节(os.uradom(p),byteorder='big')/max_int

首先,如果x**2+y**2。你的代码很混乱。最好用一个能让您了解变量含义的名称来调用变量

我已将代码简化为必要的行。因此,我使用随机库来生成点位置

这种方法的问题是它收敛得非常慢。以10*8分,我得了3.14167604分

import random


def approx_pi(points):
    """
    Approximates Pi by putting dots in a square and counting
    the dots in the max possible circle in that square.
    :param points: Number of dots
    :return: Approximation of Pi
    """
    in_circle = 0
    for dummy_i in xrange(points):
        # get two random Numbers between 0 and 1
        x_dot_position = random.random()
        y_dot_position = random.random()

        if x_dot_position ** 2 + y_dot_position ** 2 <= 1:
            in_circle += 1

    return 4.0*in_circle/points
随机导入
def近似值(点):
"""
通过将点放在正方形中并计数来近似Pi
正方形中最大可能圆中的点。
:参数点:点数
:return:Pi的近似值
"""
圆内=0
对于X范围内的虚拟_i(点):
#获取两个介于0和1之间的随机数
x_dot_position=random.random()
y_dot_position=random.random()

如果x\u点位置**2+y\u点位置**2我猜你开始涉足蒙特卡罗方法了。使用蒙特卡罗方法时,生成的随机数必须具有均匀分布,才能得到准确的近似值。尝试使用:

import random

random.uniform(0,1)
这将产生更好的结果。伊万托尔绝对正确,精确的近似值需要大样本量。这里有一个链接到维基百科上的蒙特卡罗方法:本文的引言部分将详细介绍您现在正在研究的内容。干杯


编辑:您还可以增加random.uniform(0,1)的范围,然后相应地调整算法以获得性能的略微提高。

如果您使用
x=int.from_字节(os.uradom(p),byteorder='big')
y
模拟)是否有效如果x**2+y**2,
n
p
的值是多少?@Stefan,我选择n:=1.000.000和p\in{1,2,3,4}.@koffein这真是一个好观点!不幸的是,到目前为止,它似乎没有任何效果,但我正在增加数量并进行更多的测试。@Finn还有一件事:选择
n>max\u int**2
,没有任何好处,因为在这种情况下,您还可以采取所有可能的
(x,y)
-组合,您会得到更好的结果。谢谢。我认为我们不应该使用
random.random()
最主要的是,返回值在
[0,1)
中,因此我们将得到一个pi>pi。根据python文档,它的保护程序将使用
os.urandom()
import random

random.uniform(0,1)