实验目的:
编程实现课本例4.1,理解遗传算法
实验平台:
平台:笔记本电脑。
软件:MATLAB2010
实验内容:
M文件如下:
%遗传算法````````````````````````````````````````````````````````````````````````
%设群体规模为5,交配概率为0.88,变异概率0.1
%初始化
%迭代次数:N
N=10000;
k=1;
fk=zeros(1,N);
c=unifrnd (-5, 5, 5, 4);
%适应值评估
Ec1=1/(c(1,1)^2+c(1,2)^2+c(1,3)^2+c(1,4)^2+1);
Ec2=1/(c(2,1)^2+c(2,2)^2+c(2,3)^2+c(2,4)^2+1);
Ec3=1/(c(3,1)^2+c(3,2)^2+c(3,3)^2+c(3,4)^2+1);
Ec4=1/(c(4,1)^2+c(4,2)^2+c(4,3)^2+c(4,4)^2+1);
Ec5=1/(c(5,1)^2+c(5,2)^2+c(5,3)^2+c(5,4)^2+1);
E=[Ec1 Ec2 Ec3 Ec4 Ec5];
for i=1:N
%选择
x=Ec1+Ec2+Ec3+Ec4+Ec5;
pe=[Ec1/x Ec2/x Ec3/x Ec4/x Ec5/x];
%五次轮盘赌
pp=[1 2 3 4 5];
j=0;
for i=1:5
j=j+1;
m=0;
r=rand;
for i=1:5
m=m+pe(i);
if r<=m
pp(j)=i;
break
end
end
end
%更新种群
c=[c(pp(1),:);c(pp(2),:);c(pp(3),:);c(pp(4),:);c(pp(5),:)];
%判断交配
a=[0 0 0 0 0];
p=unifrnd (0, 1, 1, 5);
if p(1)<0.88
a(1)=1;
end
if p(2)<0.88
a(2)=1;
end
if p(3)<0.88
a(3)=1;
end
if p(4)<0.88
a(4)=1;
end
if p(5)<0.88
a(5)=1;
end
%交配
%随机生成1-3之间的自然数作为交配位
n=randint(1,5,[1 3]);
if(a==[1 1 0 0 0]|a==[1 0 1 0 0]|a==[1 0 0 1 0]|a==[1 0 0 0 1]|a==[0 1 1 0 0]|a==[0 1 0 1 0]|a==[0 1 0 0 1]|a==[0 0 1 1 0]|a==[0 0 1 0 1]|a==[0 0 0 1 1])
if(a==[1 0 1 0 0])
t=c(2,:);
c(2,:)=c(3,:);
c(3,:)=t;
end
if(a==[1 0 0 1 0])
t=c(2,:);
c(2,:)=c(4,:);
c(4,:)=t;
end
if(a==[1 0 0 0 1])
t=c(2,:);
c(2,:)=c(5,:);
c(5,:)=t;
end
if(a==[0 1 1 0 0])
t=c(1,:);
c(1,:)=c(3,:);
c(3,:)=t;
end
if(a==[0 1 0 0 1])
t=c(1,:);
c(1,:)=c(5,:);
c(5,:)=t;
end
if(a==[0 0 1 1 0])
t=c(1,:);
c(1,:)=c(3,:);
c(3,:)=t;
t=c(2,:);
c(2,:)=c(4,:);
c(4,:)=t;
end
if(a==[0 0 1 0 1])
t=c(1,:);
c(1,:)=c(3,:);
c(3,:)=t;
t=c(2,:);
c(2,:)=c(5,:);
c(5,:)=t;
end
if(a==[0 0 0 1 1])
t=c(1,:);
c(1,:)=c(4,:);
c(4,:)=t;
t=c(2,:);
c(2,:)=c(5,:);
c(5,:)=t;
end
%两个染色体两两交配
%第1,2条染色体交配
if(n(1)==1)
t=c(1,1);
c(1,1)=c(2,1);
c(2,1)=t;
end
if(n(1)==2)
t=c(1,3);
c(1,3)=c(2,3);
c(2,3)=t;
t=c(1,4);
c(1,4)=c(2,4);
c(2,4)=t;
end
if(n(1)==3)
t=c(1,4);
c(1,4)=c(2,4);
c(2,4)=t;
end
end
%三个染色体两两交配
if(a==[0 0 1 1 1]|a==[0 1 0 1 1]|a==[0 1 1 0 1]|a==[0 1 1 1 0]|a==[1 0 0 1 1]|a==[1 0 1 0 1]|a==[1 0 1 1 0]|a==[1 1 0 0 1]|a==[1 1 0 1 0]|a==[1 1 1 0 0])
%将三条染色体排在前三位
if(a==[0 0 1 1 1])
t=c(1,:);
c(1,:)=c(4,:);
c(4,:)=t;
t=c(2,:);
c(2,:)=c(5,:);
c(5,:)=t;
end
if(a==[0 1 0 1 1])
t=c(1,:);
c(1,:)=c(4,:);
c(4,:)=t;
t=c(3,:);
c(3,:)=c(5,:);
c(5,:)=t;
end
if(a==[0 1 1 0 1])
t=c(1,:);
c(1,:)=c(5,:);
c(5,:)=t;
end
if(a==[0 1 1 1 0])
t=c(1,:);
c(1,:)=c(4,:);
c(4,:)=t;
end
if(a==[1 0 0 1 1])
t=c(2,:);
c(2,:)=c(4,:);
c(4,:)=t;
t=c(3,:);
c(3,:)=c(5,:);
c(5,:)=t;
end
if(a==[1 0 1 0 1])
t=c(2,:);
c(2,:)=c(5,:);
c(5,:)=t;
end
if(a==[1 0 1 1 0])
t=c(2,:);
c(2,:)=c(4,:);
c(4,:)=t;
end
if(a==[1 1 0 0 1])
t=c(3,:);
c(3,:)=c(5,:);
c(5,:)=t;
end
if(a==[1 1 0 1 0])
t=c(3,:);
c(3,:)=c(4,:);
c(4,:)=t;
end
%第1,2条交配
if(n(1)==1)
t=c(1,1);
c(1,1)=c(2,1);
c(2,1)=t;
end
if(n(1)==2)
t=c(1,3);
c(1,3)=c(2,3);
c(2,3)=t;
t=c(1,4);
c(1,4)=c(2,4);
c(2,4)=t;
end
if(n(1)==3)
t=c(1,4);
c(1,4)=c(2,4);
c(2,4)=t;
end
%第1,3条交配
if(n(1)==1)
t=c(1,1);
c(1,1)=c(3,1);
c(3,1)=t;
end
if(n(1)==2)
t=c(1,3);
c(1,3)=c(3,3);
c(3,3)=t;
t=c(1,4);
c(1,4)=c(3,4);
c(3,4)=t;
end
if(n(1)==3)
t=c(1,4);
c(1,4)=c(3,4);
c(3,4)=t;
end
end
%四个染色体两两交配
if(a==[0 1 1 1 1]|a==[1 0 1 1 1]|a==[1 1 0 1 1]|a==[1 1 1 0 1]|a==[1 1 1 1 0])
%将四条染色体按顺序排列
if(a==[0 1 1 1 1])
t=c(1,:);
c(1,:)=c(5,:);
c(5,:)=t;
end
if(a==[1 0 1 1 1])
t=c(2,:);
c(2,:)=c(5,:);
c(5,:)=t;
end
if(a==[1 1 1 0 1])
t=c(4,:);
c(4,:)=c(5,:);
c(5,:)=t;
end
if(a==[1 1 0 1 1])
t=c(3,:);
c(3,:)=c(5,:);
c(5,:)=t;
end
%第1,2条交配
if(n(1)==1)
t=c(1,1);
c(1,1)=c(2,1);
c(2,1)=t;
end
if(n(1)==2)
t=c(1,3);
c(1,3)=c(2,3);
c(2,3)=t;
t=c(1,4);
c(1,4)=c(2,4);
c(2,4)=t;
end
if(n(1)==3)
t=c(1,4);
c(1,4)=c(2,4);
c(2,4)=t;
end
%3,4条交配
if(n(3)==1)
t=c(3,1);
c(3,1)=c(4,1);
c(4,1)=t;
end
if(n(3)==2)
t=c(3,3);
c(3,3)=c(4,3);
c(4,3)=t;
t=c(3,4);
c(3,4)=c(4,4);
c(4,4)=t;
end
if(n(3)==3)
t=c(3,4);
c(3,4)=c(4,4);
c(4,4)=t;
end
end
%五个染色体两两交配
if(a==[1 1 1 1 1])
%第1,2条交配
if(n(1)==1)
t=c(1,1);
c(1,1)=c(2,1);
c(2,1)=t;
end
if(n(1)==2)
t=c(1,3);
c(1,3)=c(2,3);
c(2,3)=t;
t=c(1,4);
c(1,4)=c(2,4);
c(2,4)=t;
end
if(n(1)==3)
t=c(1,4);
c(1,4)=c(2,4);
c(2,4)=t;
end
%3,4条交配
if(n(3)==1)
t=c(3,1);
c(3,1)=c(4,1);
c(4,1)=t;
end
if(n(3)==2)
t=c(3,3);
c(3,3)=c(4,3);
c(4,3)=t;
t=c(3,4);
c(3,4)=c(4,4);
c(4,4)=t;
end
if(n(3)==3)
t=c(3,4);
c(3,4)=c(4,4);
c(4,4)=t;
end
%第1,5条交配
if(n(5)==1)
t=c(1,1);
c(1,1)=c(5,1);
c(5,1)=t;
end
if(n(5)==2)
t=c(1,3);
c(1,3)=c(5,3);
c(5,3)=t;
t=c(1,4);
c(1,4)=c(5,4);
c(5,4)=t;
end
if(n(5)==3)
t=c(1,4);
c(1,4)=c(5,4);
c(5,4)=t;
end
end
%变异
for i=1:5
for j=1:4
if rand<0.05
c(i,j)=-5+10*rand;
end
end
end
%重新评价染色体适应值,更新best
Ec1=1/(c(1,1)^2+c(1,2)^2+c(1,3)^2+c(1,4)^2+1);
Ec2=1/(c(2,1)^2+c(2,2)^2+c(2,3)^2+c(2,4)^2+1);
Ec3=1/(c(3,1)^2+c(3,2)^2+c(3,3)^2+c(3,4)^2+1);
Ec4=1/(c(4,1)^2+c(4,2)^2+c(4,3)^2+c(4,4)^2+1);
Ec5=1/(c(5,1)^2+c(5,2)^2+c(5,3)^2+c(5,4)^2+1);
E=[Ec1 Ec2 Ec3 Ec4 Ec5];
x=Ec1+Ec2+Ec3+Ec4+Ec5;
pe=[Ec1/x Ec2/x Ec3/x Ec4/x Ec5/x];
[Ebest,Best]=max(E);
c(1,:)=c(Best,:);
fk(k)=Ebest;
k=k+1;
end
x=1:N;
y1=fk(x);
plot(x,y1);
实验分析:
迭代100次
迭代1000次
再次迭代1000次
迭代10000次:
可以看到10000次迭代效果不是很好,图像毛刺比较多。
实验分析
函数预期值为1,可以看到迭代100次,函数大体上递增,但未超过0.8;迭代1000次,函数在200次之后便达到0.9,之后在0.9到1之间,更贴近1。再次执行1000次,函数图形大体和之前吻合。迭代10000出现明显震荡。可以得出结论,1000次迭代能够得到较为理想的实验结果。
时间方面:
经过多次试验,1000次迭代,在一秒内完成。
精度方面:
函数值存在震荡,且存在局部收敛,尽管能提供关于最佳值的信息,但精度不高。
实验总结:
这次遗传算法实验花费时间最多,屡次得不到好的结果,最终在课本例程基础上添加了改动,让最优秀的染色体复制一条取代第一条染色体,迭代效果才差强人意。
个人认为,尽管得到了一定精度的收敛结果,该算法在解决该问题时表现的还不够优秀,具体表现为不够快,不够准。思考原因,问题出在轮盘赌和种群大小上。
从轮盘赌的实现机制看,较优的染色体被选中的概率较大,但由于选择的随机性,当前较差的染色体也具有一定的生存空间。
另一方面,变异是遗传算法中优秀基因的根本来源,然而变异是随机的,得到“好基因”或“坏基因”不以人的意志为转移,除非进化过程中物种保存下来的“好基因”数目多于变异产生的“坏基因”数目———这也是需要轮盘赌体现的实际意义——种群整体适应值才会提高,否则进化是失败的,种群将被淘汰,如果希望函数值至少为0.9,即1/(5*x^2+1)>=0.9,解得“好基因”值区间约为【-0.15,0.15】,该算法变异率设定为0.1,x取值为【-5,5】,那么要想得到”好基因“的概率是0.1*0.3/10=0.3%,即千分之三,如此低的概率下,还存在一个仁慈的轮盘赌,随时可能漏选”好基因“而给”坏基因“留下生存空间。想要进化并提高适应值,这在只有5个个体的种群中是难以想象的。
最后本次实验加强了我对遗传算法机制的理解,但是在该问题求解方面是不能让人满意的,今后可以继续探索更合适的算子选择机制,或合理的种群大小。
完成日期:2017.6.1
当年的计算智能课作业