遺傳算法-matlab

遺傳算法

記錄學習matlab的過程防止忘記。本文參考《智能優化算法及其matlab實例第二版》

遺傳算法簡介

遺傳算法利用羣體搜索技術,將種羣代表一組問題解,對種羣進行選擇,交叉,變異,複製等生物學上的進化操作產生新一代的種羣。

  1. 羣體 :可行解集(一開始羣體是隨機生成的,然後通過自然選擇,優勝略汰);
  2. 個體:可行解(組成羣體的單個生物體);
  3. 染色體 :可行解的編碼(包含生物體信息的遺傳物質);
  4. 基因:可行解編碼的分量(控制生物體的遺傳信息的基本單位) ;
  5. 適應度:可行解在具體問題中跟最優解的差值(個體對當前環境的適應能力)
羣體
個體
染色體
基因
二進制編碼
實數編碼

舉個例子
我們創建一個數值在0~10的3行5列的矩陣

randi([0,10],3,5);

結果爲

ans = 
	7     4     7     0     7
	8     7     0     1     3
	8     1     3     9    10

通常用一列作爲一個個體即這個矩陣代表了5了個體
每一列中的三個實數編碼代表了每個個體的遺傳物質
比如說第一個個體的遺傳信息是 7 8 8

遺傳算法怎麼解決問題

我覺得一個難點就是怎麼把解轉換爲編碼的個體,上面介紹過常用的編碼方式有二進制編碼跟實數編碼,那麼怎麼編

二進制編碼

如果最優解是一個實數的話,像找函數的極大值極小值這些,就可以用到二進制編碼,一列二進制編碼代表的一個解就代表了一個實數。

實數編碼

如果最優解是多個實數的話,像在一組數據中找出最合適的幾個,就可以用實數編碼。

遺傳算法流程

1.初始化:設定最大進化次數,隨機生成一個種羣(一個矩陣,維數看實際問題)。
2.個體評價:計算種羣中每個個體的適應度。
3.進化運算:對種羣進行選擇運算,交叉運算,變異運算。
4.終止條件判斷:如果進化次數大於最大進化次數則終止。

Created with Raphaël 2.2.0開始創建初始種羣適應度計算到達最大進化次數?輸入最優個體結束選擇、變異、交叉等操作yesno

遺傳算法中關鍵參數

1.羣體規模NP:NP太小時優化性能不太好,NP太大計算複雜度高。一般NP取10-200.
2.交叉概率Pc:Pc太小時可能會使遺傳算法太過於遲鈍,Pc較大時雖然可以擴大搜索區域,但穩定性不高。Pc一般取0.25-1.00
3.變異概率Pm:Pm在算法中起了一種輔助作用,不可以太高,太高會讓算法變成隨機的搜索。一般取0.001-0.1.
4.算法進化次數:一般100-1000之間。問題不大,能算不了就好。

簡單的實例

用標準遺傳算法求函數 f(x) = x+10sin(5x)+7cos(4x)的最大值

%遺傳算法
clear ;
funcl =@(x) x+10*sin(5*x)+7*cos(4*x);

NP = 50; %種羣數量
L = 20 ; %二進制編碼長度
Pc = 0.8; %交叉率
Pm = 0.1 ;%變異率
G = 100 ;%最大迭代次數
Xs = 10; % X取值的上下限
Xx = 0;
f = randi([0,1],NP,L); %隨機獲得初始種羣

fit =zeros(1,50);
x = zeros(1,50);
trace = zeros(1,100);
xtrace = zeros(1,100);   %預先分配內存

for k  = 1:G    
    for i = 1:NP
        U = f(i,:);
        m = 0;
        for j = 1:L
            m = U(j)*2^(j-1)+m;
        end
        x(i) = Xx +m*(Xs - Xx)/ (2^L-1);  %把二進制編碼變成實數
        fit(i) = funcl(x(i));       %計算適應度
    end
     
    maxfit = max(fit);
    minfit = min(fit);
    rr = find(fit == maxfit);
    fbest = f(rr(1,1),:);
    xbest = x(rr(1,1));    %歷代最優個體
    fit = (fit - minfit )/(maxfit-minfit); %歸一化適應度
    
    %複製操作
    sum_fit = sum(fit);
    fitvalue = fit./sum_fit;
    fitvalue = cumsum(fitvalue);
    ms = sort(rand(NP,1));
    fiti = 1;
    newi = 1;
    while newi <= NP
        if (ms(newi))<=fitvalue(fiti)
            nf(newi,:) = f(fiti,:);
            newi = newi +1;
        else
            fiti = fiti+1;
        end
    end
    
    %交叉操作
    for i = 1:2:NP
        p = rand;
        if p < Pc
            q = randi(1,L);
            for j = 1:L
                if q(j) == 1
                    temp = nf(i+1,j);
                    nf(i+1,j) = nf(i,j);
                    nf(i,j) = temp;
                end
            end
        end
    end
    
    %變異操作
    i = 1;
    while i <= round(NP*Pm)
        h =randi([1,NP],1,1);
        for j = 1:round(L*Pm)
            g = randi([1,L],1,1);
            nf(h,g) =~nf(h,g);
        end
        i = i+1;
    end
    
    f = nf;
    f(1,:) = fbest;
    trace(k) = maxfit;
    xtrace(k) =xbest;
end
figure;
subplot(3,1,1);
plot(trace);
xlabel('迭代次數');
ylabel('進化曲線');
title("適應度進化曲線");
hold on;
subplot(3,1,2);
plot(xtrace);
xlabel('迭代次數');
ylabel('進化曲線');
title("適應度進化曲線");
subplot(3,1,3);
fplot(funcl,[0,10]);
xlabel('x');
ylabel('y');
title("函數曲線");

代碼運行結果
在這裏插入圖片描述

可以看到算法收斂得很快。

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