1. 程式人生 > >【 MATLAB 】遺傳演算法程式

【 MATLAB 】遺傳演算法程式

有段時間,一直用為知筆記記筆記,可是後來使用了csdn部落格後,就不太喜歡用為知筆記了,可惜了我的會員。筆記裡的一些東西,例如公式什麼的,都不能直接複製過來,很是遺憾。

準備棄用為知筆記了,把這個遺傳演算法的程式粘過來吧,即使對我可能沒什麼用了,但也可能有需要用的人。

程式很詳細,當時上課的時候就是用這個程式編的一篇小報告。程式很詳細。

function main()
%% -------------主函式-----------------------------------
%                用遺傳演算法求:
%   max: f(x1,x2) = 21.5+x1*sin(4*pi*x1)+x2*sin(20*pi*x2) 
%        s.t: -3.0 <= x1 <= 12.1
%              4.1 <= x2 <= 5.8
%---------------------------------------------------------------
clear
clc
close all
popsize = 100;     %種群大小
x1_length = 18;   %x1長度為18
x2_length = 15;   %x2長度為15
chromlength = 33;  %二進位制編碼長度
pc = 0.25;          %交叉概率
pm = 0.01;        %變異概率
pop = initpop(popsize,chromlength);   %初始種群
for i = 1:1000 % 迭代1000次
    [objvalue] = cal_objvalue(pop);%計算計算函式值
    fitvalue = objvalue; %令適應度等於函式值
    [newpop] = selection(pop,fitvalue);  %選擇操作
    [newpop] = crossover(newpop,pc);     %交叉操作
    [newpop] = mutation(newpop,pm);      %變異操作
    pop = newpop;                %更新種群
    % 將種群的每個個體表示出來
    [A B] = binary2decimal(newpop);
    [y] = cal_objvalue(newpop);  
    figure(1);
    set(1, 'unit', 'normalized', 'position', [0.1,0.1,0.7,0.7]);
    if  i<=100&mod(i,10)==0  %每迭代10次做一次圖,畫100次以內的圖
        j = floor(i/10);
        %畫3d圖
        X = -3.0:0.1:12.1;
        Y = 4.1:0.1:5.8;
        subplot(2,5,j);
        [X, Y] = meshgrid(X,Y);
        Z = 21.5 + X.*sin(4*pi*X) + Y.*sin(20*pi*Y);
        mesh(X,Y,Z);
        hold on;
        title(['迭代次數為 n=' num2str(i)]);
        plot3(A,B,y,'*');
    end
    [bestindividual,bestfit]=best(pop,fitvalue);%尋找最優解
    [x1 x2] = binary2decimal(bestindividual); %將二進位制值轉換為十進位制
    BEST(i) = bestfit;
    X1(i) = x1;
    X2(i) = x2;

end 
  
    [max_value,index] = max(BEST');
    best_x1 = X1(index);
    best_x2 = X2(index);
    figure(2);
    set(2, 'unit', 'normalized', 'position', [0.1,0.1,0.7,0.7]);
    i = 1:1000;
    plot(i,BEST);
    axis([0,1000,0,40]);
    xlabel('進化代數');
    ylabel('函式值');
    text(100,10,'交叉概率pc = 0.6  變異概率pm = 0.01  進化代數1000次');
    text(100,8,['After ',num2str(index),' generations,',...
        '  the max value was got.']);
    text(100,6,[' x1 = ',num2str(best_x1),'      x2= ',num2str(best_x2),...
         '      max value= ', num2str(max_value)]);
    fprintf('After %.0f times iterations, max_value was got.\n',index);
    fprintf('the best x1 is  --->> %5.2f\n',best_x1);
    fprintf('the best x2 is  --->> %5.2f\n',best_x2);
    fprintf('the best y is   --->> %5.2f\n',max_value);
    fprintf('\n');
    fprintf('After %.0f times iterations, final_value was got.\n',1000);
    fprintf('the final x1 is  --->> %5.2f\n',x1);
    fprintf('the final x2 is  --->> %5.2f\n',x2);
    fprintf('the final y is   --->> %5.2f\n',bestfit);


function pop = initpop(popsize,chromlength)
%% -------------初始化種群函式----------------
%    初始化種群大小
%       輸入變數:
%               popsize:種群大小
%               chromlength:染色體長度--》轉化的二進位制長度
%       輸出變數:
%               pop:種群
%---------------------------------------
pop = round(rand(popsize,chromlength));  %隨機產生一個矩陣,每一行是一個長33位染色體;



function [pop1 pop2] = binary2decimal(pop)
%% -----------解碼函式---------------------
%    二進位制轉化為十進位制數
%    輸入變數:
%        二進位制種群
%    輸出變數:
%        十進位制數值
%-----------------------------------------
for i = 1:18
    pop_x1(:,i) = 2.^(18 - i).*pop(:,i);
end
for j = 1:15
    pop_x2(:,j) = 2.^(15 - j).*pop(:,j+18);
end
%sum(.,2)對行求和,得到列向量
temp1 = sum(pop_x1,2);
temp2 = sum(pop_x2,2);
pop1 = -3.0 + temp1*15.1/(2^18-1); %pop1表示輸出x1的十進位制數
pop2 = 4.1 + temp2*1.7/(2^15-1);  %pop2表示輸出的x2的十進位制數



function [objvalue] = cal_objvalue(pop)
%% --------------計算函式值函式----------------------
% 計算函式目標值
%輸入變數:二進位制數值
%輸出變數:目標函式值
%---------------------------------------------
[x1 x2] = binary2decimal(pop);
objvalue = 21.5 + x1.*sin(4*pi*x1) + x2.*sin(20*pi*x2);


function [newpop] = selection(pop,fitvalue)
%% -----------------根據適應度選擇函式-------------------
% 輸入變數 :pop:二進位制種群
%           fitvalue: 適應度
%輸出變數:  newpop: 選擇以後的二進位制種群
% -------------------------------------------
%構造輪盤
[px,py] = size(pop);
totalfit = sum(fitvalue);
p_fitvalue = fitvalue/totalfit;
p_fitvalue = cumsum(p_fitvalue);%概率求和後排序
ms = sort(rand(px,1)); %產生一列隨機數,從小到大排列,相當於轉轉盤10次
fitin = 1;
newin = 1;
while newin <= px
    if(ms(newin)) < p_fitvalue(fitin) % 轉盤轉到 fitin 的位置
        newpop(newin,:) = pop(fitin,:); %新種群的第 newin 個體為pop中的第fitin 個體
        newin = newin + 1;
    else
        fitin = fitin +1; %相當於每次都從第一個比較起,依次加1,直至比較完,看轉到的是哪一個
    end
end


function [newpop] = crossover(pop,pc)
%% ----------交叉函式--------------------
% 輸入變數:pop:二進位制的父代種群數
%          pc :交叉概率
% 輸出變數:newpop: 交叉後的種群數
%---------------------------------------
[px,py] = size(pop);
newpop = ones(size(pop));
for i = 1:2:px-1  % 1與2交叉。3與4交叉。。。。。每次隔一個,因此步子為2
    if (rand<pc)  % pc = 0.6,即有60%的機會交叉
        cpoint = round(rand*py); %交叉點隨機選取,互換交叉點以後的值
        if cpoint <= 0
          % cpoint = 1;
          continue;
        end
        newpop(i,:) = [pop(i,1:cpoint),pop(i+1,cpoint+1:py)];%交叉後的第i個個體
        newpop(i+1,:) = [pop(i+1,1:cpoint),pop(i,cpoint+1:py)];
    else  % 40%的機會不交叉
        newpop(i,:) = pop(i,:);
        newpop(i+1,:) = pop(i+1,:);
    end
end


function [newpop] = mutation(pop,pm)
%% ------------變異函式---------------------------
% 輸入變數 pop: 二進位制種群
%          pm : 變異概率
% 輸出變數: newpop : 變異以後的種群
%-----------------------------------------------
[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) = 0;
        end
    else
        newpop(i,:) = pop(i,:);
    end
end



function [bestindividual,bestfit] = best(pop,fitvalue)
%% --------------選出最優個體函式-----------------------
% 輸入變數: pop :種群
%           fitvalue : 種群適應度
% 輸出變數: bestindividual : 最佳個體(二進位制)
% bestfit : 最佳適應度值
% ---------------------------------------------
[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