Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.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问题12优化的意外时间结果_Python_Python 3.x_Performance_Math_Optimization - Fatal编程技术网

Python 项目euler问题12优化的意外时间结果

Python 项目euler问题12优化的意外时间结果,python,python-3.x,performance,math,optimization,Python,Python 3.x,Performance,Math,Optimization,我已解决问题,并尝试优化我的解决方案。 我关注的部分是求除数的部分。 我认为我创建的第一个算法会比第二个慢,但事实并非如此,我不明白为什么 第一个(常规计数直到n**0.5): 从数学导入sqrt def get(n): 计数=0 极限=sqrt(n) 对于范围(1,int(limit)+1)内的i: 如果n%i==0: 计数+=2 如果limit.is_integer(): 返回计数-1 返回计数 第二(质数因子分解得到每个质数的阶数为了使用它,我使用质数的形式来计算更快,但它仍然更慢) d

我已解决问题,并尝试优化我的解决方案。
我关注的部分是求除数的部分。
我认为我创建的第一个算法会比第二个慢,但事实并非如此,我不明白为什么

第一个(常规计数直到n**0.5):

从数学导入sqrt
def get(n):
计数=0
极限=sqrt(n)
对于范围(1,int(limit)+1)内的i:
如果n%i==0:
计数+=2
如果limit.is_integer():
返回计数-1
返回计数
第二(质数因子分解得到每个质数的阶数为了使用它,我使用质数的形式来计算更快,但它仍然更慢)

def Get_designors_Amount(n):#素因子分解

在第一种方法中,如果n,则测试1到
sqrt(x)
之间的每个数字的可分性,因此测试单个数字的复杂性是
sqrt(x)
。根据公式,第一个
n
根的和可以近似为
n*sqrt(n)

方法1的时间复杂度
O(N*sqrt(N))
(N是被测试的数字总数)

在第二种方法中,有两种情况:

  • 如果一个数字不是素数,则测试所有小于等于
    n
    的素数。复杂性-
    O(n/6)=O(n)
  • 如果一个数字是素数,我们可以将复杂度近似为
    O(log(n))
    (在这种情况下,可能会有更精确的复杂度计算,我正在进行近似,因为这在证明中并不重要)
  • 对于素数,我们使用
    (n/6)
    素数测试它们,复杂性将变成
    5/6+7/6+11/6+13/6+17/6。。。。。(n之前的最后一个素数)/6
    。这可以暂时减少到
    (n之前所有素数的总和)/6
    。现在,
    N
    之前的所有素数之和可以是
    N^2/(2*logN)
    。因此,该步骤的复杂性变为
    N^2/(6*(2*logN))=N^2/(12*lognN)

    方法2的时间复杂度
    O(N^2/(12*lognN))
    (N是被测试的数字总数)


    (如果你愿意,你可以为每一步的时间复杂度设定更精确的界限。我做了一些近似,因为它有助于证明这一点,而不会做出任何过于乐观的假设)。

    你的第一个算法明智地只考虑sqrt(n)以下的除数

    但是你的第二个算法考虑的因子一直到n,尽管不可否认的是,如果n有很多因子,n会一直减少

    如果您在算法中解决了此问题,请通过更改以下内容:

    t = 6*i-1
    
    为此:

    t = 6*i-1
    if t*t > n:
      return dcount * 2
    
    那么你的第二个算法会更快


    (之所以使用
    *2
    是因为该算法最终会找到剩余的素因子(n本身),然后
    dcount*=(count+1)
    会在返回它之前将dcount加倍。)

    感谢您提供了这个伟大而全面的答案。(对不起,我还不能投票赞成)谢谢你的回复。但是你的修正不起作用,但它给了我添加'if n=1和OriginalN%n==0:return dcount*2`OriginalN是我作为n的副本在开头添加的变量