【最优化】精确一维线搜索—黄金分割法在Matlab上的实现

1 前言

  在线搜索迭代算法中,当迭代方向 d k d^k dk确定后,需要看沿 d k d^k dk 走多远对算法有利,即需要寻找迭代步长。迭代步长通常由精确一维线搜索、非精确一维线搜索、非单调一维线搜索等方式获得。实现精确一维线搜索的方法有很多,其中包括 Fibonacci \text{Fibonacci} Fibonacci 法、黄金分割法、进退法、平分法、抛物线法等。下面只介绍黄金分割法。黄金分割法又称为 0.618 0.618 0.618法。

2 算法内容

  算法(黄金分割法) 给定目标函数 f ( x ) ,    f(x),\; f(x),初始搜索区间 [ a 0 , b 0 ] ⊆ [ 0 , + ∞ ) [a_0,b_0]\subseteq [0,+\infty) [a0,b0][0,+)和精度要求 ε > 0.    \varepsilon>0.\; ε>0. b 0 − a 0 < ε ,    b_0-a_0<\varepsilon,\; b0a0<ε,那么算法终止 ,    ,\; ,输出 λ ∗ : = a 0 + b 0 2 . \lambda_*:=\frac{a_0+b_0}{2}. λ:=2a0+b0.

  步1 t 0 = a 0 + 0.382 ( b 0 − a 0 ) ,    s 0 = a 0 + 0.618 ( b 0 − a 0 ) ,    t_0=a_0+0.382(b_0-a_0),\;s_0=a_0+0.618(b_0-a_0),\; t0=a0+0.382(b0a0),s0=a0+0.618(b0a0),计算 f ( t 0 ) , f ( s 0 ) .    f(t_0),f(s_0).\; f(t0),f(s0). k : = 0 k:=0 k:=0.

  步2 f ( t k ) > f ( s k ) ,    f(t_k)>f(s_k),\; f(tk)>f(sk),则转步3 ;    ;\; ;否则转步4.

  步3 b k − t k < ε ,    b_k-t_k<\varepsilon,\; bktk<ε,则算法终止 ,    ,\; ,输出 λ ∗ : = s k ;    \lambda_*:=s_k;\; λ:=sk;否则置 a k + 1 : = t k ,    b k + 1 : = b k ,    t k + 1 a_{k+1}:=t_k,\;b_{k+1}:=b_k,\;t_{k+1} ak+1:=tk,bk+1:=bk,tk+1 : = s k ,    f ( t k + 1 ) : = f ( s k ) ,    :=s_k,\;f(t_{k+1}):=f(s_k),\; :=sk,f(tk+1):=f(sk),计算 s k + 1 : = a k + 1 + 0.618 ( b k + 1 − a k + 1 ) s_{k+1}:=a_{k+1}+0.618(b_{k+1}-a_{k+1}) sk+1:=ak+1+0.618(bk+1ak+1) f ( s k + 1 ) ,    f(s_{k+1}),\; f(sk+1),转步5.

  步4 s k − a k < ε ,    s_k-a_k<\varepsilon,\; skak<ε,则算法终止 ,    ,\; ,输出 λ ∗ : = t k ;    \lambda_*:=t_k;\; λ:=tk;否则置 a k + 1 : = a k ,    b k + 1 : = s k ,    s k + 1 a_{k+1}:=a_k,\;b_{k+1}:=s_k,\;s_{k+1} ak+1:=ak,bk+1:=sk,sk+1 : = t k ,    f ( s k + 1 ) : = f ( t k ) ,    :=t_k,\;f(s_{k+1}):=f(t_k),\; :=tk,f(sk+1):=f(tk),计算 t k + 1 : = a k + 1 + 0.382 ( b k + 1 − a k + 1 ) t_{k+1}:=a_{k+1}+0.382(b_{k+1}-a_{k+1}) tk+1:=ak+1+0.382(bk+1ak+1) f ( t k + 1 ) ,    f(t_{k+1}),\; f(tk+1),转步5.

  步5 k : = k + 1 ,    k:=k+1,\; k:=k+1,转步2.

3 在Matlab上的实现

3.1 代码

3.1.1 Goldsection.m(函数.m文件)

function [target_value,target_x,k,lambda] = Goldsection(f,epsilon,x,d,upper,lower)
% 黄金分割法
k=0;
kk=k+1;
if (upper-lower)<epsilon
    lambda=(lower(kk)+upper(kk))/2;
else
    t=lower+0.382*(upper-lower);   s=lower+0.618*(upper-lower);
    theta_t=f(x+t*d);      theta_s=f(x+s*d);
    while 1==1
        if theta_t(kk)>theta_s(kk)
            if (upper(kk)-t(kk))<epsilon
                lambda=s(kk);
                break
            else
                lower(kk+1)=t(kk);   upper(kk+1)=upper(kk);
                t(kk+1)=s(kk);
                s(kk+1)=lower(kk+1)+0.618*(upper(kk+1)-lower(kk+1));
                theta_t(kk+1)=f(x+t(kk+1)*d);
                theta_s(kk+1)=f(x+s(kk+1)*d);
                k=k+1;
                kk=k+1;
            end
        else
            if (s(kk)-lower(kk))<epsilon
                lambda=t(kk);
                break
            else
                lower(kk+1)=lower(kk);  upper(kk+1)=s(kk);
                s(kk+1)=t(kk);
                t(kk+1)=lower(kk+1)+0.382*(upper(kk+1)-lower(kk+1));
                theta_t(kk+1)=f(x+t(kk+1)*d);
                theta_s(kk+1)=f(x+s(kk+1)*d);
                k=k+1;
                kk=k+1;
            end
        end
    end
end
target_x=x+lambda*d;
target_value=f(x+lambda*d);
fprintf('算法迭代次数为%d,输出的λ=%f,目标函数值为:%f\n',k,lambda,target_value);  %输出结果
target_x
end

main.m

clear all
clc

%% 数据输入
% 创建目标函数的句柄函数
f=@(x)(1-x(1))^2+100*(x(2)-x(1)^2)^2;
%输入起始点
x=[0,0]';
%输入迭代方向
d=[1,0]';
%输入精度
epsilon=0.001;
%初始区间下界
lower=0;
%初始区间上界
upper=1;    

%% 通过黄金分割法计算
[target_value,target_x,k,lambda] = Goldsection(f,epsilon,x,d,upper,lower);

%target_value 储存当前精度下目标函数极小值
%target_x 储存当前精度下目标函数为极小值时x的位置,通常是向量
%  k    储存迭代次数
%lambda 储存迭代步长

3.2 使用说明

以下题为例:
  求Rosenbrock函数
min ⁡ f ( x ) = ( 1 − x 1 ) 2 + 100 ( x 2 − x 1 2 ) 2 \min f(x)=(1-x_1)^2+100(x_2-x_1^2)^2 minf(x)=(1x1)2+100(x2x12)2
在点 x k = ( 0 , 0 ) T x_k=(0,0)^T xk=(0,0)T处沿方向 d k = ( 1 , 0 ) T d^k=(1,0)^T dk=(1,0)T的近似步长。其中黄金分割法的初始区间 [ 0 , 1 ] [0,1] [0,1],精度 ϵ = 0.001 ϵ=0.001 ϵ=0.001.

  1. 保证main.m和Goldsection.m文件在同一目录下.
  2. 打开main.m,
    输入目标函数句柄函数:f=@(x)(1-x(1))$^2+100*(x(2)-x(1)^2)^2;
    修改为起始点x=[0,0]';
    修改迭代方向d=[1,0]';
    修改精度epsilon=0.001;
    修改初始区间下界lower=0;
    修改初始区间上界upper=1;
  3. 运行,即可得到
    运行结果图
    其中target_x为当前精度下目标函数为极小值时x的位置。
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值