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