费马分解方法限制

时间:2010-03-15 07:43:46

标签: algorithm scheme

我正在尝试实现费马的分解(算法C 计算机编程艺术,第2卷)。不幸的是,在我的版本(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))))))

2 个答案:

答案 0 :(得分:1)

通过算法C 查看,看起来问题在于递归步骤,它会在r < 0时有效地跳过步骤C4,因为x没有递增而r 1}}仅递减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,我们只是通过跟踪ra增加时b的变化情况来实现。如果我们要在上面b的表达式中将b+2设置为r,则相当于将r的旧值减少b,这就是为什么两者都在算法的步骤C4中并行完成。我鼓励你扩展上面的代数表达式并说服自己这是真的。

只要r > 0,您希望继续减少它以找到b的正确值,因此您不断重复步骤C4。但是,如果您超调,r < 0,则需要增加它。您可以通过增加a来实现此目的,因为将a增加2相当于将r的旧值减少a,如步骤C3所示。您将始终拥有a > b,因此在步骤C3中r增加a会自动使r再次为正,因此您只需直接进入步骤C4。

证明a > b也很容易。我们从明显大于a的{​​{1}}开始,如果我们将b增加到b,我们就会

b = a - 2

这意味着N = (a - (a - 2))/2 * ((a + (a - 2) - 2)/2 = 1 * (a - 2) 是素数,因为它具有的最小因子小于N是1,并且算法已经终止。

答案 1 :(得分:1)

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

  

x = N + 2

     

y = N

然后返回1.

相关问题