费马分解方法极限

发布于 2024-08-25 03:22:44 字数 882 浏览 3 评论 0 原文

我正在尝试实现 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))))))

I am trying to implement Fermat's factorization (Algorithm C in The Art of Computer Programming, Vol. 2). Unfortunately in my edition (ISBN 81-7758-335-2), this algorithm is printed incorrectly. what should be the condition on factor-inner loop below? I am running the loop till y <= n [passed in as limit].

(if (< limit y) 0 (factor-inner x (+ y 2) (- r y) limit))

Is there anyway to avoid this condition altogether, as it will double the speed of loop?

(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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟酒忠诚 2024-09-01 03:22:44

( 检查是不必要的,因为在最坏的情况下,算法最终会找到这个解决方案:

x = N + 2

y = N

然后它将返回 1。

The (< limit y) check is not necessary because, worst-case, the algorithm will eventually find this solution:

x = N + 2

y = N

It will then return 1.

强者自强 2024-09-01 03:22:44

纵观算法C,问题似乎出在递归步骤上,每当r <<时,递归步骤就会有效地跳过步骤C4。 0,因为x不递增,而r仅递减y

使用 1998 年版 Vol 中的 abr 表示法。 2(ISBN 0-201-89684-2),Scheme 版本如下:

(define (factor n) 
  (let ((x (inexact->exact (floor (sqrt n)))))
    (factor-inner (+ (* x 2) 1)
                  1
                  (- (* x x) n))))

(define (factor-inner a b r)
  (cond ((= r 0) (/ (- a b) 2))
        ((< 0 r) (factor-inner a       (+ b 2) (- r b)))
        (else    (factor-inner (+ a 2) (+ b 2) (- r (- a b))))))

编辑添加:基本上,我们正在做一个反复检查是否

r <- ((a - b) / 2)*((a + b - 2)/2) - N

为 0 的技巧,我们正在做通过简单地跟踪当我们增加 abr 如何变化即可。如果我们在上面的 r 表达式中将 b 设置为 b+2,则相当于减少 rb 的旧值决定,这就是为什么两者在算法的步骤 C4 中并行完成的原因。我鼓励您扩展上面的代数表达式并说服自己这是正确的。

只要 r > 0,你想不断减少它来找到正确的b值,所以你不断重复步骤C4。但是,如果超出范围,并且 r 0,你需要增加它。您可以通过增加 a 来实现此目的,因为将 a 增加 2 相当于将 r 减少 a 的旧值>,如步骤 C3 中所示。你总会有 a >; b,因此在步骤 C3 中将 r 增加 a 会自动使 r 再次为正值,因此您只需直接进入步骤 C4 。

证明 a > 也很容易。 b。我们从明显大于 ba 开始,如果我们将 b 增加到 b = a - 2 code>,我们有

N = (a - (a - 2))/2 * ((a + (a - 2) - 2)/2 = 1 * (a - 2)

这意味着 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, because x is not incremented and r is only decremented by y.

Using the notation of a, b and r from the 1998 edition of Vol. 2 (ISBN 0-201-89684-2), a Scheme version would be as follows:

(define (factor n) 
  (let ((x (inexact->exact (floor (sqrt n)))))
    (factor-inner (+ (* x 2) 1)
                  1
                  (- (* x x) n))))

(define (factor-inner a b r)
  (cond ((= r 0) (/ (- a b) 2))
        ((< 0 r) (factor-inner a       (+ b 2) (- r b)))
        (else    (factor-inner (+ a 2) (+ b 2) (- r (- a b))))))

EDIT to add: Basically, we are doing a trick that repeatedly checks whether

r <- ((a - b) / 2)*((a + b - 2)/2) - N

is 0, and we're doing it by simply tracking how r changes when we increment a or b. If we were to set b to b+2 in the expression for r above, it's equivalent to reducing r by the old value of b, 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 of b, so you keep repeating step C4. However, if you overshoot, and r < 0, you need to increase it. You do this by increasing a, because increasing a by 2 is equivalent to decreasing r by the old value of a, as in step C3. You will always have a > b, so increasing r by a in step C3 automatically makes r positive again, so you just proceed directly on to step C4.

It's also easy to prove that a > b. We start with a manifestly greater than b, and if we ever increase b to the point where b = a - 2, we have

N = (a - (a - 2))/2 * ((a + (a - 2) - 2)/2 = 1 * (a - 2)

This means that N is prime, as the largest factor it has that is less than sqrt(N) is 1, and the algorithm has terminated.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文