GLH*_*LHF 2 python math mathematical-optimization while-loop python-3.4
我正在解决Project Euler 中的一个问题;我在 SO 中发现了一个问题。问题和接受的答案说;
n = 600851475143
i = 2
while i * i < n:
while n%i == 0:
n = n / i
i = i + 1
print (n)
Run Code Online (Sandbox Code Playgroud)
这太棒了。我还是不明白这个过程怎么这么快,竟然能在 0.00001 秒内找到 6000 亿的最大质因数。我为此尝试了大量方法和代码,过程耗时超过 1 小时。
谁能向我解释这些代码的逻辑以及为什么它超快?被while循环有Python中一个特殊的地方?
该算术基本定理指出,每一个大于1的整数可以表示为素数的乘积。例如,数字 2100 可以这样表示:
2 x 2 x 3 x 5 x 5 x 7
我已经安排了它,所以最大的质因数在右边,在这种情况下是 7。这个算法正在做的是从 2 开始并除以n(即“删除”那个因数)直到没有更多的要删除(模 0在除法之前,步骤检查它是否可以干净地整除。)
因此,按照代码,我们将有i= 2 和n= 2100,或者
2 x 2 x 3 x 5 x 5 x 7
2100 可以被 2 ( 2100 % 2 == 0)整除,也是因为我们在上面的分解中看到了 2。所以除以 2 得到 1050,或者
2 x 3 x 5 x 5 x 7
继续除以 2,再一次,得到一个不能被 2 整除的数,即 525,或
3 x 5 x 5 x 7
然后我们增加到i3 并继续。看看最后我们将如何得到最高的质因数?
第一个 while 循环的原因i * i < n(确实应该是i * i <= n)是因为
如果一个数的一个除数或因数(完美平方除外)大于其平方根,则另一个因数将小于其平方根。因此,不需要考虑所有大于n平方根的素数倍数。
来自:http : //britton.disted.camosun.bc.ca/jberatosthenes.htm
因此,如果i大于 的平方根n,则意味着所有剩余的因子都有一个我们已经找到的“对”,低于 的平方根n。使用的检查i * i <= n等效但比进行平方根计算更快。
之所以如此之快,而其他蛮力方法如此之慢,是因为这将每个步骤中的数量进行了划分,从而以指数方式减少了需要完成的步骤数量。
要看到这一点,600851475143 的质因数分解是
71 x 839 x 1471 x 6857
如果您修改代码以阅读:
n = 600851475143
i = 2
while i * i <= n:
while n%i == 0:
print "Dividing by %d" % i
n = n / i
i = i + 1
if n > 1:
print n
Run Code Online (Sandbox Code Playgroud)
你会看到的:
>>>
Dividing by 71
Dividing by 839
Dividing by 1471
6857
Run Code Online (Sandbox Code Playgroud)
这表明这正是它的工作方式。