Python 调查结果6648031207514';最大主因子

Python 调查结果6648031207514';最大主因子,python,jupyter-notebook,Python,Jupyter Notebook,这是我的第一个问题 我一直在解决eulerproject.net问题,并且在得到给定输入的正确答案之后 我想尝试不同的方法来检查我的代码是否正常工作。好像没有 最大的素因子应该是1137193159,但我得到79。当然是因为我设定的上限 在这里然而,如果我增加一点上限,我的代码就会变得非常慢 这是我用来寻找最大素因子的函数 def largest_prime_factor(n) : upper_limit = math.trunc((n**0.5)) while(1) : for

这是我的第一个问题

我一直在解决eulerproject.net问题,并且在得到给定输入的正确答案之后 我想尝试不同的方法来检查我的代码是否正常工作。好像没有

最大的素因子应该是1137193159,但我得到79。当然是因为我设定的上限 在这里然而,如果我增加一点上限,我的代码就会变得非常慢

这是我用来寻找最大素因子的函数

def largest_prime_factor(n) :

upper_limit = math.trunc((n**0.5))

while(1) : 

    for num in range(upper_limit, 2, -1) : 
        if n % num == 0 :
            if(isPrime(num)) : 
                return num 
        else : 
            pass

    if(isPrime(n)) : 
        return n 
这里是isprime方法

## taken from : https://stackoverflow.com/questions/15285534/isprime-function-for-python-language
def isPrime(n):
if n==2 or n==3: return True
if n%2==0 or n<2: return False
for i in range(3, int(n**0.5)+1, 2):   # only odd numbers
    if n%i==0:
        return False    

return True
##摘自:https://stackoverflow.com/questions/15285534/isprime-function-for-python-language
def iPrime(n):
如果n==2或n==3:返回True
如果n%2==0或n修复软件

  • 最大素数因子可以大于sqrt(n)。软件仅返回到sqrt(n)
  • 对于范围内的num(上限,1,-1),范围“range”(上限,2,-1):”应该是
    ,因为停止点是独占的
  • 不应使用while循环进行循环
  • 在for循环之后,不需要检查数字是否为素数
问题

import math

def largest_prime_factor(n) :

  upper_limit = math.trunc((n**0.5))

  for num in range(upper_limit, 1, -1) : # use 1 for lower limit
      if n % num == 0 :
          if(isPrime(num)) : 
              return max(num, n // num)  # to include values above sqrt(n)

  #if(isPrime(n)) : 
  return n  # We know it's prime since no divisors in for loop

def isPrime(n):
  if n==2 or n==3: return True
  if n%2==0 or n<2: return False
  for i in range(3, int(n**0.5)+1, 2):   # only odd numbers
      if n%i==0:
          return False    

  return True
print(largest_prime_factor(1137193159 )) # Output: 1137193159 
# Timing (using timeit):  0.01357 seconds per calculation
上面修复了代码,但剩下的问题是算法复杂度将是O(n)

  • O(sqrt(n))for循环的大小
  • 要运行的O(sqrt(n))是每个循环中的_素数
  • 1和2使复杂性为O(n)
  • 重构代码

    import math
    
    def largest_prime_factor(n) :
    
      upper_limit = math.trunc((n**0.5))
    
      for num in range(upper_limit, 1, -1) : # use 1 for lower limit
          if n % num == 0 :
              if(isPrime(num)) : 
                  return max(num, n // num)  # to include values above sqrt(n)
    
      #if(isPrime(n)) : 
      return n  # We know it's prime since no divisors in for loop
    
    def isPrime(n):
      if n==2 or n==3: return True
      if n%2==0 or n<2: return False
      for i in range(3, int(n**0.5)+1, 2):   # only odd numbers
          if n%i==0:
              return False    
    
      return True
    
    print(largest_prime_factor(1137193159 )) # Output: 1137193159 
    # Timing (using timeit):  0.01357 seconds per calculation
    
    更好的算法(更接近O(sqrt(n)*log(n))时间复杂度

    优势

    • 对于一批数字,Erastosenes的筛选更好——O(n logn logn)找到范围内的素数,然后对数(n)每个数字。对于单个数字,这将是O(n*logn))
    • 当前的算法对于单个数字更好——没有设置,所以每个数字都有O(sqrt(n)*log(n))

      求最大素因子的函数 def最大基本系数(n):

    比较

    n=1137193159的定时

    • 最大素数因数:.0061秒
    • 最大因数:0.01357秒

    因此:
    isPrime()
    方法比原始代码提高了约2倍。您可以通过使用erastoscenes筛选来更改
    isPrime()
    方法。因为您只检查根(n)数,所以您必须创建一个大小为根(n)的筛选。然后,您的时间复杂度将从O(n)降低到O(根(n)。@mooncarter--is O(n log log n),这有助于查找范围内的所有素数。考虑到这一开销,如何将复杂性降低到O(sqrt(n)),以便使用筛子查找一个数字的最大素数因子?这意味着使用素数列表,is_素数将变为O(1),但首先会产生O(n*log n)查找所有素数的开销。是的,伙计,你明白了。我创建了一个自定义的因式分解模块,它使用Erastohenes筛选,并且是非概率的。它还可以减少PARI/ECM无法通过直接因式分解分解分解的较大数,但是可以使用它在PARI/ECM上创建的伪素数来减少,因此可以结合使用它来减少e数字2*1200-1,你不能直接使用PARI/ECM快速完成。如果你对它感兴趣,你可以在这里找到它:它还包括一种用于二次幂的超快速模量缩减技术