在matlab中利用遺傳演算法(GA)求取函式全域性最大值

daylight714發表於2020-10-14

遺傳演算法的簡單實現


今天學習了遺傳演算法,其最大的特點就是能求取全域性最優值,但是演算法隨機性高,對連續定義域很難求得精確解,本文僅參考遺傳演算法的思想,在整數範圍內,來求取函式全域性最大值

首先回顧一下演算法流程
在這裡插入圖片描述
在這裡插入圖片描述
(b)方法在(a)的基礎上,選擇保留一部分父代個體,防止優秀基因的丟失,我在這裡使用的是經典遺傳演算法,在下面這種簡單的二次函式方面效果不錯

clc;
clear;
%設定起始計時器
tic;
%定義群體個數num(設為偶數),定義自變數數n,定義自變數取值範圍[1,top],
num=160;n=4;top=12;
%定義用來儲存目標結果的向量
F_result=zeros(1,num);
%定義種群最大值,平均值
F_max=[];F_mean=[];F_min=[];
%隨機生成num個個體,即生成初始種群
for i=1:num
    for j=1:n
        X{i}(j)=unidrnd(top);
    end
    F_result(i)=f(X{i});     %請先自定義f函式
end
i=1;
%選擇使函式f較大的前一半個體隨機組合,隨機交換基因,產生下一代,直到群體數復原
while(1)
    %取群體最大值,平均值,最小值作為觀察物件
    F_max(i)=max(F_result);F_mean(i)=mean(F_result);F_min(i)=min(F_result);
    if (F_max(i)==F_mean(i))
        break;
    end
    %選擇前一半表現優秀的個體雜交產生下一代
    F_tem=F_result;   %臨時儲存F的結果用於排序
    [result,coo]=sort(F_tem);
    t=unidrnd(num/2); %基因交換迴圈過程中發生變異的某時刻
    for j=1:num/2    %基因交換迴圈過程,子代將完全取代老一代
        a=unidrnd(num/2)+num/2;    %隨機選擇兩個表現優秀的不同個體
        b=unidrnd(num/2)+num/2;
        if(a==b)
            j=j-1;
            continue;
        end
        %選擇與重組
        X{coo(j)}=[X{coo(a)}(1) X{coo(a)}(2) X{coo(b)}(3) X{coo(b)}(4)];
        F_result(coo(j))=f(X{coo(j)});
        X{coo(j+num/2)}=[X{coo(b)}(1) X{coo(b)}(2) X{coo(a)}(3) X{coo(a)}(4)];
        F_result(coo(j+num/2))=f(X{coo(j+num/2)});
        %變異
        if(j==t)
            c=unidrnd(n);    %任選一位變異
            d=unidrnd(top);  %任變異成定義域內某值
            X{coo(j)}(c)=d;
            F_result(coo(j))=f(X{coo(j)});
            X{coo(j+num/2)}(c)=d;
            F_result(coo(j+num/2))=f(X{coo(j+num/2)});
        end
    end
    i=i+1;
end
plot(F_max,'r');
hold on;
plot(F_mean,'g');
hold on;
plot(F_min,'b');
toc;

下面是執行結果
在這裡插入圖片描述

相關文章