m=23;
pc=0.6;
pm=0.02;
for i=1:50
s(i)=20*(rand-0.5); %随机生成50个数字
delta_v(i)=(s(i)+10)*10^6;
stringv=dec2bin(delta_v(i)); %生成对应的编码
k=m-length(stringv);
if k>0
a='0';
v1=stringv;
for j=1:k
v1=[a,v1];
end
else
v1=stringv;
end %将编码前面的0补齐
v{i}=cellstr(v1); %50个编码都存入一个元胞数组中
end
%开始正式遗传模拟
for turn=1:1000
for i=1:50
eval(i)=-15*sin(2*s(i))^2-(s(i)-2)^2+220; %适应值,增加了60保证即使超过x=10以后eval依然为正
end
eval_max(turn)=max(eval);
eval_average(turn)=mean(eval);
for i=1:50
eval(i)==eval_max(turn);
pick=i;
end
s_max(turn)=s(pick);
for i=1:50
p(i)=eval(i)/sum(eval); %选择概率
end
q1(1)=p(1);
for i=1:49
q1(i+1)=q1(i)+p(i); %累计概率
end
for i=1:50
q(i)=q1(i)/q1(50); %因为计算精度的关系,理论上q1(50)=1,但是实际上在p(i)相加的时候不等于1,为了保持概率的准确性重新归一化
end
for i=1:50
pick(i)=0; %每个编码选择的次数,先初始化
end
for i=1:50
r=rand;
if r<=q(1);
pick(1)=pick(1)+1;
else
for j=2:50
if r>q(j-1) && r<=q(j);
pick(j)=pick(j)+1; %确定了父本的每个编码数量
end
end
end
end
i=1;
k=1;
while i<51 %生成了新的父本
j=1;
if pick(k)>0
j=k;
v_new1{i}=v{j};
pick(k)=pick(k)-1;
i=i+1;
else
k=k+1;
end
end
cross=1;
uncross=1; %先把v_new1分成两组,杂交的和不杂交的,保存在v_cross和v_uncross中
for i=1:50
r=rand;
if r<0.5
v_cross{cross}=v_new1{i};
cross=cross+1;
else
v_uncross{uncross}=v_new1{i};
uncross=uncross+1;
end
end
cross=cross-1; %杂交的数量
uncross=uncross-1; %未杂交的数量
t=1; %杂交后父本编号用
while cross>1
r=rand;
if r==0
r1=1;
else
r1=ceil(r*cross); %生成第一个杂交的编号
end
v_process1=v_cross{r1}; %提取出第一个编码
k=1;
for i=1:cross %生成剩余的杂交组还未杂交的编码集合
if i==r1
;
else
v_cross{k}=v_cross{i};
k=k+1;
end
end
cross=cross-1; %未杂交的杂交组数量-1
r=rand;
if r==0;
r2=1;
else
r2=ceil(rand*cross);
end
v_process2=v_cross{r2};
k=1;
for i=1:cross %生成剩余的杂交组还未杂交的编码集合
if i==r2
;
else
v_cross{k}=v_cross{i};
k=k+1;
end
end
cross=cross-1;
r=rand;
if r==0 %r3为杂交的断点
r3=1;
elseif r==1
r3=m-1;
else
r3=ceil(r*m);
end
v_str1=char(v_process1);
v_str2=char(v_process2);
v_strnew1=v_str1(1);
v_strnew2=v_str2(1);
for i=1:r3 %杂交过程
v_strnew1=[v_strnew1,v_str1(i)];
v_strnew2=[v_strnew2,v_str2(i)];
end
for i=r3+1:m
v_strnew1=[v_strnew1,v_str2(i)];
v_strnew2=[v_strnew2,v_str1(i)];
end
v_new2{t}=cellstr(v_strnew1);
t=t+1;
v_new2{t}=cellstr(v_strnew2);
t=t+1;
end
t=t-1;
if cross==1 %如果剩下一个没有杂交直接保留
v_new2{t}=v_cross{1};
t=t+1;
end
unpick=1;
for i=t+1:50 %未杂交的加入父本
v_new2{i}=v_uncross{unpick};
unpick=unpick+1;
end
for i=1:50 %变异
v_strnew3=char(v_new2{i});
for k=1:m
r=rand;
if r<pm
if v_strnew3(k)=='1'
v_strnew3(k)='0';
else
v_strnew3(k)='1';
end
end
v_new3{i}=cellstr(v_strnew3);
end
end
for i=1:50 %字符串找到对应的数字s(i)方便重新计算eval值
v_newstr=char(v_new3{i});
deltav(i)=bin2dec(v_newstr);
s(i)=-10+deltav(i)/10^6;
end
end
gen=1:1:1000;
subplot(2,1,1);
scatter(gen,eval_max);
%scatter(gen,eval_average);
subplot(2,1,2);
scatter(gen,s_max);