【问题标题】:Why is this an incorrect implementation of Fermat's Factorization?为什么这是费马分解的错误实现?
【发布时间】:2017-05-06 01:40:37
【问题描述】:

我目前正在通过 Project Euler 工作,这是我在问题 3 中的尝试(在 Python 中)。我运行了它并让它运行了大约 30 分钟。在此之后,我查看了“sum”下的数字。我发现了几个问题:其中一些数字是偶数,因此不是素数,其中一些数字甚至不是 n 的适当因数。当然,它们仅相差 0.000001(通常除法产生 x.99999230984 或其他)。我最终停在的号码是 3145819243.0。

谁能解释为什么会出现这些错误?

编辑:我对定理的解释基本上是,通过重新排列变量,您可以用 n + y^2 的平方根求解 x,并且 y 将被强制执行,直到它是一个整数。在此之后,实际的素因子将是 x+y。

这是我的代码。

import math
n = int(600851475143)
y = int(1)
while y >= 1:
    if math.sqrt(n + (y**2)).is_integer():
        x = math.sqrt(n + (y**2))
        print "x"
        print x
        print "sum"
        print x + y 
        if x + y > (600851475142/2):
            print "dead"
        else:
            print "nvm"
    y = y + 1

【问题讨论】:

  • 我给你一个提示:Sieve algorithm 这将通过 Projecteuler 和那里的许多其他人的挑战来挽救你的生命。如果您觉得很难,我可以使用Sieve algorithm 发布我对这个问题的回答。否则,请自己尝试,这是最佳做法。另外,请记住一件事:Projecteuler 的问题必须在不到一分钟的时间内解决。如果没有,你必须改变你的方法/算法/思维方式。
  • @ChihebNexus 筛子很好,但是理解为什么这种不同方法的实现不起作用会更好。欧拉项目的问题也没有时间限制。如果想使用蛮力方法,为什么不呢?
  • @njzk2 是的,你说得对。

标签: python math factorization


【解决方案1】:

大数字和浮点精度的典型问题。

当您到达y = 323734167 时,您计算出math.sqrt(n + y**2),即math.sqrt(104804411734659032)

根据 wolfram alpha,这是 3.23735095000000010811308548429078847808587868214170702... × 10^8,即不是整数,而是根据 python 的 323735095.0

如您所见,python 不具备查看 .00000001... 的精度。

您可以测试结果的平方,而不是测试is_integer

 > 323735095 ** 2
=> 104804411734659025

并查看它是否与输入匹配(不匹配,输入为104804411734659032,关闭 7)。

【讨论】:

  • 哦,好的。除此之外,实现是否正确?
  • 还有优化空间,但它看起来像是费马分解的有效实现。不过,您必须找到更好的平方根。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多