遺傳算法優化函數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