遺傳算法之Matlab實現1:從下載工具箱到實現,極詳細,保證一看就會!!!

本文找了兩個遺傳算法的例子,分別是求一元函數和二元函數的最大值,用MATLAB進行了實現,以下是具體過程:

1)下載遺傳算法需要的工具箱,Genegic Algorithm Toolbox(GA工具箱)。下載方法:在百度中輸入關鍵字“Genegic Algorithm 官網”,然後點擊第二個(Genegic Algorithm Toolbox)網頁進入後,點擊Download即下載完畢,下載後的文件後面有。

(2)批量修改GA工具箱的文件後綴名。由於下載的GA工具箱文件後綴都爲.M,會導致後面用不了裏面的函數,所以需要修改文件後綴爲.m。修改方法:

把一個文件格式轉化爲另外一種格式普遍方法爲:在文件列表中新建一個txt文檔,在裏面輸入ren *.(原文件後綴)  *.(將要改的後綴),然後把txt改爲bat即可。在這裏要將M文件改爲m文件,需要先以jpg爲鋪墊,先把M改爲jpg,再將jpg修改爲m。具體方法如下:先新建一個txt文檔。在裏面輸入ren *.M *.jpg,然後點擊保存後修改該txt後綴爲bat,點確定可以看到M文件全變爲jpg文件。再新建一個txt文件,輸入ren *.jpg *.m,然後點擊保存後修改該txt後綴爲bat,點確定可以看到jpg文件全變爲m文件。

(3)添加工具箱到matlab中。先把工具箱文件夾gatbx複製到matlab安裝路徑下的toolbox文件夾中(也可以省略此步找到路徑直接添加也可),然後在MATLAB中點擊File-Set path-Add with Subfolders,找到gatbx文件夾的路徑-save即可。

(4)檢驗工具箱添加是否成功。在MATLAB命令行輸入help reins(可隨意輸入GA工具箱中任意的一個函數檢驗),出現該函數的用法說明等則表示添加成功,若沒有添加成功會提示not found。,

(5)遺傳算法一元函數MATLAB實現。

實例:用遺傳算法求函數f(x)=x*cos(5*pi*x)+3.5在區間[-1,2.5]上的最大值。(注:pi表示π)

先在工作區建立上面函數的一個m文件輸入以下代碼並保存,保存M文件時默認爲函數名命名,所以不需要修改文件名,同時注意M文件的保存路徑要與當前的工作空間保持一致,不然在運行命令文件時會找不到該函數,導致出錯。

function y=fun_sigv(x)
    y=x.*cos(5*pi*x)+3.5;

然後在命令行輸入以下代碼運行即可:

opt_minmax=1;   %目標優化類型:1最大化、0最小化
num_ppu=50;     %種羣規模即個體個數  初始種羣的大小一般是20-100,這裏選擇的是50個
num_gen=60;     %最大遺傳代數
len_ch=20;          %基因長度
gap=0.9;            %代溝(Generation gap)  代溝是父代中需要經過選擇、交叉、變異得到下一代的比例,例如父代有100個個體,代溝爲0.9表示有90個個體被選中進行上述一系列操作進化到下一代,剩下10%個不變直接進入下一代,即下一代還是100個個體
sub=-1;         %變量取值下限
up=2.5;         %變量取值上限 由題目中變量的取值區間可以知道
cd_gray=1;      %是否選擇格雷碼編碼方式:1是、0否  格雷碼屬於可靠性編碼,是一種錯誤最小化的編碼方式,它相比自然二進制碼減少了出錯的可能性。
sc_log=0;       %是否選擇對數標度:1是、0否  對數標度座標x-logy 算數標度座標x-y 增長方式不同,一個均勻增長,一個對數增長
trace=zeros(num_gen,2);     %遺傳迭代性能跟蹤器   trace是代數*2的二維矩陣,存儲各子代種羣的最優解和各子代種羣的平均值
fieldd=[len_ch;sub;up;1-cd_gray;sc_log;1;1];    %區域描述器  有的書中叫譯碼矩陣,矩陣第一行表示每一個個體的染色體的基因數目,最後兩行分別表示包不包含上下邊界,0不包含,1包含。fieldd是區域描述器,有的書中也叫譯碼矩陣。其結構爲
  FieldD=[len,lb,ub,code,scale,lbin,ubin]';('代表轉置,也就是FieldD是列向量)
  len是每個chrom的長度,lb和ub是行向量,分別指明每個變量使用的下界和上界。 code是二進制行向量,code(i)=1爲標準二進制編碼,code(i)=0爲格雷碼。
  scale是二進制行向量,指明每個子串是否使用對數或算數刻度。0爲算數刻度,1爲對數刻度。
  lbin和ubin是二進制行向量,指明表示範圍中是否包含每個邊界。選擇lbin=0或ubin=0,從表示範圍中去掉邊界;lbin=0或ubin=1則表示包含邊界。
fieldd在二進制串到實值轉換函數bs2rv中用到:Phen=bs2rv(Chrom,FieldD),即根據譯碼矩陣FieldD將二進制串矩陣Chrom轉換爲實值向量。返回矩陣Phen包含對應的種羣表現型。對於bs2rv函數,如果使用對數刻度,其範圍不能包含零
chrom=crtbp(num_ppu,len_ch);     %初始化生成種羣
k_gen=0;
x=bs2rv(chrom,fieldd);     %翻譯初始化種羣爲10進制 二進制轉化爲十進制
fun_v=fun_sigv(x);          %計算目標函數值
tx=sub:.01:up;              % 約束條件,即變量取值範圍在[-1.2.5]區間內
plot(tx,fun_sigv(tx));   %畫出函數的優化結果的二維圖形
xlabel('x');ylabel('y');   %標出x軸爲自變量x,y軸爲因變量y
title('一元函數優化結果'); %圖形標題
hold on;
while k_gen<num_gen  while循環是當爲非零時執行下面的語句,即一直循環進行到最大遺傳代數爲止
    fit_v=ranking(-opt_minmax*fun_v);           %計算目標函數的適應度
    selchrom=select('rws',chrom,fit_v,gap);     %使用輪盤賭方式選擇
    selchrom=recombin('xovsp',selchrom);     %交叉
    selchrom=mut(selchrom);                         %變異
    x=bs2rv(selchrom,fieldd);                          %子代個體翻譯
    fun_v_sel=fun_sigv(x);         %計算子代個體對應目標函數值 [chrom,fun_v]=reins(chrom,selchrom,1,1,opt_minmax*fun_v,opt_minmax*fun_v_sel);%根據目標函數值將子代個體插入新種羣
    [f,id]=max(fun_v);                                      %尋找當前種羣最優解
    x=bs2rv(chrom,fieldd);                             
    f=f*opt_minmax;
    fun_v=fun_v*opt_minmax;
    k_gen=k_gen+1;
    trace(k_gen,1)=f;
    trace(k_gen,2)=mean(fun_v);
end
plot(x(id),f,'r*');
figure;
plot(trace(:,1),'r-*');
hold on;
plot(trace(:,2),'b-o');
legend('各子代種羣最優解','各子代種羣平均值');
xlabel('迭代次數');ylabel('目標函數優化過程');
title('一元函數優化過程');

上面的代碼註釋有的是我自己的解釋,如果有錯歡迎指正。直接可以運行無錯的代碼如下:

opt_minmax=1;   %目標優化類型:1最大化、0最小化
num_ppu=50;     %種羣規模即個體個數 
num_gen=60;     %最大遺傳代數
len_ch=20;          %基因長度
gap=0.9;            %代溝(Generation gap)  
sub=-1;         %變量取值下限
up=2.5;         %變量取值上限 
cd_gray=1;      %是否選擇格雷碼編碼方式:1是、0否 
sc_log=0;       %是否選擇對數標度:1是、0否  
trace=zeros(num_gen,2);     %遺傳迭代性能跟蹤器   
fieldd=[len_ch;sub;up;1-cd_gray;sc_log;1;1];    %區域描述器  
chrom=crtbp(num_ppu,len_ch);     %初始化生成種羣
k_gen=0;
x=bs2rv(chrom,fieldd);     %翻譯初始化種羣爲10進制
fun_v=fun_sigv(x);          %計算目標函數值
tx=sub:.01:up;               
plot(tx,fun_sigv(tx));
xlabel('x');ylabel('y');
title('一元函數優化結果');
hold on;
while k_gen<num_gen
    fit_v=ranking(-opt_minmax*fun_v);           %計算目標函數的適應度
    selchrom=select('rws',chrom,fit_v,gap);     %使用輪盤賭方式選擇
    selchrom=recombin('xovsp',selchrom);     %交叉
    selchrom=mut(selchrom);                         %變異
    x=bs2rv(selchrom,fieldd);                          %子代個體翻譯
    fun_v_sel=fun_sigv(x);                               %計算子代個體對應目標函數值
    [chrom,fun_v]=reins(chrom,selchrom,1,1,opt_minmax*fun_v,opt_minmax*fun_v_sel);%根據目標函數值將子代個體插入新種羣
    [f,id]=max(fun_v);                                      %尋找當前種羣最優解
    x=bs2rv(chrom,fieldd);                             
    f=f*opt_minmax;
    fun_v=fun_v*opt_minmax;
    k_gen=k_gen+1;
    trace(k_gen,1)=f;
    trace(k_gen,2)=mean(fun_v);
end
plot(x(id),f,'r*');
figure;
plot(trace(:,1),'r-*');
hold on;
plot(trace(:,2),'b-o');
legend('各子代種羣最優解','各子代種羣平均值');
xlabel('迭代次數');ylabel('目標函數優化過程');
title('一元函數優化過程');

運行結果圖如下:

從圖一可以看出從[-1,2.5]每個x對應的優化結果y,從而清晰地看出最優值;圖二是用跟蹤器記載了優化的過程,隨着迭代次數的增加,最優值最後趨於一個穩定的值5.9008。

(6)遺傳算法二元函數MATLAB實現。

求解下列二元函數的最大值:

直接在matlab命令行輸入以下代碼:

clc;clear all;
format long;%設定數據顯示格式
%初始化參數
T=10;%仿真代數
N=4;% 羣體規模
pm=0.05;pc=0.8;%交叉變異概率
umax=7;umin=1;%參數取值範圍
L=3;%單個參數字串長度,總編碼長度2L
bval=round(rand(N,2*L));%初始種羣
bestv=-inf;%最優適應度初值
%迭代開始
for ii=1:T
%解碼,計算適應度
for i=1:N
        y1=0;y2=0;
        for j=1:1:L
           y1=y1+bval(i,L-j+1)*2^(j-1);
        end
        x1=(umax-umin)*y1/(2^L-1)+umin;
        for j=1:1:L
           y2=y2+bval(i,2*L-j+1)*2^(j-1);
        end
        x2=(umax-umin)*y2/(2^L-1)+umin;
obj(i)=x1.^2+x2.^2; %目標函數 
        xx(i,:)=[x1,x2];
    end
func=obj;%目標函數轉換爲適應度函數
p=func./sum(func);
q=cumsum(p);%累加
[fmax,indmax]=max(func);%求當代最佳個體
   if fmax>=bestv
      bestv=fmax;%到目前爲止最優適應度值
      bvalxx=bval(indmax,:);%到目前爲止最佳位串
      optxx=xx(indmax,:);%到目前爲止最優參數
   end   
   Bfit1(ii)=bestv; % 存儲每代的最優適應度
%%%%遺傳操作開始
%輪盤賭選擇
 for i=1:(N-1)
    r=rand;
tmp=find(r<=q);
    newbval(i,:)=bval(tmp(1),:);
 end 
  newbval(N,:)=bvalxx;%最優保留
  bval=newbval;
%單點交叉
for i=1:2:(N-1)
   cc=rand;
   if cc<pc
       point=ceil(rand*(2*L-1));%取得一個1到2L-1的整數
       ch=bval(i,:);
       bval(i,point+1:2*L)=bval(i+1,point+1:2*L);
       bval(i+1,point+1:2*L)=ch(1,point+1:2*L);
    end
end   


bval(N,:)=bvalxx;%最優保留
%位點變異
mm=rand(N,2*L)<pm;%N行,小於變異概率的賦值爲1,其他賦值0
mm(N,:)=zeros(1,2*L);%最後一行不變異,強制賦0
bval(mm)=1-bval(mm); %bval(mm)把mm中賦值爲1的基因提取出來
end
%輸出


plot(Bfit1);% 繪製最優適應度進化曲線
bestv   %輸出最優適應度值
optxx    %輸出最優參數

注意:不是全部複製粘貼,分三步運行上面的空格就是分段處。最終結果如下:

bestv =

    98


optxx =

     7     7

上圖中x軸爲迭代次數,y軸爲最優值。

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章