SICP 習題 (2.11)解題總結:區間乘法的優化

SICP 習題 2.11又出現Ben這個人了,如以前說到的,只要是Ben說的一般都是對的。


來看看Ben說什麼,他說:“通過監測區間的端點,有可能將mul-interval分解爲9中情況,每種情況中所需要的乘法都不超過兩次”。

所以這個叫Ben的人建議Allysa重寫mul-interval過程。


到底是啥意思呢,我們先來看看以前的mul-interval過程:

(define (mul-interval x y)
  (let (( p1 (* (lower-bound x) (lower-bound y)))
	( p2 (* (lower-bound x) (upper-bound y)))
	( p3 (* (upper-bound x) (lower-bound y)))
	( p4 (* (upper-bound x) (upper-bound y))))
    (make-interval (min p1 p2 p3 p4)
		   (max p1 p2 p3 p4))))


可以發現,這裏使用了4次乘法,然後取4此乘法的最小值爲起點,最大值爲終點。

按Ben的意思,我們可以將這4次乘法減少爲兩次,前提是對區間的端點進行判斷。


其實我們自己想一想大概能夠明白Ben這段神祕的話。 比如,如果相乘的兩個區間都是完全大於零的區間,兩個區間的起點相乘肯定是4次乘法中最小的值,而兩個終點相乘肯定是4次乘法中的最大的,這樣我們只需要計算兩個起點相乘,還有就是兩個終點相乘就可以了。這樣我們就可以使用2次乘法完成工作,而不用4次。


不過,對我們程序員來講工作就複雜很多了,我們需要取判斷這9中情況,分別想好9種情況種選用什麼作爲結構的起點和終點,最後寫出來的代碼如下,巨煩瑣:

(define (mul-interval x y)
  (if (> (lower-bound x) 0)
      (if (> (lower-bound y) 0)
	  (make-interval (* (lower-bound x) (lower-bound y)) (* (upper-bound x) (upper-bound y)))
	  (if (> (upper-bound y) 0)
	      (make-interval (* (upper-bound x) (lower-bound y)) (* (upper-bound x) (upper-bound y)))
	      (make-interval (* (lower-bound x) (upper-bound y)) (* (lower-bound x) (upper-bound y)))))
      (if (> (upper-bound x) 0)
	  (if (> (lower-bound y) 0)
	      (make-interval (* (lower-bound x) (upper-bound y)) (* (upper-bound x) (upper-bound y)))
	      (if (> (upper-bound y) 0)
		  (make-interval (* (lower-bound x) (lower-bound y)) 
				 (* (upper-bound x) (upper-bound y)))
		  (make-interval (* (lower-bound x) (lower-bound y))
				 (* (upper-bound x) (upper-bound y)))))
	  (if (> (lower-bound y) 0)
	      (make-interval (* (lower-bound x) (lower-bound y)) (* (upper-bound x) (upper-bound y)))
	      (if (> (upper-bound y) 0)
		  (make-interval (* (lower-bound x) (lower-bound y)) 
				 (* (upper-bound x) (upper-bound y)))
		  (make-interval (* (lower-bound x) (lower-bound y)) 
				 (* (upper-bound x) (upper-bound y))))) )))



有人可能會問,把原來那個如此優雅的過程寫成現在這樣有意思嗎?一堆醜陋的判斷!

這裏需要理解的就是,如果系統中乘法是一個消耗很大的操作,比如每個乘法消耗2秒,這樣我們做這個優化就有意義的,雖然我們寫的代碼醜很多,麻煩很多,不過代碼運行效率就比較高了。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章