线性搜索基本迭代格式为,其中
为迭代方向,
为迭代步长,在确定迭代方向后怎样寻找最佳迭代步长是本章的主要内容(本章不重点涉及迭代方向问题,因为算法比较基础,都是建立在一元函数下,所以只有前和后,故本章不介绍复杂的迭代方向问题)
原理
所谓最佳迭代步长就是在此步长下函数值最小,,也可表述为
,其中
是求导符号。
0.618法,Fibonacci法
这是两个很早的线性搜索方法,(作为早期的迭代方法,并不实用,铸瓷差值逼近法为重点)共同前提为为在我们所划定的搜索区间
为凸函数,原理为
,取
中最小的三个,取最小的这三个的横坐标中最大的为
,最小的为
。重复上述过程,Fibonacci法类似。
代码部分
p=0.382;a=0;b=1;% 0.618
t2=a+p(b-a);
x1=f(t2);% 函数需要你们自己给出
t1=a+b-t2;
x2=f(t1);% 函数需要你们自己给出
x=b-a
while x<=o
if x1<=x2
a=t2;
t2=t1;
x2=x1;
t1=a+b-t2;
x1=f(t1);
else
b=t1;
t1=t2;
x1=x2;
t2=a+p(b-a);
x2=f(t2);
end
x=b-a;
end
xo=(a+b)/2;
n=100; % Fibonacci
a=zeros(1,102);
a(1)=1;
a(2)=1;
a=0;
b=1;
q=0.05;
for i=1:n
a(i+2)=a(i+1)+a(i);
end
l=1;
while (b-a)>=q
k=a+(1-a(l)/a(l+1))*(b-a);
j=a+(a(l)/a(l+1))*(b-a);
if f(j)<f(k) % 函数需要你们自己给出
b=k;
else
a=j;
end
l=l+1;
end
t=(a+b)/2;
逐次插值逼近法
逐次插值逼近法是用插值多项式的极小点来逼近或者说收敛于原函数的极小点,在搜索区间内找到三点满足,通过Language插值法来构造二次函数,然后找到二次函数的极小点
,然后比较
的大小,找到函数值最小的点x和左右两边跟x相距最近的两个点作为新的
,显然满足
,按此规律不断迭代,直到
,
为极小值点的精度。
基本逻辑已经很清楚了,具体迭代公式不再做一一推导,迭代公式结论在代码中,关于其收敛性问题,这里不作为重点,有趣性的读者可以去阅读《最优化方法》。
代码部分
a1=0;a2=2;a3=3;
while abs(a-a2)>=0.05
a=0.5*((a2^2-a3^2)*f(a1)+(a3^2-a1^1)*f(a2)
+(a1^2-a2^2)*f(a3))/((a2-a3)*f(a1)+(a3-a1)*f(a2)+(a1-a2)*f(a3));
% a点的迭代公式,按照基本逻辑很容易推导
if a>a2
if f(a)<=f(a2)
a1=a2;
a2=a;
else
a3=a;
end
else
if f(a)<=f(a2)
a3=a2;
a2=a;
else
a1=a;
end
end
end
t=(a+a2)/2;
(代码如有问题,欢迎指正交流)