【 MATLAB 】遺傳演算法程式
阿新 • • 發佈:2018-12-12
有段時間,一直用為知筆記記筆記,可是後來使用了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