Dogleg「狗腿」最優化演算法

2021-06-25 20:31:28 字數 3418 閱讀 4202

近期剛學習了dogleg狗腿最優化演算法,老師給出了乙個大體的框架並給出了乙個練習,讓我們用程式去實現它,鑑於本人剛剛開始接觸最優化,對matlab語言的使用也很生疏,在網上查閱了大量的資料,乙個通宵把演算法寫出來,並在matlab中得到了驗證。

老師給出的練習為

主程式(demo_dogleg):

%programed by lu qi,ucas

%my email:[email protected]

global syms x y

pars.f_x_y=100*(y - x^2).^2 + (1 - x)^2;

pars.dfdx=diff(pars.f_x_y,x,1);

pars.dfdy=diff(pars.f_x_y,y,1);

pars.df2dxdy=diff(pars.dfdx,y,1);

pars.df2dx2=diff(pars.dfdx,x,1);

pars.df2dy2=diff(pars.dfdy,y,1);

pars.trustregionbound=10; %信賴域

pars.tao=2; %tao的初始化

pars.x0=[-9 -9]'; %初始點的座標

[x_final,num_iter]=dogleg(pars);

fprintf('x_final= \n');

[m, n] = size(x_final);

for i = 1 : m

for j = 1 : n

fprintf('%8.4f', x_final(i, j));

endfprintf('\n');

endfprintf('num_iter=%d',num_iter);

其中,在程式中,前半部分,也就是在dogleg函式之前的**,是用來求函式的一次偏導和二次偏導,所以如果想求不同的函式,可以僅僅改變pars.f_x_y的值。

下面是實現dogleg演算法的程式(dogleg):

function [x_final,i]=dogleg(pars)

global syms x y

%programed by lu_qi

temp=pars.x0;

temp_x=temp(1);

temp_y=temp(2);

calculate;

fan_g_x=sum(abs(pars.g_x));

tao=pars.tao;

i=1;

while(1)

if(fan_g_x<=0.00001)

break

endfprintf('iter=%d\n',i);

d_u=pars.g_x'*pars.g_x/(pars.g_x'*pars.b_x*pars.g_x);

d_u=-d_u*pars.g_x;

d_b=inv(pars.b_x);

d_b=-d_b*pars.g_x;

if d_u'*d_u > pars.trustregionbound*pars.trustregionbound;

tao = pars.trustregionbound / sqrt((d_u'*d_u));

else if d_b'*d_b > pars.trustregionbound*pars.trustregionbound

tao = sqrt((pars.trustregionbound*pars.trustregionbound - d_u'*d_u) / ((d_b-d_u)'*(d_b-d_u))) + 1;

endend

if tao <=1 && tao >= 0

d_tao = tao * d_u;

else if tao <=2 && tao >= 1

d_tao = d_u + (tao - 1) * (d_b - d_u);

end

endp=((f_x_result(pars,temp_x,temp_y,d_tao))/(q_x_result(pars,d_tao)));

if p > 0.75 && abs(d_tao'*d_tao)==pars.trustregionbound

pars.trustregionbound = min(2 * pars.trustregionbound, 3);

else if p < 0.25

pars.trustregionbound = sqrt(abs(d_tao'*d_tao)) * 0.25;

end

end

if p > 0

temp = temp + d_tao;

endtemp_x=temp(1);

temp_y=temp(2);

calculate;

fan_g_x=sum(abs(pars.g_x));

i=i+1;

endx_final=temp;

dogleg的程式中包含了如下三個小函式:

calculate函式,用來求在某一座標下的g(x)和b(x)的值:

%calculate g_x b_x

old=;

new=;

pars.g_x=[subs(pars.dfdx,old, new);subs(pars.dfdy,old, new)];

pars.b_x=[subs(pars.df2dx2,old, new) subs(pars.df2dxdy,old, new);

subs(pars.df2dxdy,old, new) subs(pars.df2dy2,old, new)

f_x_result函式用來求兩點的差值:

function result=f_x_result(pars,temp_x,temp_y,d)

%global syms x y

old=;

new=;

result=subs(pars.f_x_y,old, new);

new=;

result=result-subs(pars.f_x_y,old, new);

q_x_result函式用來求近似情況下兩點的差值:

function result=q_x_result(pars,d_tao)

%result=-(d_tao'*pars.g_x+0.5*d_tao'*pars.b_x*d_tao);

這樣整個程式就完成了,測試後的結果為:

由於本人在菜鳥乙個,剛剛進入研究生的門檻,難免在程式的思路上出現錯誤,還請大家多多指教,也可以郵件進行交流,共同進步。我的郵箱是[email protected],謝謝大家斧正。

DoglegMethod 「狗腿」演算法

問題 對於最速下降法,本質的等式在於x k 1 x k a k d k x k 為定義域上的點,a k 為前進的步長,是乙個標量,d k 是前進的方向,對於高維變數d k 就是向量,是乙個列向量。一般常用的是取d k 為x k 點負梯度方向,當然也可以用到海森陣,就是跟牛頓法很像的一系列演算法。非線...

最優化 牛頓優化演算法

本人總結的常用優化演算法pdf版本,主要講解原理 主要包括梯度下降,共軛梯度法 牛頓法,擬牛頓法 信賴域方法,罰函式法。coding utf 8 author uniquez file 牛頓法,基於dfp的擬牛頓法 date 2017 06 24 remark 原方程為 x1 2 2 x2 2 im...

最優化 數值優化演算法

核心思路 對梯度方向做一些修正,使得每次迭代尋找最優點都在可行域的內部進行。我們從可行域內部的某個點開始搜尋,一開始沿著梯度方向進行迭代搜尋,一旦碰到邊界 說明下一步可能會離開可行域 就要扭轉方向,使得搜尋過程始終在可行域的內部進行。當點落在可行域外部時,該怎樣選擇搜尋方向,衍生出了下列的演算法。1...