【问题标题】:Fermat factorization method limit费马分解方法限制
【发布时间】:2010-03-15 07:43:45
【问题描述】:

我正在尝试实现 Fermat 的因式分解(计算机编程艺术第 2 卷中的算法 C)。不幸的是,在我的版本(ISBN 81-7758-335-2)中,这个算法打印不正确。下面的因子内循环的条件应该是什么?我正在运行循环,直到 y

(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))))))

【问题讨论】:

  • 为什么你认为书中提出的算法是错误的?
  • 如果您认为错误,请从 Knuth 下载勘误表并检查该页码。如果你在那里找不到,请告诉他。
  • @user49117:因为它是错误的。这是算法。如该版本的书所述。它甚至不会以给出的方式终止。 C1: set x = 2sqrt(N)+1, y=1, r= (sqrt(N))^2-N // sqrt(N) 舍入到下限 C2: 如果 r=0,完成。 C3:设置 r=r+x,x+=2 C4:设置 r=r-y,y+=2 C5:如果 r > 0,则返回 c3,否则转到 c2。 @伊恩:谢谢!会这样做。
  • 在第三版中,C5 表示如果 r > 0 则返回 C4,而不是 C3。
  • @Jason:我的版本中没有[这是第三版,而是印度版]!

标签: algorithm scheme


【解决方案1】:

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

x = N + 2

y = N

然后它会返回 1。

【讨论】:

  • 是的 - 这避免了检查的需要。不过,对于大质数来说,这将需要很长时间!
【解决方案2】:

查看算法C,问题似乎出在递归步骤上,只要r &lt; 0 有效地跳过步骤C4,因为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))))))

EDIT 补充:基本上,我们正在做一个反复检查是否

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

是 0,我们通过简单地跟踪 r 在增加 ab 时的变化来做到这一点。如果我们在上面r 的表达式中将b 设置为b+2,则相当于将r 减去b 的旧值,这就是为什么两者在步骤C4 中并行完成的原因算法。我鼓励你扩展上面的代数表达式并说服自己这是真的。

只要r &gt; 0,你要不断地递减它来找到b的正确值,所以你不断重复步骤C4。但是,如果您超调,并且r &lt; 0,您需要增加它。您可以通过增加a 来做到这一点,因为将a 增加2 相当于将r 减少a 的旧值,如步骤C3 中所示。您将始终拥有a &gt; b,因此在步骤 C3 中将 r 增加 a 会自动使 r 再次为正,因此您只需直接继续执行步骤 C4。

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

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

这意味着N 是素数,因为它小于sqrt(N) 的最大因子是1​​,并且算法已经终止。

【讨论】:

  • 您在 (
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-16
  • 1970-01-01
相关资源
最近更新 更多