2011-02-23 52 views
2

考慮以下兩個略有不同的方法用於計算第五根:爲什麼這些略有不同的尋根方法會產生不同的結果?

(define (fifth-root-right x) 
    (fixed-point-of-transform (lambda (y) (/ x (expt y 4))) 
          (repeated average-damp 2) 
          1.0)) 

(define (fifth-root-wrong x) 
    (fixed-point (repeated 
       (average-damp (lambda (y) (/ x (expt y 4)))) 
       2) 
       1.0)) 

都試圖計算第五根平均衰減搜索一個固定點,因爲x的第五根是地圖y的固定點 - > x /(y^4)。我定義

(define (average-damp f) 
    (lambda (x) (average x (f x)))) 
(define tolerance 0.00001) 
(define (fixed-point f first-guess) 
    (define (close-enough? v1 v2) 
    (< (abs (- v1 v2)) tolerance)) 
    (define (try guess) 
    (let ((next (f guess))) 
     (if (close-enough? guess next) 
      next 
      (try next)))) 
    (try first-guess)) 
(define (fixed-point-of-transform g transform guess) 
    (fixed-point (transform g) guess)) 
(define (repeated f n) 
    (if (= n 1) 
     f 
     (compose f (repeated f (- n 1))))) 
(define (compose f g) (lambda (x) (f (g x)))) 

嘗試這兩種方法,我們得到

> (fifth-root-right 32) 
2.000001512995761 
> (fifth-root-wrong 32) 
2.8804315666156364 

爲什麼第二種方法給不能正確計算第五根源是什麼?更奇怪的是,如果我們試圖在第四或第三根這種錯誤的方法,它工作正常:

(define (fourth-root x) 
    (fixed-point (repeated 
       (average-damp (lambda (y) (/ x (expt y 3)))) 
       2) 
       1.0)) 

(define (cube-root x) 
    (fixed-point (repeated 
       (average-damp (lambda (y) (/ x (expt y 2)))) 
       2) 
       1.0)) 


> (fourth-root 16) 
1.982985155172348 
> (cube-root 8) 
2.0000009087630515 

以供參考,該代碼試圖解決計算機程序的Exercise 1.45結構和解釋。現在我有正確的方法,我的代碼有效,但我不明白爲什麼我的錯誤方法是錯誤的。

+0

你的第三和第四度例子似乎是正確方式的副本,而不是錯誤的方式。 – btilly 2011-02-23 02:26:37

+0

謝謝,現在固定正確和錯誤的標籤。 – petehern 2011-02-23 15:25:14

回答

3

本質區別在於什麼功能重複兩次。在正確的一個,average-damp正在申請兩次,淨效應更多的阻尼; ((repeated average-damp 2) f)在數學上減少爲(lambda (x) (+ (* 0.75 x) (* 0.25 (f x))))(道歉,如果我的語法關閉,我的lisp非常非常生鏽)。這使得該算法不易受到變換的瘋狂波動的影響。

第二個,不過,適用(average-damp (lambda (y) (/ x (expt y 2))))兩次 - 即,它衰減所述變換一次,然後重複所得到的函數。 average-damp的一個應用程序恰好足以使序列不發散,但不足以實際上使其趨於一致。它實際上收斂到振盪狀態,在1.6726450849432732.8804350135298153之間來回跳動。然而,阻尼變換在每一步都應用了兩次,所以fixed-point只能看到序列中的每個其他元素 - 該子序列收斂於後者,即使序列整體無法收斂。

+1

另外,我懷疑它對低階命令起作用的原因簡直歸結爲低階減震需要較少的事實,因此應用較少衰減的其他版本仍然能夠通過。如果您進一步增加訂單,您可能會發現需要更多的阻尼來抵消增加的無限衝擊傾向。 – mokus 2011-02-23 03:07:53

+0

這是正確的。當我做同樣的問題時,我發現當n增加一倍時,你需要增加1的平均衰減數。http://www.billthelizard.com/2010/08/sicp-145-computing-nth-roots.html – 2011-02-23 04:44:02

+0

@蜥蜴♦♦:不錯的貼子。我很確定這樣做的原因是因爲這種方法的步驟是一種逼近牛頓 - 拉夫森步驟的非常迂迴的方式。重複平均衰減m次與計算f(y)=(1 - 1/2^m)y + x /(2^m y ^(n-1))相同。令m爲log2(n)使得階躍函數f(y)=(1 - 1/n)y + x /(ny ^(n-1)),這正是Newton-Raphson所使用的。使用它的地板使它成爲一個(足夠好的)近似值,所以我會說你在帖子中的直覺是正確的。 – mokus 2011-02-23 13:51:39

相關問題