基於matlab的遺傳算法簡單實例--淺談精英策略和輪盤賭


首先要了解遺傳算法的一些基本概念:

  • 基因型(genotype):性狀染色體的內部表現;
  • 表現型(phenotype):染色體決定性狀的外部表現,或者說,根據基因型形成的個體;
  • 進化(evolution):逐漸適應生存環境,品質不斷得到改良。生物的進化是以種群的形式進行的。
  • 適應度(fitness):度量某個物種對於生存環境的適應程度。
  • 選擇(selection):以一定的概率從種群中選擇若干個個體。一般,選擇過程是一種基於適應度的優勝劣汰的過程。
  • 復制(reproduction):細胞分裂時,遺傳物質DNA通過復制而轉移到新產生的細胞中,新細胞就繼承了舊細胞的基因。
  • 交叉(crossover):兩個染色體的某一相同位置處DNA被切斷,前后兩串分別交叉組合形成兩個新的染色體。也稱基因重組或雜交;
  • 變異(mutation):復制時可能(很小的概率)產生某些復制差錯,變異產生新的染色體,表現出新的性狀。
  • 編碼(coding):DNA中遺傳信息在一個長鏈上按一定的模式排列。遺傳編碼可看作從表現型到基因型的映射。
  • 解碼(decoding):基因型到表現型的映射。
  • 個體(individual):指染色體帶有特征的實體;是問題的一個解
  • 種群(population):個體的集合,該集合內個體數稱為種群的大小,根據適應函數選擇產生的一組解。

 

遺傳算法的精髓就在於自然選擇。

算法中有三個主要算子,重組、變異、選擇。重組的作用是穩定朝着最優解的方向進化。變異的作用是保證解空間的良好搜索。選擇的作用是適者生存。

選擇的算法有很多,如輪盤選選擇、隨機遍歷選擇、截斷選擇、錦標賽選擇、局部選擇等等

本文對選擇中的輪盤賭和精英策略用一簡單實例來進行對比。

 

從GA的整個選擇策略來講,精英選擇是群體收斂到優化問題最優解的一種基本保障。如果下一代群體的最佳個體適應值小於當前群體最佳個體的適應值,則將當前群體最佳個體或者適應度大於下一代最佳個體適應值的多個個體直接復制到下一代,隨機替代或替代最差的下一代群體中的相應數量的個體。采用這種策略的遺傳算法,一般稱為基於精英選擇模型的遺傳算法

輪盤賭選擇又稱比例選擇算子。基本思想:個體被選中的概率與其適應度函數值成正比。設群體大小為n,個體i的適應度為Fi,則個體i被選中遺傳到下一代群體的概率為:

 

 

設想群體全部個體的適當性分數由一張餅圖來代表。群體中每一染色體指定餅圖中一個小塊。塊的大小與染色體的適應性分數成比例,適應性分數愈高,它在餅圖中對應的小塊所占面積也愈大。為了選取一個染色體,要做的就是旋轉這個輪子,直到輪盤停止時,看指針停止在哪一塊上,就選中與它對應的那個染色體。

 

遺傳算法的基本流程

 

 

 

 

 

 

 

問題:

以y=(x-15)^2,x的范圍是0-31為例,求y的最小值。進行算法編程實驗,選用兩種以上不同的進化/淘汰機制,對遺傳算法的效果進行比較。

 

這里x的范圍0-31,我們剛好把表現型編碼為00000-11111的二進制數。為方便起見,每一代取4個個體,第一代是隨機生成,后面就開始選擇、變異、進化。x取到的值帶入算式再通過適應度函數即可算出選擇所需的適應度。

function Y=genetic     %此函數是初始化加輪盤賭后的結果。
    num =5;gt =4;
    a = unifrnd(0,1,gt,num);aa = zeros(1,gt);
    for i = 1:1:gt
        for j = 1:1:num
            if a(i,j) < 0.5
                a(i,j) = 0;
            else
                a(i,j) =1;
            end
            aa(i) = aa(i) + a(i,j) * 2^(num-j);
        end
    end
    %%   適應度計算
    fitsum =0;
    for i =1:1:gt
        fitsum = 300-(aa(i)-15)^2 +fitsum;
        A1(i) = i;
    end
    for i =1:1:gt
        fits(i) = (300-(aa(i)-15)^2 )/fitsum;
    end
    for i = 1:1:gt
        A1(i) = i;

        if i == 1 
            acc(i) = fits(i);
        else
            acc(i) = fits(i)+acc(i-1);
        end
    end
    %自然選擇列表記錄 list的編號即為輪盤賭的結果
    while 1
        r = rand([4 1]);
        for i = 1:1:gt
            if r(i) <= acc(1) 
                list(i) = 1;
            elseif r(i) <= acc(2) 
                list(i) = 2;
            elseif r(i) <= acc(3) 
                list(i) = 3;
            else r(i) <= acc(4) 
                list(i) = 4;
            end
        end
        if list(1)~=list(2) && list(2)~=list(3) && list(1)~=list(3)
            break
        end          
    end
    A = A1';A(:,2) = aa';A(:,3) = fits';A(:,4) = acc';A(:,5) = list';
Y=A;
end
%%  輪盤賭算法    以4個個體為例
%編碼后進制轉換
%例子為 y = (x-15)^2 的最小值

%% 十進制轉二進制后轉為矩陣形式
function tt=tm(a) 
    s=reshape(str2num((dec2bin (a))'),[],1)';   %可能少了首位的0 這就不能與之交換
    if length(dec2bin(a)) ==1;        %移位處理
        ss = [0,0,0,0,s];
    elseif  length(dec2bin(a)) ==2;
        ss = [0,0,0,s];
    elseif  length(dec2bin(a)) ==3;
        ss = [0,0,s];
    elseif  length(dec2bin(a)) ==4;
        ss = [0,s];
    else
        ss=s;
    end
    tt =ss;
end

這里的適應度函數是

 Fi(x) = (300-(x-15)^2)/sum(F(i))
F(i)是每個x取到值后帶入表達式得到的值,把他們加起來即是sumF(i)

%% 交叉  基本遺傳算法(SGA)中交叉算子采用單點交叉算子
function  cc=gen3(a)
% 開始交叉   011 |00  這樣的模式  手動模式交叉完的結果是cross
cross=a;   c=0;
c = cross(1,4);  cross(1,4) = cross(2,4); cross(2,4)=c;
c = cross(1,5);  cross(1,5) = cross(2,5); cross(2,5)=c;
c = cross(3,4);  cross(3,4) = cross(4,4); cross(4,4)=c;
c = cross(3,5);  cross(3,5) = cross(4,5); cross(4,5)=c;
    for i = 1:1:4
        for j = 1:1:5
           b =rand(1);
           vary = 0.01;
           if  b<vary
               if cross(i,j) ==0
                   cross(i,j) =1;
               else
                   cross(i,j) =0;
               end
%               disp("有變異")
           end    
        end
    end
cc =cross;
end
%  此函數完成的是交叉、變異的過程
%重新評價適應度
function hello=gen2(a)
    num =5;gt =4;
    fitsum =0;
    aa = zeros(1,gt);
    for i = 1:1:gt
        for j = 1:1:num
            if a(i,j) < 0.5
                a(i,j) = 0;
            else
                a(i,j) =1;
            end
            aa(i) = aa(i) + a(i,j) * 2^(num-j);
        end
    end
    for i =1:1:gt
        fitsum = 300-(aa(i)-15)^2 +fitsum;
        A1(i) = i;
    end
    for i =1:1:gt
        fits(i) = (300-(aa(i)-15)^2 )/fitsum;
    end
    for i = 1:1:gt
        A1(i) = i;
        if i == 1 
            acc(i) = fits(i);
        else
            acc(i) = fits(i)+acc(i-1);
        end
    end
    %自然選擇列表記錄 list的編號即為輪盤賭的結果
    r = rand([4 1]);
    for i = 1:1:gt
        if r(i) <= acc(1) 
            list(i) = 1
        elseif r(i) <= acc(2) 
            list(i) = 2
        elseif r(i) <= acc(3) 
            list(i) = 3
        else r(i) <= acc(4) 
            list(i) = 4
        end
    end
    A = A1';A(:,2) = aa';A(:,3) = fits';A(:,4) = acc';A(:,5) = list';
    hello =A;
end

輪盤賭

clc
clear
%% 本文用迭代次數來評價選擇策略的優劣程度
%  迭代的越少就達到目標值就說明策略較優
%輪盤賭選3個 怎么選 怎么淘汰
%淘汰后補位   一輪選擇后    
A =genetic;
num =5;gt =4;log=0;n=1;
while 1
    k1=A(1,5);k2=A(2,5);k3=A(3,5);
    a1 =A(k1,2);a2 =A(k2,2);a3 =A(k3,2);  %輪盤賭過程
    a4 = unifrnd(0,1,1,5);
    a5=0;
     for j = 1:1:5
            if a4(j) < 0.5
                a4(j) = 0;
            else
                a4(j) =1;
            end
        a5 = a5 + a4(j) * 2^(5-j);
     end
    b =[a1,a2,a3,a5];
    
     fitsum =0;
    for i =1:1:gt
        fitsum = 300-(b(i)-15)^2 +fitsum;
        A1(i) = i;
    end
    for i =1:1:gt
        fits(i) = (300-(b(i)-15)^2 )/fitsum;
        A1(i) = i;
    end
     B = A1';B(:,2) = b';B(:,3) = fits'; %B為選擇后的列表
    %% 十進制轉二進制后轉為矩陣形式
    for i=1:1:4
        C(i,:)=tm(b(i));
    end
    CC=gen3(C);       %交叉、變異完成后的CC矩陣
    %%
    A=gen2(CC);       %已重新評價適應度並輪盤選  此A非彼A
    n = n+1;       %n為迭代次數   
    for i =1:1:4
        if A(i,2) ==15
            log =1;
            break;
        else
            log =0;
        end
     end
     if log == 1
         break
     end
end   
n

% 第1次輪盤賭結果是迭代了11次達到最優解
% 第2次輪盤賭結果是迭代了15次達到最優解
% 第3次輪盤賭結果是迭代了4次達到最優解
% 第4次輪盤賭結果是迭代了6次達到最優解
% 第5次輪盤賭結果是迭代了9次達到最優解

精英策略

%% 精英策略
function  Y=elite
    A=genetic;   %初始化
    for i=1:1:4
        C(i,:)=tm(A(i,2));
    end
    BB =gen3(C);    %交叉+選擇
    B=gen2(BB);    %再評價
    A1 =A(:,2:3);  %一代
    B1 =B(:,2:3);   %二代
    B2 =B(:,2:3);
    A2=[];
    for i =1:1:4
        if A1(i,2) > max(B1(:,2))
            A2(1,:) =A1(i,:);
            break
        end
    end
    t =1;
    for i=1:1:4   
        if min(B1(:,2)) == B1(i,2)
            break;
        else
            t =t+1;
        end
    end  
    if  isempty(A2)
        disp('無精英')
    else
        B2(t,:) =A2;
    end
    %B2是精英選擇后的結果
    Y =B2;
end



%%
n=1;log=0;
while 1
    R =elite_1;     
    for i =1:1:4
        if R(i,1) ==15
            log =1;
            break;
        else
            log =0;
        end
     end
     if log == 1
         break
     end
     n = n+1;       %n為迭代次數 
end
n
% 第1次精英策略結果是迭代了6次達到最優解
% 第2次精英策略結果是迭代了3次達到最優解
% 第3次精英策略結果是迭代了2次達到最優解
% 第4次精英策略結果是迭代了3次達到最優解
% 第5次精英策略結果是迭代了4次達到最優解

 

由上結果觀察知:本例子中選擇的策略為精英策略會比輪盤賭策略的收斂性更好。

 

 

第一次寫,如有出錯,歡迎大佬們指教批評。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM