基於黃金分割的修正Powell演算法

2021-07-11 01:19:03 字數 3852 閱讀 5151

function y= textf(x)

%目標函式

%輸入引數x[x1,x2];

%輸出引數y

y = x(1)*x(1)+2*x(2)*x(2)-4*x(1)-2*x(1)*x(2);

end

function [matrix,value] = powell

%--------------------------------step1-------------------------------------

%設定初始迭代輪次k=1;迭代精度:err;初始點;初始搜尋方向組;

err = 0.01;

x0 = [1,1];

dir = [1,0;

0,1];

num = 2;

while(1)

%----------------------------------step2-----------------------------------

%第一輪:

%沿著第乙個方向進行一維搜尋的得到相應的極值

[x(1,:),jz(1)] = onedimensionsearch(x0,dir(1,:),err);

%沿著第2到第num方向進行一維搜尋

for k = 2:num

dir(k,:) = dir(k,:);

[x(k,:),jz(k)] = onedimensionsearch(x(k-1,:),dir(k,:),err);

end%構造新的搜尋方向向量 並以x0為起點,沿此方向進行新一輪搜尋,得到相應的極值

dir(num+1,:) = x(num,:)-x0;

[x(num+1,:),jz(num+1)] = onedimensionsearch(x0,dir(num+1,:),err);

%----------------------------------step3-----------------------------------

%判斷迭代終止條件

delta = x(num+1,:)-x0;

if( sqrt(sum(delta.*delta))<=err )

matrix = x(num+1,:);

value = textf(matrix); %輸出最優解和最優變換引數

break;

else

%----------------------------------step4-----------------------------------

muinfoval_0 = textf(x0);

%計算各個方向上的下降量

diff(1) = muinfoval_0-jz(1);%此時我們在尋找極小值

for k = 2:num

diff(k) = jz(k-1)-jz(k);

end%記錄最下降量 以及 其出現的位置

[maxdiff,m] = max(diff);

%----------------------------------step5-----------------------------------

%計算對映點

xmap = 2*x(num,:)-x0;

%計算powell特徵值

val_0 = textf(x0);

val_1 = textf(x(num,:));

val_2 = textf(xmap);

%判斷powell條件

if(val_2>val_0 && ...

(val_0-2*val_1+val_2)*(val_0-val_1-maxdiff)<0.5*maxdiff(val_0-val_2)^2 )

%----------------------------------step6-----------------------------------

x0 = x(num+1,:);

%替換m位置的搜尋方向

dir(m,:) = dir(num+1,:);

%----------------------------------step7-----------------------------------

if(val_1 < val_2)

x0 = x(num,:);

else

x0 = x(num+1,:);

endend

end

endend

%% 一維搜尋函式:採用**分割法 %%

function [extremepos,extremeval] = onedimensionsearch(x1,dir,err)

% 從x0點開始,進行搜尋

% dir:搜尋的方向。

% err:**分割的停止搜尋的精度。

% 返回極大值extremeval,以及極大值對應的點extremepos

%------------------------step1:進退法確定區間------------------------------

%計算x1,前進,計算x2

y1 = textf(x1);

x2 = x1+dir;

y2 = textf(x2);

%最小值左右支判斷

if y1 < y2 % 右支

dir = -dir;

temp = x1;

x1 = x2;

x2 = temp;

x3 = x2+dir;

y3 = textf(x3);

else %左支 擴大搜尋步法

dir = 2*dir;

x3 = x2+dir;

y3 = textf(x3);

endwhile(1)

if (y2<=y3) %發現極小值所在的區間

a = min(x1,x3);

b = max(x1,x3);

break;

else

x1 = x2;

x2 = x3;

y2 = y3;

x3 = x2+dir;

y3 = textf(x3);

endend%--------------------------step2:**分割----------------------------------

g1 = 0.382; g2 = 0.618;

xx1 = a+g1*(b-a);

yy1 = textf(xx1);

xx2 = a+g2*(b-a);

yy2 = textf(xx2);

delta = sqrt(sum(abs(b-a).*abs(b-a)));

while( delta>=err)

if(yy1 < yy2)

b = xx2;

xx2 = xx1;

yy2 = yy1;

xx1 = a+g1*(b-a);

yy1 = textf(xx1);

else

a = xx1;

xx1 = xx2;

yy1 = yy2;

xx2 = a+g2*(b-a);

yy2 = textf(xx2);

end

delta = sqrt(sum(abs(b-a).*abs(b-a)));

endextremepos = 0.5*(a+b);

extremeval = textf(extremepos);

end

[m,n]=powell

m = 3.9969 1.9985

n = -8.0000

黃金分割查詢

在二分查詢中,我們是取mid等於left和right的中間值,即用等分的方法進行查詢。那為什麼一定要等分吶?能不能進行 分割 也就是mid left 0.618 right left 當然mid要取整數。如果這樣查詢,時間複雜性是多少?也許你還可以程式設計做個試驗,比較一下二分法和 分割 法的執行效...

數學 黃金分割比

今天讀了一本科普讀物,數學美,其中將到了 分割比,普遍的人都認為用 分割比建築的東西是最美得,為什麼全世界的人,都很喜歡這種比例關係呢,我認為在人類的dna中存在乙個基因,這個基因就是,用來存放 分割比的資訊,那這個基因又是怎麼來的呢,我認為在人類還沒進化 的時候,更高階的智慧型生物來到過地球,他們...

結對程式 黃金分割

這周我們的軟體工程作業是結對程式設計。經過前幾次的個人編寫程式,慢慢地找到了一些感覺。對於這次結對程式設計還是挺新鮮的,更是期待後期的團隊程式設計。結對程式設計究竟是什麼樣子的呢,書上的解釋是這樣的 在結對程式設計模式下,一對程式設計員肩並肩,平等地,互補地進行開發工作。他們併排坐在一台電腦前,面對...