# 信赖域狗腿（dogleg）方法

### 信赖域狗腿方法

#### 原理简述

• 当B点在信赖域内部时，取方向为 pU p U $p^U$方向， xk+1 x k + 1 $x_{k+1}$点为B点：
• 当B点和U点都在信赖域外时，取下一个迭代点为 pU p U $p^U$和信赖域边界的交点：
• 当B点在外，U点在内时，去BU连线和信赖域边界的交点：

#### 算法步骤

τ τ $\tau$ sk=xk+1xk s k = x k + 1 − x k $s_k = x_{k+1} - x_k$的计算就是使用上面提到的狗腿方法。

#### 代码

function [x,k] = trust_region1(varargin)
%帮助信息：
%clc
%clear
%输入参数为options = struct('f',f,'x0',[0;0],'Delta',1,'Delta0',0.1,'eta',1/4);
if nargin < 1, help(mfilename),
f = @(x1,x2)100*(x2-x1^2)^2 + (1-x1)^2;
options = struct('f',f,'x0',[0;0],'Delta_hat',10,'Delta0',0.1,'eta',0);
fprintf('使用默认参数…… \n \n');
end

f = options.f;
syms x1 x2;
f_s = f(x1,x2);
x0 = options.x0;
Delta_hat = options.Delta_hat;
Delta0 = options.Delta0;
eta = options.eta;
df = diff_handle(f_s);
B = hessian(f_s);
Delta = Delta0;
x = x0;
step = 100;
for k = 0:step-1
x
fk = f(x(1),x(2));
dfk = df(x(1),x(2));
Bk = subs(B,{x1,x2},{x(1),x(2)});
Bk = double(Bk);
sk = cal_sk(dfk,Bk,Delta);
m = @(p) fk + dfk'*p + 1/2*p'*Bk*p;
rho_k = cal_rho_k(f,m,x,sk);
if rho_k < 1/4
Delta = 1/4*Delta;
elseif rho_k > 3/4 && abs(norm(sk,2) - Delta)<1.0e-10;
Delta = min(2*Delta,Delta_hat);
else
%不做任何操作；
end

if rho_k > eta
x = x + sk;
else
%不做任何操作；
end
end

end

function df = diff_handle(f_s)
syms x1 x2;
df = [diff(f_s,x1); diff(f_s,x2)];
df = matlabFunction(df);
end

function tau = cal_tau(pB,pU,Delta)
npB = sqrt(pB'*pB);
npU = sqrt(pU'*pU);
if npB <= Delta
tau = 2;
elseif npU >= Delta
tau = Delta/npU;
else
pB_U = pB-pU;
tau = (-pU'*pB_U+sqrt((pU'*pB_U)^2-pB_U'*pB_U*(pU'*pU-Delta^2)))/(pB_U'*pB_U);
tau = tau + 1;
end
end
% temp = conj(dfk')*Bk*dfk;
% if  temp<= 0
%     tau = 1;
% else
%     tau = min(norm(dfk,2)/temp,1);

function sk = cal_sk(dfk,Bk,Delta)
pU = -(conj(dfk')*dfk)/(conj(dfk')*Bk*dfk).*dfk;
pB = -Bk^(-1)*dfk;
tau = cal_tau(pB,pU,Delta);
if tau >=0 && tau <=1
sk = tau*pU;
elseif tau >= 1 && tau <=2
sk = pU + (tau-1)*(pB-pU);
else
error('tau的值不能为%f',tau);
end

end

function rho_k = cal_rho_k(f,m,x,sk)
rho_k = (f(x(1),x(2)) - f(x(1)+sk(1),x(2)+sk(2)))/((m([0;0])-m(sk)));
end


10-26
04-04 885

07-23 4432
08-06 2653
03-10 2687
01-21 626
09-21 2888
09-15
12-26 6934