Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 试图定义一个Euler';s近似为pi,获取';列表和';int';_Python_Pi_Approximation - Fatal编程技术网

Python 试图定义一个Euler';s近似为pi,获取';列表和';int';

Python 试图定义一个Euler';s近似为pi,获取';列表和';int';,python,pi,approximation,Python,Pi,Approximation,我试图使用Euler的一种方法在python中定义一个函数,该函数将近似于pi。他的公式如下: 到目前为止,我的代码是: def pi_euler1(n): numerator = list(range(2 , n)) for i in numerator: j = 2 while i * j <= numerator[-1]: if i * j in numerator: numer

我试图使用Euler的一种方法在python中定义一个函数,该函数将近似于
pi
。他的公式如下:

到目前为止,我的代码是:

def pi_euler1(n):
    numerator = list(range(2 , n))
    for i in numerator:
        j = 2
        while i * j <= numerator[-1]:
            if i * j in numerator:
                numerator.remove(i * j)
            j += 1
    for k in numerator:
        if (k + 1) % 4 == 0:
            denominator = k + 1
        else:
            denominator = k - 1
    #Because all primes are odd, both numbers inbetween them are divisible by 2,
    #and by extension 1 of the 2 numbers is divisible by 4
    term = numerator / denominator
def pi_euler1(n):
分子=列表(范围(2,n))
对于分子中的i:
j=2

当i*j在
术语=分子/分母时,你将一个列表除以一个数字,这是没有意义的。将
k
除以循环中的分母,以便将
分子
元素逐个用于等式的每个因子。然后您可以将它们重复相乘为术语
term*=i/分母
,您在开始时将其初始化为
term=1


另一个问题是第一个循环,它不会给出第一个
n
素数。例如,对于
n=3
列表(范围(2,n))=[2]
。因此,唯一的素数是2

以下是代码,经过一些小的修改后可以正常工作:

import math
def pi_euler1(n):
    lim = n * n + 4
    numerator = list(range(3, lim, 2))
    for i in numerator:
        j = 3
        while i * j <= numerator[-1]:
            if i * j in numerator:
                numerator.remove(i * j)
            j += 2
    euler_product = 1
    for k in numerator[:n]:
        if (k + 1) % 4 == 0:
            denominator = k + 1
        else:
            denominator = k - 1
        factor = k / denominator
        euler_product *= factor
    return euler_product * 4

print(pi_euler1(3))
print(pi_euler1(10000))
print(math.pi)
备注:

  • 您只需要奇数素数,因此可以从奇数列表开始
  • j
    可以从
    3
    开始,并以2的步长递增。事实上,
    j
    可以从
    i
    开始,因为
    i
    小于
    i*i
    的所有倍数都已在前面删除
  • 一般来说,从正在迭代的列表中删除元素是非常糟糕的做法。见例。在内部,Python在其迭代的列表中使用索引。巧合的是,在这种特定情况下,这不是问题,因为只有大于当前值的数字才会被删除
  • 此外,从一个很长的列表中删除元素的速度非常慢,因为每次都需要移动完整的列表以填补空白。因此,最好使用两个单独的列表
  • 您没有计算结果产品,也没有退货
  • 正如你所注意到的,这个公式收敛得非常慢
  • 如评论中所述,以前的版本将
    n
    解释为最高素数的限制,而实际上
    n
    应该是素数。我修改了代码来纠正这一点。在上述版本中,有一个粗略的限制;下面的版本尝试对极限进行更严格的近似
这是一个经过修改的版本,没有从您正在迭代的列表中删除。它不是删除元素,而是标记它们。这要快得多,因此可以在合理的时间内使用较大的
n

import math
def pi_euler_v3(n):
    if n < 3:
        lim = 6
    else:
        lim = n*n
        while lim / math.log(lim) / 2 > n:
            lim //= 2
    print(n, lim)

    numerator = list(range(3, lim, 2))
    odd_primes = []
    for i in numerator:
        if i is not None:
            odd_primes.append(i)
            if len(odd_primes) >= n:
                break
            j = i
            while i * j < lim:
                numerator[(i*j-3) // 2] = None
                j += 2
    if len(odd_primes) != n:
       print(f"Wrong limit calculation, only {len(odd_primes)} primes instead of {n}")
    euler_product = 1
    for k in odd_primes:
        denominator = k + 1 if k % 4 == 3 else k - 1
        euler_product *= k / denominator
    return euler_product * 4

print(pi_euler_v2(100000))
print(math.pi)

谢谢你,我已经完成了你建议的所有工作,并将素数的范围更改为n+1,以便包括n,我还添加了第三个for循环,以迭代I/分母,如你所说。我对pi_euler(10)的输出是0.04486。。。更大的数字只会得到非常小的浮点输出,我会摆弄它,看看哪里出错了。不过,谢谢你,我现在有了它工作原理的前提,我认为将素数范围更改为n+1是不够的,因为在一般情况下,你不知道你的最大素数是什么(例如,第三个素数是5,不包括在n+1=4中)。更好的方法是:从一个空列表开始,找到下一个素数,然后继续追加,直到列表的长度
n
。找到有效的素数生成算法应该很容易。如果你从
分子=列表(范围(3,n,2))
开始,你将不会得到
n
第一个素数的列表,这就是问题的定义。“…它计算乘积中前n个项的值…”,这是对
n
的不同解释。解决方案是用一个足够大的数字乘以n,以获得数组限制。我宁愿以增量方式构建素数列表。但我不是素数算法的专家。从一个随机长度的列表开始听起来不是一个好的通用方法,事实上,以块的形式构建列表的额外优势是需要更少的内存。您只需要固定块长度的内存,以及存储
n
素数的内存。上面的新版本试图计算一个好的极限。
3.28125
3.148427801913721
3.141592653589793
import math
def pi_euler_v3(n):
    if n < 3:
        lim = 6
    else:
        lim = n*n
        while lim / math.log(lim) / 2 > n:
            lim //= 2
    print(n, lim)

    numerator = list(range(3, lim, 2))
    odd_primes = []
    for i in numerator:
        if i is not None:
            odd_primes.append(i)
            if len(odd_primes) >= n:
                break
            j = i
            while i * j < lim:
                numerator[(i*j-3) // 2] = None
                j += 2
    if len(odd_primes) != n:
       print(f"Wrong limit calculation, only {len(odd_primes)} primes instead of {n}")
    euler_product = 1
    for k in odd_primes:
        denominator = k + 1 if k % 4 == 3 else k - 1
        euler_product *= k / denominator
    return euler_product * 4

print(pi_euler_v2(100000))
print(math.pi)
3.141752253548891
3.141592653589793