matlab一维搜索_工程优化设计与Matlab实现——无约束问题的导数解法(变尺度法)...

尺有所短,寸有所长。 ——屈原《楚辞·卜居》

取其精华去其糟粕。 ——鲁迅《拿来主义》

变尺度法

如果说我们想要在距离极值点比较远的起点处,像最速下降法那样小计算量且速度不算太慢迭代,在距离极值点比较近时像牛顿法那样快速收敛,该怎么办呢?

让我们回顾一下这两种方法的迭代思路:

最速下降法迭代:

equation?tex=x_%7B1%7D%3Dx_%7B0%7D%2B%5Calpha_0+%5B-%E2%96%BDf%28x_0%29%5D

阻尼牛顿法迭代:

equation?tex=x%3Dx_%7B0%7D%2B%5Calpha_0%5B-%5BH%28x_%7B0%7D%29%5D%5E%7B-1%7D%E2%96%BDf%28x_%7B0%7D%29%5D

可以看出,迭代的差别在于方向的不同,阻尼牛顿方法的方向比最速下降法多了一个Hessian矩阵的逆。

那我们是否可以构造一个矩阵

equation?tex=A 来取代阻尼牛顿法中Hessian矩阵的位置,并且这个矩阵可以随着迭代点位置作出改变,在起始点时
equation?tex=A%3D1 ,在极值点时
equation?tex=A%3DH%5E%7B-1%7D

答案当然是肯定的,这就是像“初一到十五的月亮”一样的变尺度法,其迭代公式如下:

equation?tex=x%3Dx_%7B0%7D%2B%5Calpha_0%5B-A_0%E2%96%BDf%28x_%7B0%7D%29%5D

那么问题就来了,这个矩阵

equation?tex=A怎么构造呢?别急,看Point 1 。

Point 1 变尺度矩阵

equation?tex=A的建立

一方面,构造近似矩阵

equation?tex=A 的迭代格式:
equation?tex=A_1%3DA_0%2B%5CDelta+A_0

其中

equation?tex=A_1
equation?tex=A_0 是n阶对称阵,则修正矩阵
equation?tex=%5CDelta+A_0 也一定是n阶对称阵

所以

equation?tex=%5CDelta+A_0 的格式可以设为
equation?tex=%5CDelta+A_0%3DC_1uu%5ET%2BC_2vv%5ET

故有

equation?tex=A_1%3DA_0%2B%28C_1uu%5ET%2BC_2vv%5ET%29

另一方面,对目标函数在

equation?tex=x_0 点泰勒二阶展开,有:

equation?tex=f%28x%29%3Df%28x_0%29%2B%5B%E2%96%BDf%28x_0%29%5D%5ET%28x-x_0%29%2B1%2F2%5Bx-x_0%5D%5ETH%28x_0%29%28x-x_0%29

求一阶导数有:

equation?tex=%E2%96%BDf%28x%29%3D%E2%96%BDf%28x_0%29%2BH%28x_0%29%28x-x_0%29

将迭代点

equation?tex=x_1 代入上式,有:
equation?tex=%E2%96%BDf%28x_1%29-%E2%96%BDf%28x_0%29%3DH%28x_0%29%28x_1-x_0%29

移项得:

equation?tex=%E2%96%BDf%28x_1%29-%E2%96%BDf%28x_0%29%3DH%28x_0%29%28x_1-x_0%29

equation?tex=x_1-x_0%3D%5BH%28x_0%29%5D%5E%7B-1%7D%5B%E2%96%BDf%28x_1%29-%E2%96%BDf%28x_0%29%5D

此时,令

equation?tex=%5CDelta+x_0%3Dx_1-x_0%3B+%5CDelta+g_0%3D%E2%96%BDf%28x_1%29-%E2%96%BDf%28x_0%29

则有

equation?tex=%5CDelta+x_0%3D%5BH%28x_0%29%5D%5E%7B-1%7D%5CDelta+g_0

两个方面都准备好后,我们用

equation?tex=A_1 代替
equation?tex=%5BH%28x_0%29%5D%5E%7B-1%7D ,就有:
equation?tex=%5CDelta+x_0%3DA_1%5CDelta+g_0

代入

equation?tex=A_1%3DA_0%2B%28C_1uu%5ET%2BC_2vv%5ET%29 ,并移项得:

equation?tex=C_1uu%5ET%5CDelta+g_0%2BC_2vv%5ET%5CDelta+g_0%3D%5CDelta+x_0-A_0%5CDelta+g_0

观察上式,令

equation?tex=u%3D%5CDelta+x_0%3Bv%3DA_0%5CDelta+g_0 ,得:

equation?tex=C_1%5CDelta+x_0%5B%5CDelta+x_0%5D%5ET%5CDelta+g_0%2BC_2%5BA_0%5CDelta+g_0%5D%5BA_0%5CDelta+g_0%5D%5ET%5CDelta+g_0%3D%5CDelta+x_0-A_0%5CDelta+g_0

比较左右两边系数,可得:

equation?tex=C_1%3D%5B%28%5CDelta+x_0%29%5ET%5CDelta+g_0%5D%5E%7B-1%7D
equation?tex=C_2%3D-%5B%28%5CDelta+g_0%29%5ETA_0%5CDelta+g_0%5D%5E%7B-1%7D

equation?tex=C_1
equation?tex=C_2
equation?tex=u
equation?tex=v 代入
equation?tex=A_1%3DA_0%2B%28C_1uu%5ET%2BC_2vv%5ET%29

就得到变尺度矩阵:

b9f053bc877064b36f3338455a446f60.png

Point 2 变尺度法的步长

变尺度矩阵构造完成,搜索方向也就确定了,然后又是一维搜索求最优步长了,此处省略N个字。如有疑问,请往前参考:工程优化设计与Matlab实现——一维搜索方法(总结)中提到的一维搜索解决多维问题,工程优化设计与Matlab实现——无约束问题的导数解法(一)中最速下降法求最优步长,工程优化设计与Matlab实现——无约束问题的导数解法(三)中阻尼牛顿法求最优步长。

e8e5632a4be73942209038efd6e7a3b2.png
变尺度法流程

Point 3 栗子

利用变尺度法求目标函数

equation?tex=f%28x%29%3Dx_1%5E2%2B2x_2%5E2-2x_1x_2-4x_1 ,在初始值为
equation?tex=%5B0%2C0%5D%5ET 时的极小值点和极小值。

主程序:

clc;
clear all;
close all;
%设置精度、函数、起始点
e = 1e-4;
x0 = [0;0];
%-----------调用变尺度法(使用求导的方式,获得步长)-----------%
fprintf('nn变尺度法:(使用求导的方式,获得步长)n')
[BianChiDuFa1_x, BianChiDuFa1_xf, BianChiDuFa1_n] = BianChiDuFa(e, x0);
fprintf('变尺度法极值点:n%fn%fn%fn%fn',BianChiDuFa1_x)
fprintf('变尺度法极值:%fn变尺度法迭代次数:%dn', BianChiDuFa1_xf, BianChiDuFa1_n)
%-----------调用变尺度法(使用求导的方式,获得步长)-----------%
fprintf('n变尺度法:(使用一维搜索方法,获得步长)n')
[BianChiDuFa2_x, BianChiDuFa2_xf, BianChiDuFa2_n] = BianChiDuFa2(e, x0);
fprintf('变尺度法极值点:n%fn%fn%fn%fn',BianChiDuFa2_x)
fprintf('变尺度法极值:%fn变尺度法迭代次数:%dn', BianChiDuFa2_xf, BianChiDuFa2_n)

目标函数定义:

function f = func(x)
    f = x(1)^2 + 2 * x(2)^2 - 2 * x(1) * x(2) - 4 * x(1);

变尺度法函数定义:

使用求导的方式,获得步长

%-----------变尺度法---主函数-----------%
function [BianChiDuFa_x, BianChiDuFa_xf, BianChiDuFa_n] = BianChiDuFa(e, x0)
    syms t1 t2 t3 t4 a
    x = [t1;t2];
    f = func(x);
    
    %求x0处jacobian矩阵的值
    yf = jacobian(f)';       %求jacobian矩阵的转置(梯度)

    n = 0;                     %迭代次数统计
    A0 = 1;
    k = 1;                      %迭代开
    while k == 1
        n = n + 1;                     %迭代次数统计     
        yf_x0 = subs(yf, x, x0);     %将x0代入,得x0处的梯度
        d0 = -A0 * yf_x0;                                   %x0迭代方向

        %求最优步长a
        x1 = x0 + a * d0;                 %设最优步长为未知数a,求得x1
        f_x1 = subs(f, x, x1);            %将x1代入原函数
        diff_f_a =diff(f_x1, a);          %将x1代入原函数后得到的含有a的函数,对a求偏导 
        a_n = solve(diff_f_a, a);         %偏导数等于0,求得使函数取极值的a

        %将求得的a代回,求得具体的x1,f(x1),和x1处的梯度
        x1 = subs(x1, a, a_n);             %x1的具体值
        f_x1 = subs(f, x, x1);             %x1的函数值
        yf_x1 = subs(yf, x, x1);           %x1的梯度值
        
        f_x0 = subs(f, x, x0);            %将x0代入原函数
        
        %判断迭代是否终止
        if abs(f_x1-f_x0) <= e
            break
        else
            Dx0 = x1 - x0;
            Dyf0 = yf_x1 - yf_x0;
            DA0 = (Dx0 * Dx0') / (Dx0' * Dyf0) - (A0 * Dyf0 * Dyf0' * A0) / (Dyf0' * A0 * Dyf0);
            A1 = A0 + DA0;
            x0 = x1;
            A0 = A1;
        end
    end

    BianChiDuFa_x = vpa(x1);
    BianChiDuFa_xf = vpa(f_x1);
    BianChiDuFa_n = n;

使用一维搜索方法,获得步长

%-----------变尺度法---主函数-----------%
function [BianChiDuFa_x, BianChiDuFa_xf, BianChiDuFa_n] = BianChiDuFa2(e, x0)
    syms t1 t2 t3 t4 a
    x = [t1;t2];
    f = func(x);
    
    %求x0处jacobian矩阵的值
    yf = jacobian(f)';       %求jacobian矩阵的转置(梯度)

    n = 0;                     %迭代次数统计
    A0 = 1;
    k = 1;                      %迭代开
    while k == 1
        n = n + 1;                     %迭代次数统计     
        %fprintf('迭代次数:%fn',n)
        
        f_x0 = subs(f, x, x0);       %将x0代入,得x0处的函数值
        yf_x0 = subs(yf, x, x0);     %将x0代入,得x0处的梯度
        d0 = -A0 * yf_x0;            %x0迭代方向

        %一维搜索方法求最优步长(求x1)
        [JT_a, JT_b, JT_c] = JinTuiFa(x0, 0.1, d0);    %进退法初始搜索步长,设为0.1    
        [x1, f_x1, HJFGF_n] = HuangJinFenGeFa(JT_a, JT_c, e);   %黄金分割法
        yf_x1 = subs(yf, x, x1);           %x1的梯度值
        
        if abs(f_x1-f_x0) <= e
            break
        else
            Dx0 = x1 - x0;
            Dyf0 = yf_x1 - yf_x0;
            DA0 = (Dx0 * Dx0') / (Dx0' * Dyf0) - (A0 * Dyf0 * Dyf0' * A0) / (Dyf0' * A0 * Dyf0);
            A1 = A0 + DA0;
            x0 = x1;
            A0 = A1;
        end
    end

    BianChiDuFa_x = vpa(x1);
    BianChiDuFa_xf = vpa(f_x1);
    BianChiDuFa_n = n;

    

进退法程序:工程优化设计与Matlab实现——一维搜索方法(一)

黄金分割法程序:工程优化设计与Matlab实现——一维搜索方法(二)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值