精确线搜索-黄金分割法

黄金分割法[1]

黄金分割法

黄金分割法也称为0.618 法, 其基本思想是通过试探点函数值得比较,是包含极小点的搜索区间不断缩小. 该方法仅需要计算函数值, 适用范围广, 使用方便. 下面我们来推导0.618 法的计算公式.
设$$\phi(s)=f(x_k+sd_k)$$

其中\(\phi(s)\)是搜索区间\([a_0,b_0]\)上的单峰函数. 在第\(i\) 次迭代时搜索区间为\([a_i,b_i]\). 取两个试探点为\(p_i,q_i \in [a_i,b_i]\)\(p_i <q_i\). 计算\(\phi(p_i)\)\(\phi(q_i)\). 根据单峰函数的性质, 可能会出现如下两种情形之一:

(1) 若\(\phi(p_i) \leq \phi(q_i)\),则令\(a_{i+1}=a_i,b_{i+1}=q_i\)
(2) 若\(\phi(p_i) > \phi(q_i)\),则令\(a_{i+1}=p_i,b_{i+1}=b_i\)
我们要求两个试探点\(p_i\)\(q_i\)满足下述两个条件:
(1)\([a_i,q_i]\)\(p_i,b_i]\)的长度相同, 即\(b_i-p_i=q_i-a_i\)
(2)区间长度的缩短率相同, 即\(b_{i+1}-a_{i+1}=t(b_i-a_i)\)
从而可得

\[p_i=a_i+(1-t)(b_i-a_i),\ q_i=a_i+t(b_i-a_i) \]

现在考虑情形(1). 此时, 新的搜索区间为

\[[a_{i+1}=b_{i+1}]=[a_i,q_i] \]

为了进一步缩短搜索区间, 需取新的试探点\(p_{i+1},q_{i+1}\).由以上推导 得
\begin{align}
q_{i+1} &=a_{i+1}+t(b_{i+1}-a_{i+1})\
& = a_i+t(q_i-a_i) \
& = a_i+t^2(b_i-a_i)
\end{align
}
若令$$t^2=1-t,\ t>0$$
则$$q_{i+1}=a_i+(1-t)(b_i-a_i)=p_i$$
这样, 新的试探点\(q_{i+1}\)就不需要重新计算. 类似地, 对于情形(2), 也有相同的结论.
解方程\(t^2=1-t,\ t>0\) 得区间长度缩短率为$$t=\frac{\sqrt(5)-1}{2}\approx 0.618$$
因此, 我们可以写出0.618 法的计算步骤如下.

算法2 (0.618 法)

步0 确定初始搜索区间\([a_0,b_0]\)和容许误差\(0\leq \epsilon \leq1\). 令\(t=\frac{\sqrt(5)-1}{2}\)计算初始试探点$$p_0=a_0+(1-t)(b_0-a_0), \ q_0=a_0+t(b_0-a_0)$$
及相应的函数值\(\phi(p_0),\phi(q_0)\)。令\(i=0\)
步1\(\phi(p_i)\leq\phi(q_i)\),转步骤2;否则,转步骤3
步2计算左试探点. 若\(\left | q_i-a_i \right |\leq \epsilon\),停算,输出\(p_i\);否则,令

\[a_{i+1}=a_i,\ b_{i+1}=q_i,\ \phi(q_{i+1})=\phi(p_i),\\ q_{i+1}=p_i,\ p_{i+1}=a_{i+1}+(1-t)(b_{i+1}-a_{i+1}).\]

计算\(\phi(p_{i+1}), i=i+1,\)转步骤1
步3计算右试探点.若\(\left | b_i-p_i \right |\leq \epsilon\),停算,输出\(q_i\);否则,令

\[a_{i+1}=p_i,\ b_{i+1}=b_i,\ \phi(p_{i+1})=\phi(q_i),\\ p_{i+1}=q_i,\ q_{i+1}=a_{i+1}+t(b_{i+1}-a_{i+1}).\]

计算\(\phi(q_{i+1}), i=i+1,\)转步骤1
值得说明的是, 由于每次迭代搜索区间的收缩率是\(t=0.618\), 故0.618法只是线性收敛的, 即这一方法的计算效率并不高. 但该方法每次迭代只需计算一次函数值的优点足以弥补这一缺憾.

MATLAB实现

function [s,phis,i,G,E]=huanjfg(phi,a,b,delta,epsilon)
%功能: 0.618法精确线搜索
%输入: phi是目标函数, a, b 是搜索区间的两个端点
%         epsilon delta分别是自变量和函数值的容许误差
%输出:  s, phis分别是近似极小点和极小值,  G是nx4矩阵,
%         其第i行分别是a,p,q,b的第i次迭代值[ak,pk,qk,bk],
%          E=[ds,dphi], 分别是s和phis的误差限.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 步0    确定初始搜索区间$[a_0,b_0]$和容许误差$0\leq \epsilon \leq1$. 
%       令$t=\frac{\sqrt(5)-1}{2}$计算初始试探点$$p_0=a_0+(1-t)(b_0-a_0), \  q_0=a_0+t(b_0-a_0)$$
%       及相应的函数值$\phi(p_0),\phi(q_0)$。令$i=0$
% 步1    若$\phi(p_i)\leq\phi(q_i)$,转步骤2;否则,转步骤3
% 步2    计算左试探点. 若$\left | q_i-a_i \right |\leq \epsilon$,停算,输出$p_i$;否则,令
%           $$a_{i+1}=a_i,\  b_{i+1}=q_i,\  \phi(q_{i+1})=\phi(p_i),\\
%           q_{i+1}=p_i,\ p_{i+1}=a_{i+1}+(1-t)(b_{i+1}-a_{i+1}).$$
%       计算$\phi(p_{i+1}), i=i+1,$转步骤1
% 步3    计算右试探点.若$\left | b_i-p_i \right |\leq \epsilon$,停算,输出$q_i$;否则,令
%           $$a_{i+1}=p_i,\  b_{i+1}=b_i,\  \phi(p_{i+1})=\phi(q_i),\\
%           p_{i+1}=q_i,\ q_{i+1}=a_{i+1}+t(b_{i+1}-a_{i+1}).$$
%       计算$\phi(q_{i+1}), i=i+1,$转步骤1

t=(sqrt(5)-1)/2;
p=a+(1-t)*(b-a);q=a+t*(b-a);
phip=feval(phi,p);phiq=feval(phi,q);
i=0;
G(i+1,:)=[a p q b];
while(1)
    %step 1
    if phip<=phiq
        %step 2
        if (abs(b-a)>epsilon)||(abs(phib-phia)>delta)
%             a=a;
            b=q;phib=phiq;
            phiq=phip;
            q=p;
            p=a+(1-t)*(b-a);
            phip=feval(phi,p);
        else
            break;
        end
    else
        %step 3
        if (abs(b-a)>epsilon)||(abs(phib-phia)>delta)
            a=p;phia=phip;
%             b=b;
            phip=phiq;
            p=q;
            q=a+t*(b-a);
            phiq=feval(phi,q);
        else
            break;
        end
    end
    i=i+1;
    G(i+1,:)=[a p q b];
end
if phip<=phiq
    s=p;
    phis=phip;
else
    s=q;
    phis=phiq;
end
% E=[ds,dphi]
ds=abs(b-a);dphi=abs(phib-phia);
E=[ds,dphi];

MATLAB实验结果

>> phi=@(x)((x-1)^2);
>> [a,b,k]=bfm(phi,0,0.1)
a =
                       0.3
b =
                       1.5
k =
     3
>> delta=0.001;epsilon=0.001;
>> [s,phis,i,G,E]=huanjfg(phi,a,b,delta,epsilon);
>> [s,phis,i]
ans =
         0.999974521703027      6.49143616637166e-10                        15
       

取函数\(\phi(x)=(x-1)^2\),初始区间为\([0.3,1.5]\),容许误差\(\epsilon\)为0.001,
大概迭代16次可得极小点\((0.999974521703027,\ 6.49143616637166e-10)\)


  1. 马昌凤. 最优化方法及其Matlab程序设计[M]. 科学出版社, 2010. ↩︎

posted @ 2017-08-28 17:20  main_c  阅读(2907)  评论(0)    收藏  举报