第N个根计算在Racket中非常慢

时间:2013-11-13 22:12:12

标签: scheme racket

我正在使用DrRacket编写我的编程类。我认为使用简化的语法。 练习是以给定的精度计算给定数字的第n个根。 这个程序工作正常,但如果它尝试使用它与243的第5个根(即3),程序太慢,无法计算它。但是,如果叠加(improve 1 5 243)函数,它就可以工作。但如果我将它堆叠的频率超过7次,那么程序执行时间会太长。

有什么问题?

这是程序:(它使用牛顿算法)

(check-within (nth-root 3 125 0.001) 5 0.001)
(check-within (nth-root 2 625 0.01) 25 0.01)
(check-within (nth-root 3 64 0.001) 4 0.001)
(: nth-root (natural natural real -> real))
(define nth-root
  (lambda (n x eps) (root-iter 1 1 n x eps)))

(: root-iter (real real natural natural real -> real))
(define root-iter
  (lambda (current last n x eps)
    (if (good-enough? current n x eps)
        current
        (root-iter (improve last n x) current n x eps))))

(: improve (real natural natural -> real))
(define improve
   (lambda (last n x)
    (* (/ 1 n)
       (+ (/ x
              (expt last (- n 1)))
          (* (- n 1)
              last)))))

(: good-enough? (real natural natural real -> boolean))
(define good-enough?
   (lambda (current n x eps)
    (< (abs (- (expt current n) x)) eps)))

1 个答案:

答案 0 :(得分:0)

几乎可以肯定你在这里使用精确算术。在这种特殊情况下,这将是昂贵的,因为你的数学将是有理数的;你的分子和分母将会变得巨大。进入不精确的算术,你应该看到一个重大的性能改进(以精度为代价,请注意)。

如果你正在处理确切的数字,那么球拍(和一般的方案)会给你精确的算术。事实证明,你从迭代到迭代改进猜测的方式都使用了确切的数字! :P

要确认此效果,请尝试:(nth-root 5 243.0 0.001)。比较vs (nth-root 5 243 0.001),您应该看到计算答案所需的时间差异很大。

这就是为什么你会在Scheme中看到像exact->inexact这样的函数。为什么你会在你的计算机中看到浮点(不精确)算术:你会遇到让柏拉图式答案非常昂贵的情况,对于许多应用程序,你可以容忍不精确的行为。

(虽然没有融资。当你处理钱财时,不要使用不准确的数字,否则你会让某人非常非常不开心。)