Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.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 哥德巴赫猜想——找出一个偶数可以写成两个素数之和的方法_Python_Math - Fatal编程技术网

Python 哥德巴赫猜想——找出一个偶数可以写成两个素数之和的方法

Python 哥德巴赫猜想——找出一个偶数可以写成两个素数之和的方法,python,math,Python,Math,我想知道一个给定的正偶数可以写成两个素数之和的方法有多少 目前,我有以下代码: n = int(input(">")) def genprimes(n):#generate primes from 2 to n primes = [] for i in range(2,n): prime = True for a in range(2,i): if i % a == 0: prime =

我想知道一个给定的正偶数可以写成两个素数之和的方法有多少

目前,我有以下代码:

n = int(input(">"))
def genprimes(n):#generate primes from 2 to n
    primes = []
    for i in range(2,n):
        prime = True
        for a in range(2,i):
            if i % a == 0:
                prime = False
        if prime == True:
            primes.append(i)
    return primes

pairs = []
primes = genprimes(n)

for prime1 in primes:
    for prime2 in primes:
        if prime1 + prime2 == n and [prime1,prime2] not in pairs and [prime2,prime1] not in pairs:
            pairs.append([prime1,prime2])
print(len(pairs))

它是有效的,但是当n超过10000时,它会变得有点慢。有没有人能想出一种更有效的方法来找到这个值,以便快速得到高值的结果?

您有两种缓慢的算法

要获得素数列表,请分别检查每个素数。获取素数列表的最快方法是使用预构建的素数列表,这就是我为此类问题所做的。最多2**16 65536的素数列表只需要6542个整数,我将该列表存储在一个模块中。您可能更喜欢使用,这通常被认为是从零开始获取此类列表的最快方法


然后尝试每对素数,看看它们是否增加到目标数。对于每个素数p,看n-p是否也是素数会快得多。正如@Shubham所建议的那样,你可以用二进制搜索来检查n-p,但如果有两个索引,可能会更快,一个定期上升并产生p,另一个根据需要下降以检查n-p。将主列表复制到一个集合中,并用它检查列表中是否有n-p,这可能是最快的方法。最后两种技术的阶数为n,但对于仅高达10000的数字,开销可能会影响哪种技术最好。是的,对于这些问题,10000不是很大。最后,如果内存不是问题,@BoulderKeith指出,您可以将素数列表保留为布尔值的真/假列表,并非常快速地检查n-p是否为素数这是所有技术中最快、消耗内存最多的技术。

这可以通过优化程序的两个部分来有效地完成

首先,我们可以通过使用Eratosthenes筛生成素数来优化genprime,该筛可以在onlogn中生成高达n的素数

在那之后,一旦我们有了素数列表,我们可以执行以下操作:

遍历素数列表并选择一个素数,比如p1。 使用二进制搜索检查素数列表中是否也存在n-p1。 如果p=到n的素数

那么这部分的复杂性将是Oplogp

正如我们所建议的,从的答案中,我们可以在获得基本列表后建立Op解决方案

第二部分的实施第一部分是标准:


这是来自的建议的实际解决方案,它使用Eratosthenes的筛来有效地生成素数,然后查看n素数是否也是素数

因此,需要将正确的解决方案数减半并四舍五入,以防止重复

n = int(input(">"))
def genprimes(n):
    limitn = n+1
    not_prime = set()
    primes = []

    for i in range(2, limitn):
        if i in not_prime:
            continue
        for f in range(i*2, limitn, i):
            not_prime.add(f)
        primes.append(i)
    return primes

nos=0
primes = genprimes(n)

for prime in primes:
    if n-prime in primes:
        nos += 1
print(str(int((nos/2)+0.5)))

如果内存不是问题,您可以通过以下方式进一步优化速度:

1从2..n构建数组,如果i为素数,则数组[i]=true。可以使用埃拉托斯坦筛或更高级的东西


2对于所有2,给定排序的素数列表n = int(input(">")) def genprimes(n): limitn = n+1 not_prime = set() primes = [] for i in range(2, limitn): if i in not_prime: continue for f in range(i*2, limitn, i): not_prime.add(f) primes.append(i) return primes nos=0 primes = genprimes(n) for prime in primes: if n-prime in primes: nos += 1 print(str(int((nos/2)+0.5)))
    def prim(n):
        primes = []
        for num in range(1, n + 1):     # current number check
            limit = int(num ** 0.5) + 1 # search limit
            for div in range(2, limit): # searching for divider
                if (num % div) == 0:    # divider found
                    break               # exit the inner loop
            else:                       # out of the inner loop
                primes.append(num)      # no divider found hence prime
        return(primes)

    num = int(input('Input an even number: '))
    primes = prim(num)                  # create list of primes

    for i in range(num//2 + 1):
        if num % 2 != 0:
            print(num, 'not even'); break
        if i in primes and (num - i) in primes:
            print(i, '+', num - i)
"""
Examples:
=========
Input an even number: 18
1 + 17
5 + 13
7 + 11

Input an even number: 88
5 + 83
17 + 71
29 + 59
41 + 47

Input an even number: 17
17 not even
"""