费马分解方法极限
我正在尝试实现 Fermat 分解(计算机编程艺术,第 2 卷中的算法 C)。不幸的是,在我的版本(ISBN 81-7758-335-2)中,该算法打印不正确。下面的因子内循环的条件应该是什么?我正在运行循环,直到 y <= n [作为限制传入]。
(if (< limit y) 0 (factor-inner x (+ y 2) (- r y) limit))
有没有办法完全避免这种情况,因为它会使循环速度加倍?
(define (factor n)
(let ((square-root (inexact->exact (floor (sqrt n)))))
(factor-inner (+ (* 2 square-root) 1)
1
(- (* square-root square-root) n)
n)))
(define (factor-inner x y r limit)
(if (= r 0)
(/ (- x y) 2)
(begin
(display x) (display " ") (display y) (display " ") (display r) (newline)
;;(sleep-current-thread 1)
(if (< r 0)
(factor-inner (+ x 2) y (+ r x) limit)
(if (< limit y)
0
(factor-inner x (+ y 2) (- r y) limit))))))
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
( 检查是不必要的,因为在最坏的情况下,算法最终会找到这个解决方案:
然后它将返回 1。
The
(< limit y)
check is not necessary because, worst-case, the algorithm will eventually find this solution:It will then return 1.
纵观算法C,问题似乎出在递归步骤上,每当
r <<时,递归步骤就会有效地跳过步骤C4。 0
,因为x
不递增,而r
仅递减y
。使用 1998 年版 Vol 中的
a
、b
和r
表示法。 2(ISBN 0-201-89684-2),Scheme 版本如下:编辑添加:基本上,我们正在做一个反复检查是否
为 0 的技巧,我们正在做通过简单地跟踪当我们增加
a
或b
时r
如何变化即可。如果我们在上面的r
表达式中将b
设置为b+2
,则相当于减少r
由b
的旧值决定,这就是为什么两者在算法的步骤 C4 中并行完成的原因。我鼓励您扩展上面的代数表达式并说服自己这是正确的。只要
r > 0
,你想不断减少它来找到正确的b
值,所以你不断重复步骤C4。但是,如果超出范围,并且 r0
,你需要增加它。您可以通过增加a
来实现此目的,因为将a
增加 2 相当于将r
减少a
的旧值>,如步骤 C3 中所示。你总会有a >; b
,因此在步骤 C3 中将r
增加a
会自动使r
再次为正值,因此您只需直接进入步骤 C4 。证明
a > 也很容易。 b。我们从明显大于
b
的a
开始,如果我们将b
增加到b = a - 2
code>,我们有这意味着
N
是素数,因为它小于sqrt(N)
的最大因子是 1,算法终止。Looking through Algorithm C, it looks like the issue is with the recursion step, which effectively skips step C4 whenever
r < 0
, becausex
is not incremented andr
is only decremented byy
.Using the notation of
a
,b
andr
from the 1998 edition of Vol. 2 (ISBN 0-201-89684-2), a Scheme version would be as follows:EDIT to add: Basically, we are doing a trick that repeatedly checks whether
is 0, and we're doing it by simply tracking how
r
changes when we incrementa
orb
. If we were to setb
tob+2
in the expression forr
above, it's equivalent to reducingr
by the old value ofb
, which is why both are done in parallel in step C4 of the algorithm. I encourage you to expand out the algebraic expression above and convince yourself that this is true.As long as
r > 0
, you want to keep decreasing it to find the right value ofb
, so you keep repeating step C4. However, if you overshoot, andr < 0
, you need to increase it. You do this by increasinga
, because increasinga
by 2 is equivalent to decreasingr
by the old value ofa
, as in step C3. You will always havea > b
, so increasingr
bya
in step C3 automatically makesr
positive again, so you just proceed directly on to step C4.It's also easy to prove that
a > b
. We start witha
manifestly greater thanb
, and if we ever increaseb
to the point whereb = a - 2
, we haveThis means that
N
is prime, as the largest factor it has that is less thansqrt(N)
is 1, and the algorithm has terminated.