Dogleg“狗腿”最优化算法
生活随笔
收集整理的這篇文章主要介紹了
Dogleg“狗腿”最优化算法
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
近期剛學(xué)習(xí)了dogleg狗腿最優(yōu)化算法,老師給出了一個(gè)大體的框架并給出了一個(gè)練習(xí),讓我們用程序去實(shí)現(xiàn)它,鑒于本人剛剛開(kāi)始接觸最優(yōu)化,對(duì)MATLAB語(yǔ)言的使用也很生疏,在網(wǎng)上查閱了大量的資料,一個(gè)通宵把算法寫(xiě)出來(lái),并在matlab中得到了驗(yàn)證。
老師給出的練習(xí)為,。Dogleg狗腿算法是信賴域算法中的一個(gè)subproblem,其主要用來(lái)求d向量,也就是搜索方向。在寫(xiě)代碼的時(shí)候,發(fā)現(xiàn)老師給出的框架當(dāng)中,沒(méi)有涉及到的取值,在查閱了很多資料之后,知道的取值與和和信賴域的取值有關(guān),具體的關(guān)系會(huì)在程序中體現(xiàn)。此外,在代碼程序中,最困擾的我是程序?qū)瘮?shù)的普適性,只要給出一個(gè)函數(shù),代碼會(huì)自動(dòng)的進(jìn)行,而不是需要人為地把函數(shù)各個(gè)變量的系數(shù)先算出來(lái)。代碼如下:
主程序(demo_dogleg):
%programed by Lu Qi,UCAS
%my email:qqlu1992@gmail.com
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]'; %初始點(diǎn)的坐標(biāo)
[x_final,num_iter]=dogleg(pars);
fprintf('x_final= \n');
[m, n] = size(x_final);
for i = 1 : mfor j = 1 : nfprintf('%8.4f', x_final(i, j));endfprintf('\n');
end
fprintf('num_iter=%d',num_iter);其中,在程序中,前半部分,也就是在dogleg函數(shù)之前的代碼,是用來(lái)求函數(shù)的一次偏導(dǎo)和二次偏導(dǎo),所以如果想求不同的函數(shù),可以僅僅改變pars.f_x_y的值。
下面是實(shí)現(xiàn)dogleg算法的程序(dogleg):
function [x_final,i]=dogleg(pars)
global syms x y
%programed by Lu_Qitemp=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)breakendfprintf('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; endendif tao <=1 && tao >= 0d_tao = tao * d_u; else if tao <=2 && tao >= 1d_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;
end
x_final=temp;
dogleg的程序中包含了如下三個(gè)小函數(shù):
calculate函數(shù),用來(lái)求在某一坐標(biāo)下的g(x)和b(x)的值:
%calculate g_x b_x
old={x,y};
new={temp_x ,temp_y};
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函數(shù)用來(lái)求兩點(diǎn)的差值:
function result=f_x_result(pars,temp_x,temp_y,d)
%
global syms x y
old={x,y};
new={temp_x ,temp_y};
result=subs(pars.f_x_y,old, new);
new={temp_x+d(1),temp_y+d(2)};
result=result-subs(pars.f_x_y,old, new);q_x_result函數(shù)用來(lái)求近似情況下兩點(diǎn)的差值:
function result=q_x_result(pars,d_tao)
%
result=-(d_tao'*pars.g_x+0.5*d_tao'*pars.b_x*d_tao);這樣整個(gè)程序就完成了,測(cè)試后的結(jié)果為:
由于本人在菜鳥(niǎo)一個(gè),剛剛進(jìn)入研究生的門(mén)檻,難免在程序的思路上出現(xiàn)錯(cuò)誤,還請(qǐng)大家多多指教,也可以郵件進(jìn)行交流,共同進(jìn)步。我的郵箱是qqlu1992@gmail.com,謝謝大家斧正。
由于本人在菜鳥(niǎo)一個(gè),剛剛進(jìn)入研究生的門(mén)檻,難免在程序的思路上出現(xiàn)錯(cuò)誤,還請(qǐng)大家多多指教,也可以郵件進(jìn)行交流,共同進(jìn)步。我的郵箱是qqlu1992@gmail.com,謝謝大家斧正。
總結(jié)
以上是生活随笔為你收集整理的Dogleg“狗腿”最优化算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 简书显示服务器错误,openfire服务
- 下一篇: 聚类之isodata算法