优化算法:信赖域法(含matlab代码)

1.简介

在求解优化问题时,信赖域法不要求目标函数的凸性。其基本思想是在迭代点附近(信赖域内)用二次型逼近目标函数,并求其极小值作为下一个迭代点。当迭代后函数下降不充分时,调整信赖域的大小。

2.算法介绍

以下内容引用自文献[1]。

3.matlab代码

3.1 信赖域法matlab函数

%f:目标函数
%H0:初始的海森矩阵
%x0:初始的迭代点 为列向量
%k:迭代次数
%X存储每次迭代的x,F为目标函数,G为每次的梯度,H为海森阵,HN为海森矩阵的逆

function [X, F, G, H] = trust_region(x0, f, my_gradient, my_hessian)
%% 变量初始化
max_step = 1e3;
eps = 1e-5; 
m = length(x0);
X = zeros(m, max_step+1); % x1、x2的迭代值
H = zeros(m, m, max_step+1); % hessian的迭代值
F = zeros(max_step+1, 1); % function的迭代值
G = zeros(m, max_step+1); % 梯度的迭代值
% 赋初始值
X(:,1) = x0; % X(x1, x2)初始化
F(1, 1) = f(x0);
% 信赖域问题的参数
exp_rou = 0.8; % 预期下降量
gamma = 0.7; % 信赖域半径调整参数
delta = 2; % 初始信赖域半径
     
%% 迭代
for k = 1: max_step
    G(:, k) = my_gradient(X(:, k)); % 求梯度
    H(:, :, k) = my_hessian(X(:, k)); % 求hessian阵

    % 求信赖域子问题
    A=[];  Aeq=[];  b=[];  beq=[]; lb=[]; ub=[];
    trust_f = @(s) sub_f(s, G(:, k), H(:, :, k));
    trust_con = @(s) con_sub_f(s, delta);
    [trust_step, trust_fval] = fmincon(trust_f, X(:, k), A,b,Aeq,beq,lb,ub,trust_con);
    rou = (f(X(:,k)) - f(X(:,k) + trust_step))/(trust_f([0;0]) - trust_fval);
    % x迭代
    if rou > exp_rou && isreal(rou)
        X(:,k+1) = X(:,k) + trust_step;
    else
        X(:,k+1) = X(:,k);
        % 调整信赖域半径
        delta = gamma*delta;
    end

    F(k) = f(X(:, k));
    % 梯度消失后结束程序
    if norm(G(:, k)) < eps
        break;
    end
end
% 输出
X = X(:, 1:k);
H = H(:, :, 1:k);
F = F(1: k);
G = G(:, 1:k);
end

% 信赖域子问题的约束函数
function [c, ceq] = con_sub_f(s, delta)
c =  s'*s - delta^2;
ceq = [];
end

% 信赖域子问题的目标函数
function out = sub_f(s, G, H)
if length(s(1, :)) > 1
    s = s';
end
out = G'*s + 1/2*s'*H*s;
end

3.2 一个简单的测试

f = @(x) x(1).^2 + 3*x(2).^2 + exp(x(1));
grd = @(x) [2*x(1) + exp(x(1)); 6*x(2)];
hes = @(x) [2 + exp(x(1)), 0;
            0, 6];
x0 = [3; 3];
[X, F, G, H] = trust_region(x0, f, grd, hes);

3.3 非凸算例

考虑如下的问题,其目标函数非凸,在最优解附近凸。该问题来自于北航最优化理论与方法I2024秋季的大作业。

计算该函数的函数值,梯度,hessian阵。

function [cost, gradient, my_hessian] = target_function(input_x1, input_x2, flag)
%% 初始化
cost = 0;
gradient = 0;
my_hessian = 0;
%% 符号函数运算
syms x1 x2
a = [0.3; 0.6; 0.2];
b = [5; 26; 3];
c = [40; 1; 10];
u = x1 - 0.8;
v = x2 - a'*[1; u.^2.*sqrt(1-u); -u];
alpha = b'*[-1; u.^2.*sqrt(1+u); u];
beta = c(1)*v.^2.*(1-c(2)*v)./(1+c(3)*u.^2);
f = alpha.*exp(-beta);
%% 数值运算
% 目标函数
if ~(flag == 2 || flag == 3)
    cost_fun = matlabFunction(f);
    cost = cost_fun(input_x1, input_x2);
end
% 梯度函数
if ~(flag == 1 || flag == 3)
    grad_f(1) = diff(f, x1);
    grad_f(2,1) = diff(f, x2);
    grad_f_fun = matlabFunction(grad_f);
    gradient = grad_f_fun(input_x1, input_x2);
end
% Hessian矩阵
if ~(flag == 1 || flag == 2)
    grad_f(1) = diff(f, x1);
    grad_f(2,1) = diff(f, x2);
    H = jacobian(grad_f, [x1;x2]);
    H_fun = matlabFunction(H);
    my_hessian = H_fun(input_x1, input_x2);
end
end

信赖域法求解该问题:

% 信赖域法求解
clear; clc; close all;
%% 信赖域法求解
% 第一个点
x0_1 = [0.8; 0.3];
[x_rec1, f_rec1, G_rec1, H_rec1] = trust_region(x0_1, @cal_cost, @cal_gradient, @cal_hessian);
% 第二个点
x0_2 = [1; 0.5];
[x_rec2, f_rec2, G_rec2, H_rec2] = trust_region(x0_2, @cal_cost, @cal_gradient, @cal_hessian);
%% 画图
figure(1);
plot_equal_height;
hold on;
plot(x_rec1(1, :), x_rec1(2, :), 'o', 'LineWidth', 1.5, 'Color', [0.7, 0, 0]);
plot(x_rec1(1, :), x_rec1(2, :), 'LineWidth', 1.5, 'Color', [0.7, 0, 0]);
title('信赖域法迭代点,x_0 = (0.8, 0.3)');

figure(2);
plot_equal_height;
hold on;
plot(x_rec2(1, :), x_rec2(2, :), 'o', 'LineWidth', 1.5, 'Color', [0.7, 0, 0]);
plot(x_rec2(1, :), x_rec2(2, :), 'LineWidth', 1.5, 'Color', [0.7, 0, 0]);
title('信赖域法迭代点,x_0 = (1, 0.5)');

%% 计算目标函数
function out = cal_cost(x)
[out, ~, ~] = target_function(x(1), x(2), 1);
end

% 计算目标函数梯度
function out = cal_gradient(x)
[~, out, ~] = target_function(x(1), x(2), 2);
end

% 计算目标函数hessian阵
function out = cal_hessian(x)
[~, ~, out] = target_function(x(1), x(2), 3);
end

求解结果如下:

易见:目标函数的下水平集在局部是非凸的,说明目标函数是非凸的,但是采用信赖域法仍然可以手链到最优解。如果采用基本牛顿法,当初始点距离最优解较远时结果将发散。

参考文献

[1]刘东磊.非线性优化问题的内点信赖域算法研究[D].青岛大学,2021. 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Williamlliw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值