【问题标题】:Goldbach Conjecture in PythonPython中的哥德巴赫猜想
【发布时间】:2018-12-17 15:24:30
【问题描述】:

我试图编写一个代码,该代码返回一对满足给定 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 

【问题讨论】:

  • 是否有实际工作的场景?
  • @TobiasWilfert 不是我能找到的!

标签: python goldbach-conjecture


【解决方案1】:

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

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 

【讨论】:

    【解决方案2】:
    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 设置为下一个素数。

    【讨论】:

      【解决方案3】:
          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)
      

      【讨论】:

        【解决方案4】:

        哥德巴赫猜想仅在大于 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)            ```
        

        【讨论】:

        • 有什么改进?
        • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
        【解决方案5】:

        可以使用筛子将素数 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
        

        【讨论】:

          【解决方案6】:

          将偶数分解为一对素数的哥德巴赫分解并不是(总是)唯一的,因此您需要一种方法来选择一个可能的解决方案(根据问题的要求)。很自然的可能性是使用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)
          

          【讨论】:

            【解决方案7】:
            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)
            

            【讨论】:

            • 如果您解释了您提供的代码如何回答问题,这将是一个更好的答案。
            • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-27
            相关资源
            最近更新 更多