1. 程式人生 > >遺傳演算法與非線性規劃結合求解函式極值

遺傳演算法與非線性規劃結合求解函式極值

動機

 MATLAB經典非線性規劃演算法大多采用梯度下降的方法進行求解,區域性搜尋能力較強,但容易掉入區域性極值,而遺傳演算法採用選擇、交叉和變異運算元進行搜尋,全域性搜尋能力較強,區域性搜尋能力較弱
 打個比方的話,大概就是遺傳演算法可以看到各個山丘,但它不會去分辨哪個才是最高的,很容易隨便選一個就爬上去了。而梯度下降演算法視野比較窄,但它會在看到的那些裡爬到最高的山上去
如果將二者結合,就很有可能能夠得到問題的全域性最優解

流程

這裡寫圖片描述
 N是個固定的數,先用遺傳演算法進行N次迭代(即先找出那些山丘),等到了N次,再用梯度下降演算法來在這些山丘裡尋求最高的那個

MATLAB程式碼

clc
clear all
close all

%定義自變數的範圍
lbx1=0;ubx1=2.8274; 
lbx2=0;ubx2=2.8274;
lbx3=0;ubx3=2.8274;
lbx4=0;ubx4=2.8274;
lbx5=0;ubx5=2.8274;

%% 定義遺傳演算法引數
NIND=100;        %個體數目
MAXGEN=30;      %最大遺傳代數
PRECI=20;       %變數的二進位制位數
GGAP=0.95;      %代溝
px=0.6;         %交叉概率
pm=0.1;        %變異概率
trace=zeros(MAXGEN,6);                        %尋優結果的初始值
FieldD=[PRECI PRECI PRECI PRECI PRECI;lbx1 lbx2 lbx3 lbx4 lbx5;ubx1 ubx2 ubx3 ubx4 ubx5;1 1 1 1 1;0 0 0 0 0;1 1 1 1 1;1 1 1 1 1]; %區域描述器 Chrom=crtbp(NIND,PRECI*5); %初始種群 %% 優化 gen=0; %代計數器 X=bs2rv(Chrom,FieldD); %計算初始種群的十進位制轉換
X1=X(:,1);X2=X(:,2);X3=X(:,3);X4=X(:,4);X5=X(:,5); ObjV=-5*sin(X1).*sin(X2).*sin(X3).*sin(X4).*sin(X5)-sin(5*X1).*sin(5*X2).*sin(5*X3).*sin(5*X4).*sin(5*X5)+8; %計算目標函式值 while gen<MAXGEN FitnV=ranking(ObjV); %分配適應度值 SelCh=select('sus',Chrom,FitnV,GGAP); %選擇 SelCh=recombin('xovsp',SelCh,px); %重組 SelCh=mut(SelCh,pm); %變異 X=bs2rv(SelCh,FieldD); %子代個體的十進位制轉換 X1=X(:,1);X2=X(:,2);X3=X(:,3);X4=X(:,4);X5=X(:,5); ObjVSel= -5*sin(X1).*sin(X2).*sin(X3).*sin(X4).*sin(X5)-sin(5*X1).*sin(5*X2).*sin(5*X3).*sin(5*X4).*sin(5*X5)+8; %計運算元代的目標函式值 [Chrom,ObjV]=reins(Chrom,SelCh,1,1,ObjV,ObjVSel); %重插入子代到父代,得到新種群 X=bs2rv(Chrom,FieldD); X1=X(:,1);X2=X(:,2);X3=X(:,3);X4=X(:,4);X5=X(:,5); gen=gen+1; %代計數器增 if mod(gen,10)==0 for i=1:NIND x=X(i,:); %X_init拿來裝每次起始的自變數值,是個行向量 %X_min=zeros(5,NIND); %X_min拿來記錄每次求出最小值對應的自變數。每列代表一次求出的自變數值們 %Z_min=zeros(NIND,1); %Z_min拿來記錄每次求出的最小值 [X_min(:,i),Z_min(i)]=fmincon(inline('8-5*sin(x(1))*sin(x(2))*sin(x(3))*sin(x(4))*sin(x(5))-sin(5*x(1))*sin(5*x(2))*sin(5*x(3))*sin(5*x(4))*sin(5*x(5))'),x,[],[],[],[],[0 0 0 0 0],[2.8274 2.8274 2.8274 2.8274 2.8274]); end [A,I]=min(Z_min);trace(gen,1)=A;trace(gen,2)=X_min(1,I);trace(gen,3)=X_min(2,I);trace(gen,4)=X_min(3,I);trace(gen,5)=X_min(4,I);trace(gen,6)=X_min(5,I); else [A,I]=min(ObjV);trace(gen,1)=A;trace(gen,2)=X1(I);trace(gen,3)=X2(I);trace(gen,4)=X3(I);trace(gen,5)=X4(I);trace(gen,6)=X5(I); end end %% 畫進化圖 figure(1); plot(1:MAXGEN,trace(:,1)); grid on xlabel('遺傳代數') ylabel('解的變化') title('進化過程') bestZ=trace(1,end); bestX1=trace(2,end); bestX2=trace(3,end); bestX3=trace(4,end); bestX4=trace(5,end); bestX5=trace(6,end); fprintf(['最優解:\nX1=',num2str(bestX1),'\nX2=',num2str(bestX2),'\nX3=',num2str(bestX3),'\nX4=',num2str(bestX4),'\nX5=',num2str(bestX5),'\nZ=',num2str(bestZ),'\n'])

 最後執行出來結果是
這裡寫圖片描述
 發現每次到呼叫非線性規劃來求最優解時就能找到最優值…估計是這個函式比較簡單,可以直接用遺傳演算法來搞的緣故?