1. 程式人生 > >遺傳算法實例(Matlab實現)

遺傳算法實例(Matlab實現)

hold on htm true 向量 sga 如何選擇 fig inf pop

遺傳算法優化函數y=10*sin(5*x)+7*abs(x-5)+10,這個函數圖像為:

技術分享圖片

下面看代碼:

(1)首先看主函數

function main()
clear;
clc;
%種群大小
popsize=100;
%二進制編碼長度
chromlength=10;
%交叉概率
pc = 0.6;
%變異概率
pm = 0.001;
%初始種群
pop = initpop(popsize,chromlength);

for i = 1:100
    %計算適應度值(函數值)
    objvalue = cal_objvalue(pop);
    fitvalue = objvalue;
    %選擇操作
    newpop = selection(pop,fitvalue);
    %交叉操作
    newpop = crossover(newpop,pc);
    %變異操作
    newpop = mutation(newpop,pm);
    %更新種群
    pop = newpop;
    %尋找最優解
    [bestindividual,bestfit] = best(pop,fitvalue);
    x2 = binary2decimal(bestindividual);
    x1 = binary2decimal(newpop);
    y1 = cal_objvalue(newpop);
    if mod(i,10) == 0
        figure;
        fplot(‘10*sin(5*x)+7*abs(x-5)+10‘,[0 10]);
        hold on;
        plot(x1,y1,‘*‘);
        title([‘叠代次數為n=‘ num2str(i)]);
        %plot(x1,y1,‘*‘);
    end
end
fprintf(‘The best X is --->>%5.2f\n‘,x2);
fprintf(‘The best Y is --->>%5.2f\n‘,bestfit);

(2)下面看二進制種群生成的方法

%初始化種群大小
%輸入變量:
%popsize:種群大小
%chromlength:染色體長度-->>轉化的二進制長度
%輸出變量:
%pop:種群
function pop=initpop(popsize,chromlength)
pop = round(rand(popsize,chromlength));
%rand(3,4)生成3行4列的0-1之間的隨機數
% rand(3,4)
% 
% ans =
% 
%     0.8147    0.9134    0.2785    0.9649
%     0.9058    0.6324    0.5469    0.1576
%     0.1270    0.0975    0.9575    0.9706
%round就是四舍五入
% round(rand(3,4))=
% 1 1 0 1
% 1 1 1 0
% 0 0 1 1
%所以返回的種群就是每行是一個個體,列數是染色體長度

(3)下面看如何把二進制返回對應的十進制

%二進制轉化成十進制函數
%輸入變量:
%二進制種群
%輸出變量
%十進制數值
function pop2 = binary2decimal(pop)
[px,py]=size(pop);
for i = 1:py
    pop1(:,i) = 2.^(py-i).*pop(:,i);
end
%sum(.,2)對行求和,得到列向量
temp = sum(pop1,2);
pop2 = temp*10/1023;

(4)下面看計算適應度函數:

%計算函數目標值
%輸入變量:二進制數值
%輸出變量:目標函數值
function [objvalue] = cal_objvalue(pop)
x = binary2decimal(pop);
%轉化二進制數為x變量的變化域範圍的數值
objvalue=10*sin(5*x)+7*abs(x-5)+10;

(5)如何選擇新的個體

上面所有個體的函數值都計算出來了,存在objvalue中,此時它是不是也是100組y值啊,恩,那麽對於現有的隨機生成的100組x,怎麽來再選擇100組新的更好的x呢?這裏我們把選擇放在了交叉與變異之間了,都可以,如何選擇,就要構造概率的那個輪盤了,誰的概率大,是不是選擇的個體就會多一些?也就是現在的選擇就是100中100個,最後出現的就夠就是以前的100個中最優的x有一個的話,選擇完後,可能就變成5個這個x了,多余的4個是不是相當於頂替了以前的不好的4個x值,這樣才能達到x總數100不變啊。

%如何選擇新的個體
%輸入變量:pop二進制種群,fitvalue:適應度值
%輸出變量:newpop選擇以後的二進制種群
function [newpop] = selection(pop,fitvalue)
%構造輪盤
[px,py] = size(pop);
totalfit = sum(fitvalue);
p_fitvalue = fitvalue/totalfit;
p_fitvalue = cumsum(p_fitvalue);%概率求和排序
ms = sort(rand(px,1));%從小到大排列
fitin = 1;
newin = 1;
while newin<=px
    if(ms(newin))<p_fitvalue(fitin)
        newpop(newin,:)=pop(fitin,:);
        newin = newin+1;
    else
        fitin=fitin+1;
    end
end    

(6)怎麽交叉

%交叉變換
%輸入變量:pop:二進制的父代種群數,pc:交叉的概率
%輸出變量:newpop:交叉後的種群數
function [newpop] = crossover(pop,pc)
[px,py] = size(pop);
newpop = ones(size(pop));
for i = 1:2:px-1
    if(rand<pc)
        cpoint = round(rand*py);
        newpop(i,:) = [pop(i,1:cpoint),pop(i+1,cpoint+1:py)];
        newpop(i+1,:) = [pop(i+1,1:cpoint),pop(i,cpoint+1:py)];
    else
        newpop(i,:) = pop(i,:);
        newpop(i+1,:) = pop(i+1,:);
    end
end

(7)怎麽變異

%關於編譯
%函數說明
%輸入變量:pop:二進制種群,pm:變異概率
%輸出變量:newpop變異以後的種群
function [newpop] = mutation(pop,pm)
[px,py] = size(pop);
newpop = ones(size(pop));
for i = 1:px
    if(rand<pm)
        mpoint = round(rand*py);
        if mpoint <= 0;
            mpoint = 1;
        end
        newpop(i,:) = pop(i,:);
        if newpop(i,mpoint) == 0
            newpop(i,mpoint) = 1;
        else newpop(i,mpoint) == 1
            newpop(i,mpoint) = 0;
        end
    else newpop(i,:) = pop(i,:);
    end
end  

(8)選擇最優個體

%求最優適應度函數
%輸入變量:pop:種群,fitvalue:種群適應度
%輸出變量:bestindividual:最佳個體,bestfit:最佳適應度值
function [bestindividual bestfit] = best(pop,fitvalue)
[px,py] = size(pop);
bestindividual = pop(1,:);
bestfit = fitvalue(1);
for i = 2:px
    if fitvalue(i)>bestfit
        bestindividual = pop(i,:);
        bestfit = fitvalue(i);
    end
end

到這裏遺傳算法程序就算是結束了。

看部分圖片結果:

技術分享圖片技術分享圖片

交叉

基本遺傳算法(SGA)中交叉算子采用單點交叉算子。

單點交叉運算

技術分享圖片

變異

技術分享圖片

轉:https://www.cnblogs.com/LoganChen/p/7509702.html

遺傳算法實例(Matlab實現)