1

我试图编写一个代码,该代码返回一对满足给定 N 的哥德巴赫猜想的一对。猜想指出,每个大于 4 的偶数都可以表示为两个素数之和。该函数返回稍微偏离的一对,例如,goldbach(34) 返回 (5, 31) 而不是正确答案 (3, 31)。类似地,goldbach(38) 返回 (11, 31)。有什么想法我在这里出错了吗?我知道这段代码效率不高,但这是我被要求为我的作业编写代码的方式。

def eratosthenes(n):
    primes = list (range(2, n+1))
    for i in primes:
        j=2
        while i*j<= primes[-1]:
            if i*j in primes:
                primes.remove(i*j)
            j=j+1
    return primes

def odd_primes(N):
    oddprimes = eratosthenes(N)
    oddprimes.remove(2)
    return(oddprimes)

def goldbach(N):
    x, y = 0, 0
    result = 0
    if N % 2 == 0:
        prime = odd_primes(N)
        while result != N:
            for i in range(len(prime)):
                x = prime[i]
                if result == N: break
                for j in range(len(prime)):
                    y = prime[j]
                    result = x + y
                    if result == N: break 
    return x, y 
4

7 回答 7

3

x一旦满足条件,您就在中断循环之前进行分配。break只需在第一个for循环中反转您的行:

def goldbach(N):
    x, y = 0, 0
    result = 0
    if N % 2 == 0:
        prime = odd_primes(N)
        while result != N:
            for i in range(len(prime)):
                if result == N: break  # this line first
                x = prime[i]   # this line after
                for j in range(len(prime)):
                    y = prime[j]
                    result = x + y
                    if result == N: break 
    return x, y 
于 2018-12-17T15:30:59.867 回答
3
def eratosthenes(n):
    primes = list (range(2, n+1))
    for i in primes:
        j=2
        while i*j<= primes[-1]:
            if i*j in primes:
                primes.remove(i*j)
            j=j+1
    return primes

def odd_primes(N):
    oddprimes = eratosthenes(N)
    oddprimes.remove(2)
    return(oddprimes)

def goldbach(N):
    x, y = 0, 0
    result = 0
    if N % 2 == 0:
        prime = odd_primes(N)
        while result != N:
            for i in range(len(prime)):
                if result == N: break 
                x = prime[i]
                for j in range(len(prime)):
                    y = prime[j]
                    result = x + y
                    if result == N: break 
    return x, y 

是正确的版本。当你找到一对时,你将 x 设置为下一个素数。

于 2018-12-17T15:31:12.987 回答
0

哥德巴赫猜想仅在大于 2 的偶数中观察到,因此我改进了 Punnie 的答案以捕捉奇数和任何少做 2 的数字。

def isPrime(n):
    for i in range(2,n):
        if n%i == 0:
            return 0
    return 1

def goldbach(no):
  if no%2 !=0 :
    return "Error {} is not an even number ".format(no) 
  elif no <= 2:
    return "Error {} is not greater than 2, Goldbach Conjecture is observed only in even numbers greater than 2".format(no)

  else:
      for i in range(3,no):
          if isPrime(i) == 1:
              for l in range(i,no):
                  if isPrime(l) == 1:
                      if no == (i+l):
                          print(i,"+",l,"=",no)

no = int(input("Enter Even Number greater than 2: "))
goldbach(no)            ```
于 2021-09-12T22:13:03.020 回答
0

可以使用筛子将素数 1 (mod 6) 与素数 -1 (mod 6) 分开,这样可以在不使用 for 循环的情况下使用 numpy 加速:

import numpy as np

def sieve(n):
    P5m6 =np.ones((n//6+1), dtype=bool)
    P1m6 =np.ones((n//6+1), dtype=bool)
    for i in range(1,int((n**0.5+1)/6)+1):
        if P5m6[i]:
            P5m6[6*i*i::6*i-1]=[False]
            P1m6[6*i*i-2*i::6*i-1]=[False]
        if P1m6[i]:
            P5m6[6*i*i::6*i+1]=[False]
            P1m6[6*i*i+2*i::6*i+1]=[False]
    return P5m6,P1m6


def goldbach(n):
    P5m6,P1m6=sieve(n)
    nmod6=n%6
    if nmod6==0:
        r=(6*np.nonzero(P5m6[1:n//6]&P1m6[n//6-1:0:-1])[0]+5)[0]
    elif nmod6==2:
        if P5m6[n//6]:
            r=3
        else:
            r=(6*np.nonzero(P1m6[1:(n-6)//12+(n//6-1)%2+1]&P1m6[n//6-1:(n-6)//12:-1])[0]+7)[0]
    elif nmod6==4:
        if P1m6[n//6]:
            r=3
        else:
            r=(6*np.nonzero(P5m6[1:n//12+(n//6)%2+1]&P5m6[n//6:n//12:-1])[0]+5)[0]
    else:
        r=0
    return r,n-r
于 2021-10-24T08:23:07.723 回答
0

将偶数分解为一对素数的哥德巴赫分解不是(总是)唯一的,因此您需要一种方法来选择一个可能的解决方案(根据问题的要求)。一个自然的可能性是使用min/max功能。

我没有使用函数odd_primes(只是一个切片),而是goldbach使用组合方法重新实现了函数。

import itertools as it

def eratosthenes(n):
    primes = list (range(2, n+1))
    for p in primes:
        j = 2
        while p*j <= primes[-1]:
            if p*j in primes:
                primes.remove(p*j)
            j += 1
    return primes

def goldbach(n):
    if n % 2 != 0 or n <= 2: raise Exception('Conjecture assumptions not satisfied.')
    ps = eratosthenes(n)[1:]
    # trivial cases to overcome limitations of the combinations
    if n == 4: return [(2, 2)]
    if n == 6: return [(3, 3)]

    return max(it.combinations(ps, 2), key=lambda p: p[1] if sum(p) == n else 0)

for n in range(6, 40, 2):
    print(n, goldbach(n))

输出

8 (3, 5)
10 (3, 7)
12 (5, 7)
14 (3, 11)
16 (3, 13)
18 (5, 13)
20 (3, 17)
22 (3, 19)
24 (5, 19)
26 (3, 23)
28 (5, 23)
30 (7, 23)
32 (3, 29)
34 (3, 31)
36 (5, 31)
38 (7, 31)
于 2021-10-24T13:22:45.317 回答
0
    def isPrime(n):
        for i in range(2,n):
            if n%i == 0:
                return 0
        return 1

    no = int(input("Enter Number: "))

    for i in range(3,no):
        if isPrime(i) == 1:
            for l in range(i,no):
                if isPrime(l) == 1:
                    if no == (i+l):
                        print(i,"+",l,"=",no)
于 2020-01-23T17:16:40.310 回答
0
def is_prime(a):
    for div in range(2, a//2 + 1):
        if a % div == 0:
            return False
    return True


def goldbach(n):
    summ = 0
    for p1 in range(2, n):
        if is_prime(p1) and is_prime(n-p1):
            p2 = n-p1
            return str(n)+"="+str(p1)+"+"+str(p2)
于 2022-03-01T18:23:10.597 回答