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的副本在开头添加的变量