Scheme N次方根计算在球拍中非常慢

Scheme N次方根计算在球拍中非常慢,scheme,racket,Scheme,Racket,我正在用DrRacket上编程课。我想用简化的语法。 练习是以给定的精度计算给定数字的第n个根。 这个程序运行得很好,但是如果它尝试使用243的第五个根(即3),那么程序的计算速度太慢。但是,如果堆叠(改进1 5 243)功能,它会工作。但是,如果我将其堆叠超过7次,则程序执行时间太长 有什么问题 这是程序:(它使用牛顿算法) (在(n根3 125 0.001)5 0.001内检查) (检查范围为(N根2 625 0.01)25 0.01) (在(第n根3 64 0.001)4 0.001内检查

我正在用DrRacket上编程课。我想用简化的语法。 练习是以给定的精度计算给定数字的第n个根。 这个程序运行得很好,但是如果它尝试使用243的第五个根(即3),那么程序的计算速度太慢。但是,如果堆叠
(改进1 5 243)
功能,它会工作。但是,如果我将其堆叠超过7次,则程序执行时间太长

有什么问题

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

(在(n根3 125 0.001)5 0.001内检查)
(检查范围为(N根2 625 0.01)25 0.01)
(在(第n根3 64 0.001)4 0.001内检查)
(:n根(自然实数->实数))
(定义第n个根)
(lambda(nx eps)(根iter 1 nx eps)))
(:根iter(real-natural-real->real))
(定义根iter)
(λ(当前最后n x每股收益)
(如果(足够好?当前n x eps)
现在的
(根iter(改进最后一个n x)电流n x eps)
(:改善(真实自然->真实)
(定义和改进
(lambda(最后n x)
(*(/1 n)
(+/x
(上次导出(-n 1)))
(*(-n1)
最后(()))
(:足够好吗?(真实->布尔)
(足够好吗?
(λ(当前n x每股收益)
(<(abs(-(输出电流n)x))eps)

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

如果你处理的是精确的数字,Racket(和Scheme)会给你精确的算术。事实证明,在一次又一次的迭代中改进猜测的方法都使用精确的数字P

要确认此操作的效果,请尝试:
(n根目录5243.0 0.001)
。比较vs
(n根5 243 0.001)
,您应该会发现计算答案所需的时间有很大差异

这就是为什么您会在Scheme中看到像
exact->incexact
这样的函数。以及为什么你会在你的计算机上看到浮点(不精确)算法:你会遇到这样的情况:获得柏拉图式的答案是非常昂贵的,对于许多应用来说,你可以容忍这种不精确性

(虽然不是在金融业。在处理钱的问题时不要使用不精确的数字,否则你会让人非常非常不高兴。)

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