最优化方法---无约束问题:精确线性搜索方法

一、进退法及MATLAB实现

 

# MATLAB代码
# function  [a1,a2,a3]=jintuifa(a1,h)
syms a a1 a2 a3 
f=a^2-6*5*a+76;
h=0.1;
% 初始值
a1=2;
a2=a1+h;
f1=subs(f,a,a1);
f2=subs(f,a,a2);
if f1>f2:  %这里为进
    a3=a2+h;
    f3=subs(f,a,a3);
    while f3<f2:
        a1=a2;  %替换
        a2=a3;
        a3=a2+h;  %迭代
        f1=subs(f,a,a1);
        f2=subs(f,a,a2);
        f3=subs(f,a,a3);
    end
    lb=a1;
    rb=a3;
elseif f1<f2: %这里为退
    a3=a1-h;
    f3=subs(f,a,a3);
    while f3<f1:
        a2=a1;  %替换
        a1=a3;
        a3=a1-h;  %迭代
        f1=subs(f,a,a1);
        f2=subs(f,a,a2);
        f3=subs(f,a,a3);
    end
    lb=a3;
    rb=a2;
end
 
# 运行
[a,b,c]=jintuifa(0,0.1);      

有待深入的问题

  • 效率问题:
    • 在确定f(x)为单峰函数的情况下,如何确定初始点、步长或二者的组合,使得算法的效率最高? 

 

 二、黄金分割法及其MATLAB代码实现

 

# 黄金分割法
# function x=huangjinfenge(lb,rb,eps)
eps=1.0e-6;
x1=lb+0.383*(rb-lb);
x2=lb+0.618*(rb-lb);
f1=subs(f,a,x1);
f2=subs(f,a,x2);
while abs(rb-lb) > eps   % 循环
    if f1<f2   
        rb=x2;
        x1=x2;
        f2=f1;
        x1=lb+0.383*(rb-lb);
        f1=subs(f,a,x1);
    else  % f1 >= f2
        lb=x1;
        x1=x2;
        f1=f2;
        x2=lb+0.618*(rb-lb);
        f2=subs(f,a,x2);
    end
end
xx=(rb+lb)/2;
[a,b,c]=jintuifa(0,0.1);
x=huangjinfenge(a,c,10^-4);
fprintf('黄金分割法:\tx*=%f\tf(x)=%f\n',x,f(x));
  • 黄金分割法的缺点
    • 该算法对各探索点的函数值都进行了计算,但仅用来比较大小,具体函数值并没有被利用,因此该算法的收敛速度较慢。
    • 推荐插值法和多项式逼近法

 三、插值法---一维牛顿法及MATLAB代码实现

# 一维牛顿法
clear all 
clc
% 定义变量、函数f及函数的泰勒展开g
syms x x0 x1
eps=1.0e-6;   %定义误差
f=x^4-x^2-1;   %定义函数f
x0=4;    %定义泰勒展开的初始点
g=taylor(f,3,x,x0)   %f在初始点x0的二阶泰勒展开
gp=diff(g,x)    %求g的一阶导数gp
x1=solve(gp,x)   %令g的一阶导数gp为0,得到g的极小值点
fp=diff(f,x)    %求f的一阶导数
fpb=subs(fp,x,x1)   %求f在x1处的一阶导数值
c=double(fpb)    %把fpb转化为数值,以便于和eps比较
%判断是否满足终止条件,循环
while c>eps    
    x0=x1   %重新赋值
    g=taylor(f,3,x,x0)
    gp=diff(g,x)
    x1=solve(gp,x)
    fpb=subs(fp,x,x1)
    c=double(fpb)
end
xx=double(x1)   #最优解
minf=subs(f,x1,x)
minf=double(minf)

 一维牛顿法的特点

  • 优点:收敛速度快。
  • 需要注意:只能保证收敛的极限是f(x)的驻点,因此,为了保证收敛到极小点,应要求f''(x)>0,至少对足够大的n如此。

 四、插值法---抛物线法及MATLAB代码实现

 四、二分法及MATLAB代码实现

lb=0;
rb=1;  %根据进退法找到搜索区间
eps=1.0e-6;
middle=(lb+rb)/2;   %求中点值
f=2*x^2+4^x-2;    %目标函数
fp=diff(f,x);    %函数的一阶导数
fpb=subs(fp,x,middle);   %一阶导数在中点处的值
while fpb != 0 and abs(rb-lb)>eps   %一阶导数值不等于0时,非极小值点
    if fbp<0    
        lb=middle;    
    end
    if fbq>0:
        rb=middle;
    middle=(lb+rb)/2;
    fpb=subs(fp,x,middle);
# 当一阶导数等于0或者搜索区间小于误差时,跳出循环
xx=(rb+lb)/2;

 

 

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值