天天看點

遺傳算法求解香蕉函數的極大值

利用遺傳算法求Rosenbrock(香蕉函數)函數的極大值。其中香蕉函數表達式如下:

遺傳算法求解香蕉函數的極大值

遺傳算法是利用孟德爾的生物遺傳學和達爾文的進化論思想的一種智能計算方法。我覺着與其稱之為一種算法,倒不如稱之為是一種思想。

達爾文的進化論主要有以下三個基本方面:

(1)、遺傳。親代把生物資訊交給子代,子代總是和親代具有相同或相似的屬性。生物有了這個特征,物種才能穩定存在。

(2)、變異。親代和子代之間以及子代的不同個體之間的差異。變異的選擇和積累是生命多樣性的根源。

(3)、生存鬥争和适者生存。适應性強的個體會被儲存下來,并會獲得更多的繁殖機會,适應性差的會被逐漸淘汰。而擁有有利變異者的适應性會更強。

遺傳算法就是将這些基本原理引入到優化參數形成的編碼串群體中,按照所選的适應度函數并通過遺傳中的複制、交叉、變異以及對變異個體進行篩選,适應度高的個體會被保留下來,适應度低的個體會被淘汰,由此組成新的種群。不斷疊代,群體中的個體适應度就會不斷提高,直到滿足我們預先設定的一定條件。遺傳算法的基本思想還是比較簡單的,可以進行并行處理,并能夠達到全局最優。但是這畢竟隻是一種經驗思想,還是缺乏嚴格的數學推導。

遺傳算法的基本操作為:

(1)複制

從一個舊種群中選擇生命力強的個體位串産生新種群。具有高适應度的位串更有可能在下一代中産生一個或多個子孫。複制操作可以通過随機方法來實作。首先産生0~1之間的均勻分布的随機數,若某串的複制機率為40%,則當産生的随機數在0.40~1.0之間時,該串被複制,否則被淘汰。

(2)交叉

複制操作能夠從舊種群中選擇出優秀者,但不能創造新的染色體。而交叉模拟了生物進化過程中的繁殖現象,通過兩個染色體的交換組合,來産生新的優良品種。

交叉的過程為:在比對池任選兩個染色體,随機選擇一點或多點交換點位置;交換雙親染色體交換點右邊的部分,即可得到兩個新的染色體數字串。

交叉展現了自然界中資訊交換的思想。交叉有單點交叉、兩點交叉、還有一緻交叉、順序交叉和周期交叉。單點交叉是最基本的方法,應用較廣,它是指染色體切斷點隻有一處。如下例所示

遺傳算法求解香蕉函數的極大值

(3)變異

用來模拟生物在自然的遺傳環境中由于各種偶然因素引起的基因突變,它以很小的機率随機地改變遺傳基因(表示染色體符号串的某一位)的值。在染色體以二進制編碼的系統中,它随機地将染色體在某一基因由1變0,或由0變1 。

用遺傳算法求解上面香蕉函數的MATLAB代碼實作如下所示

clc,clear
 Size=500;
 CodeL=2;
 
 MinX(1)=-2.048;
 MaxX(1)=2.048;
 MinX(2)=-2.048;
 MaxX(2)=2.048;
 
 E(:,1)=MinX(1)+(MaxX(1)-MinX(1))*rand(Size,1);
 E(:,2)=MinX(2)+(MaxX(2)-MinX(2))*rand(Size,1);
 
 G=200;
 BsJ=0;
 
 %---------------Start Running--------------------------------------------%
 for kg=1:G
     time(kg)=kg;
     
     %----------------------step 1: Evaluate BestJ-----------------------%
     for i=1:Size;
         xi=E(i,:);
         x1=xi(1);
         x2=xi(2);
         
         F(i)=100*(x1^2-x2)^2+(1-x1)^2;
         Ji=1./F;
         BsJi(i)=min(Ji);
     end
     [OderJi,IndexJi]=sort(BsJi);
     BestJ(kg)=OderJi(1);
     BJ=BestJ(kg);
     Ji=BsJi+eps;
     
     fi=F;
     [Oderfi,Indexfi]=sort(fi); 
     Bestfi=Oderfi(Size);       
     BestS=E(Indexfi(Size),:);  
     bfi(kg)=Bestfi;
     
     kg
     BestS
     %---------------------------Step 2:Select and Reproduct
     %Operation---------%
     fi_sum=sum(fi);
     fi_Size=(Oderfi/fi_sum)*Size;
     
     fi_S=floor(fi_Size);                   
     r=Size-sum(fi_S);
     
     Rest=fi_Size-fi_S;
     [RestValue,Index]=sort(Rest);
     
     for i=Size:-1:Size-r+1;
         fi_S(Index(i))=fi_S(Index(i))+1;
     end
     
     k=1;
     for i=Size:-1:1;
         for j=1:fi_S(i);
             TempE(k,:)=E(Indexfi(i),:);     
             k=k+1;                           
         end
     end
     %---------------------Step 3: Crossover Operation-------------------%
     Pc=0.90;
     for i=1:2:Size-1;
         temp=rand;
         if Pc>temp
             alfa=rand;
             TempE(i,:)=alfa*E(i+1,:)+(1-alfa)*E(i,:);
             TempE(i+1,:)=alfa*E(i,:)+(1-alfa)*E(i+1,:);
         end
     end
     TempE(Size,:)=BestS;
     E=TempE;
     
     %---------------------Step 4: Mutation Operation--------------------%
     Pm=0.10-[1:Size]*(0.01)/Size;         
     Pm_rand=rand(Size,CodeL);
     Mean=(MaxX+MinX)/2;
     Dif=MaxX-MinX;
     
     for i=1:Size;
         for j=1:CodeL;
             if Pm(i)>Pm_rand(i,j);
                 TempE(i,j)=Mean(j)+Dif(j)*(rand-0.5);
             end
         end
     end
     
     TempE(Size,:)=BestS;
     E=TempE;
 end
 BestS
 Bestfi
 figure(1);
 plot(time,BestJ,'k');
 xlabel('Times');ylabel('Best J');
 
 figure(2);
 plot(time,bfi,'k');
 xlabel('Times');ylabel('Best F');
           

運作結果如下

遺傳算法求解香蕉函數的極大值
遺傳算法求解香蕉函數的極大值

由此可得

遺傳算法求解香蕉函數的極大值

繼續閱讀