优选法和newton法在实践中的比较
对于函数f(x)=2*x^2-4*x-6 ,求在(-1,2)范围内的极值,分别用优选法和newton法实践,看比较的次数。
(setq count 0)
(defun calc (x)
(progn
(incf count )
(+ (* 2
(* x
x))
(- 0
(* 4
x))
(- 0
6))))
newton
(defun look ( mid left right fun)
(if (< (abs (- (funcall fun mid )
(funcall fun left ) ))
(/ 1.0 10000000))
mid
(if (> (funcall fun left )
(funcall fun right ))
(look (/ (+ mid right ) 2.0) mid right fun)
(look (/ (+ left mid ) 2.0) left mid fun ))))
//节省计算次数 ,保存局部变量
(defun look ( mid left right leftvalue rightvalue fun)
(let ( (midvalue (funcall fun mid) ))
(if (< (abs (- midvalue
leftvalue ))
(/ 1.0 10000000))
mid
(if (> leftvalue
rightvalue)
(look (/ (+ mid right ) 2.0) mid right midvalue rightvalue fun)
(look (/ (+ left mid ) 2.0) left mid leftvalue midvalue fun )))))
(setq count 0)
(print (look (/ (+ -1.0 2.0) 2) -1.0 2.0 (calc -1.0) (calc 2.0) 'calc ))
(print 'compare)
(setq count 0)
(print (lookex 0.8 0 (/ pi 2) 0.5 'calc ))
没保存局部变量前为54,保存之后下降为16。
下面看下优选法:
(setq golden (/ (- (sqrt 5)
1)
2.0))
(defun getright (left right)
(+ left
(* golden
(- right
left))))
(defun getleft (left right)
(+ left
(* (- 1 golden)
(- right
left))))
(defun look (goldenleft goldenright leftvalue rightvalue left right fun)
(if (< (abs (- leftvalue
rightvalue ))
(/ 1.0 10000000))
goldenleft
(if (> leftvalue
rightvalue)
(look goldenright (getright goldenleft right) rightvalue (calc (getright goldenleft right)) goldenleft right fun)
(look (getleft left goldenright) goldenleft (calc (getleft left goldenright)) leftvalue left goldenright fun ))))
(setq count 0)
(print (look (getleft -1.0 2.0 )
(getright -1.0 2.0 )
(calc (getleft -1.0 2.0 ) )
(calc (getright -1.0 2.0 ) )
-1.0
2.0
'calc ))
[9]> count
19
从结果可以发现比较了19次才得出结果;
另外要注意,在判断终止条件的时候,两者选择的标准是不一样的,一个是以值,一个以坐标。
不过在目前的情况中是一样的,这样是为了便于与newton法比较;但在这种情况下有可能出现两者相等,但离所求的点很远的情况,(关于轴对称的情况).