精确线搜索-黄金分割法

来源:互联网 发布:个人域名备案企业网站 编辑:程序博客网 时间:2024/06/02 10:41

黄金分割法1

黄金分割法

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

ϕ(s)=f(xk+sdk)

其中ϕ(s)是搜索区间[a0,b0]上的单峰函数. 在第i 次迭代时搜索区间为[ai,bi]. 取两个试探点为pi,qi[ai,bi]pi<qi. 计算ϕ(pi)ϕ(qi). 根据单峰函数的性质, 可能会出现如下两种情形之一:

(1) 若ϕ(pi)ϕ(qi),则令ai+1=ai,bi+1=qi
(2) 若ϕ(pi)>ϕ(qi),则令ai+1=pi,bi+1=bi
我们要求两个试探点piqi满足下述两个条件:
(1)[ai,qi]pi,bi]的长度相同, 即bipi=qiai
(2)区间长度的缩短率相同, 即bi+1ai+1=t(biai)
从而可得

pi=ai+(1t)(biai), qi=ai+t(biai)

现在考虑情形(1). 此时, 新的搜索区间为
[ai+1=bi+1]=[ai,qi]

为了进一步缩短搜索区间, 需取新的试探点pi+1,qi+1.由以上推导 得
qi+1=ai+1+t(bi+1ai+1)=ai+t(qiai)=ai+t2(biai)

若令
t2=1t, t>0

qi+1=ai+(1t)(biai)=pi

这样, 新的试探点qi+1就不需要重新计算. 类似地, 对于情形(2), 也有相同的结论.
解方程t2=1t, t>0 得区间长度缩短率为
t=(5)120.618

因此, 我们可以写出0.618 法的计算步骤如下.

算法2 (0.618 法)

步0 确定初始搜索区间[a0,b0]和容许误差0ϵ1. 令t=(5)12计算初始试探点

p0=a0+(1t)(b0a0), q0=a0+t(b0a0)

及相应的函数值ϕ(p0),ϕ(q0)。令i=0
步1ϕ(pi)ϕ(qi),转步骤2;否则,转步骤3
步2计算左试探点. 若|qiai|ϵ,停算,输出pi;否则,令
ai+1=ai, bi+1=qi, ϕ(qi+1)=ϕ(pi),qi+1=pi, pi+1=ai+1+(1t)(bi+1ai+1).

计算ϕ(pi+1),i=i+1,转步骤1
步3计算右试探点.若|bipi|ϵ,停算,输出qi;否则,令
ai+1=pi, bi+1=bi, ϕ(pi+1)=ϕ(qi),pi+1=qi, qi+1=ai+1+t(bi+1ai+1).

计算ϕ(qi+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,$转步骤1t=(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];endif 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.3b =                       1.5k =     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

取函数ϕ(x)=(x1)2,初始区间为[0.3,1.5],容许误差ϵ为0.001,
大概迭代16次可得极小点(0.999974521703027, 6.49143616637166e10)


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