根据demo简单编写一个求解某个函数的最大值的程序,从而理解下算法,会对每个步骤简单分析下。
主程序
clear all
clc
popsize=20; %群体大小
chromlength=10; %字符串长度(个体长度)
pc=0.8; %交叉概率
pm=0.006; %变异概率
pop=initpop(popsize,chromlength); %随机产生初始群体
for i=1:30 %30为迭代次数
[objvalue]=calobjvalue(pop); %计算目标函数
fitvalue=calfitvalue(objvalue); %计算群体中每个个体的适应度
[newpop]=selection(pop,fitvalue); %复制
[newpop]=crossover(pop,pc); %交叉
[newpop]=mutation(pop,pc); %变异
[bestindividual,bestfit]=best(pop,fitvalue); %求出群体中适应值最大的个体及其适应值
y(i)=max(bestfit);
n(i)=i;
pop5=bestindividual;
x(i)=decodechrom(pop5,1,chromlength)*10/1023;
pop=newpop;
end
fplot('11*sin(7*x)-7*cos(3*x)',[0 11])
hold on
plot(x,y,'r*')
hold off
f=max(y)
一、初始化
1.首先执行的是初始化的程序 相当于就是随机初始化了一个以种群数为行数,具体编码个体的列数为主的随机初始化种群。
其中roud主要起的作用是把随机数规范化为0-1,更符合我们使用。
%初始化
function pop=initpop(popsize,chromlength)
pop=round(rand(popsize,chromlength));
% rand随机产生每个单元为{0,1}行数为popsize,列数为chromlength的矩阵,
% roud对矩阵的每个单元进行圆整。这样产生的初始种群。
end
二、进行迭代
1、计算目标函数
function [objvalue]=calobjvalue(pop)
temp1=decodechrom(pop,1,10); %将pop每行转化成十进制数
x=temp1*10/1023; %将二值域 中的数转化为变量域 的数
objvalue=10*sin(5*x)+7*cos(4*x); %计算目标函数值
end
这里要先将二进制编码的数转化为十进制,就是使用普通的二进制的方法进行做的。
%将二进制编码转换成十进制
function pop2=decodechrom(pop,spoint,length)
pop1=pop(:,spoint:spoint+length-1);
pop2=decodebinary(pop1);
end
function pop2=decodebinary(pop)
[px,py]=size(pop);
%求pop行和列数
for i=1:py
pop1(:,i)=2.^(py-i).*pop(:,i);
end
pop2=sum(pop1,2);
%求pop1的每行之和
end
2.根据刚才得到的函数值来计算适应度。
因为是求极大值 将小于0的数的适应度直接置为零,其他的函数值的地方直接当成适应度
%计算个体的适应值
function fitvalue=calfitvalue(objvalue)
global Cmin; %全局变量
Cmin=0;
[px,py]=size(objvalue);
for i=1:px
if objvalue(i)+Cmin>0
temp=Cmin+objvalue(i);
else
temp=0.0;
end
fitvalue(i)=temp;
end
fitvalue=fitvalue'
3.选择复制
首先计算适应度
这得看你的排序选择策略是怎样的。
一种排序是只对当代种群进行排序,这种排序选择方式并不包含精英保留策略的作用。
另一种排序是把上一次种群放一直排序,这种方式包含了精英保留策略的作用。
例如有初始种群包含个体为A1,A2,A3,A4,经过适应度计算后得知最优个体为顺序为A2,A1,A3,A4,经过排序选择后为A2,A2,A1,A3,然后经过交叉和变异后的变为B1,B2,B3,B4,而B1,B2,B3,B4的适应度均没有A2大,那么如果采用第一种排序方式,只对B1-B4排序选择,那么将丢失A2这一优良个体,所以并不包含精英保留作用。如果将B1-B4与A1-A2一起排序,那么由于A2适应度最大,因此必然会选到A2,等效于精英保留策略。
%选择复制
function [newpop]=selection(pop,fitvalue)
totalfit=sum(fitvalue); %求适应值之和
fitvalue=fitvalue/totalfit; %单个个体被选择的概率
fitvalue=cumsum(fitvalue); %如 fitvalue=[1 2 3 4],则 cumsum(fitvalue)=[1 3 6 10]
[px,py]=size(pop);
ms=sort(rand(px,1)); %从小到大排列
fitin=1;
newin=1;
while newin<=px
if(ms(newin))<fitvalue(fitin)
newpop(newin)=pop(fitin);
newin=newin+1;
else
fitin=fitin+1;
end
end
4.交叉
%交叉
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
5.变异
%变异
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 any(newpop(i,mpoint))==0
newpop(i,mpoint)=1;
else
newpop(i,mpoint)=0;
end
else
newpop(i)=pop(i);
end
end
6.求出适应度最大个体。
%求出群体中适应值最大的值
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