%测试函数 F(x)=-cos(x1)*cos(x2)*exp(-(x1-pi)^2-(x2-pi)^2);
clear all;
clc;
tic
% 初始化参数
D=500; %进化代数
umax=100; %x1和x2得取值范围均为[-100,100]
umin=-100;
prob_crossover = 0.8; % 交叉概率
prob_mutation = 0.01; % 变异概率
prob_deletion = 0.01; % 删除概率
prob_insertion = 0.01; % 插入概率
prob_invertion = 0.01; % 倒位概率
del_ins_len = 3; % 删除或插入长度
soap_size = 20; % DNA汤的大小
dna_length = 30; % 染色体长度
DNA_Soap = zeros(soap_size,dna_length); % 初始化DNA汤
New_DNA_Soap = zeros(soap_size,dna_length);%初始化新DNA汤
best_dna = zeros(1,dna_length);
% 初始化DNA汤
for i = 1:soap_size
for j = 1:dna_length
rand_num = rand;
if rand_num > 0.0 && rand_num < 0.25
DNA_Soap(i,j) = 0;
elseif rand_num > 0.25 && rand_num < 0.5
DNA_Soap(i,j) = 1;
elseif rand_num > 0.5 && rand_num < 0.75
DNA_Soap(i,j) = 2;
elseif rand_num > 0.75 && rand_num < 1.0
DNA_Soap(i,j) = 3;
end
end
end
for k=1:1:D
time(k)=k;
for s=1:1:soap_size
m=DNA_Soap(s,:); %m为DNA_Soap的依次一整行四进制数
y1=0;y2=0; %转为十进制数的中间变量赋初值
%解码过程
m1=m(1:1:dna_length/2);
for i=1:1:dna_length/2
y1=y1+m1(i)*4^(i-1); %转为十进制数
end
x1=(umax-umin)*y1/(4^15-1)+umin; %x1解码
m2=m(dna_length/2+1:1:dna_length);
for i=1:1:dna_length/2
y2=y2+m2(i)*4^(i-1);
end
x2=(umax-umin)*y2/(4^15-1)+umin;%x2解码
%将测试函数取负作为个体适应度函数F(2),计算其最优解
F(s)=cos(x1)*cos(x2)*exp(-(x1-pi)^2-(x2-pi)^2);
end
%适应度值评价
Ji=1./F; %选个体适应度的倒数作为目标函数
%适应度值评价
BestJ(k)=-min(Ji); %每一代中的最小值
fit=F; %个体适应度函数
[Sort,Index]=sort(fit); %将fit从小到大排序
Bestfit=Sort(soap_size); %使Bestfit=max(fit)(适应度值)
BestS=DNA_Soap(Index(soap_size),:); %使BestS指向拥有最大适应度值的个体(单代最优个体)
BestF(k)=-Bestfit; %最优解函数
%选择过程
fit_sum=sum(fit); %适应度值求和
P=fit/fit_sum; %求每个个体的选择概率
Q=cumsum(P); %累积概率
sum_Q=[0 Q];
for i=1:1:soap_size
New_DNA_Soap(i,:)=DNA_Soap(length(find(rand>=sum_Q)),:); %选择操作
end
% 交叉过程
for i = 1:2:soap_size-1
if rand < prob_crossover
crossover_point = floor(dna_length*rand) + 1;
% 交叉
for j = crossover_point:dna_length
New_DNA_Soap(i,j) = DNA_Soap(i+1,j); %保留最优个体
New_DNA_Soap(i+1,j) = DNA_Soap(i,j);
end
end
end
New_DNA_Soap(soap_size,:)=BestS;
DNA_Soap = New_DNA_Soap;
% 变异,变异有多种,如碱基的替换、丢失、插入
% 碱基的替换
for i = 1:soap_size
for j = 1:dna_length
if rand < prob_mutation
rand_num = rand;
if New_DNA_Soap(i,j) == 0
if rand_num > 0.0 && rand_num < 1/3
New_DNA_Soap(i,j) = 1;
elseif rand_num > 1/3 && rand_num < 2/3
New_DNA_Soap(i,j) = 2;
elseif rand_num > 2/3 && rand_num < 1
New_DNA_Soap(i,j) = 3;
end
elseif New_DNA_Soap(i,j) == 1
if rand_num > 0.0 && rand_num < 1/3
New_DNA_Soap(i,j) = 0;
elseif rand_num > 1/3 && rand_num < 2/3
New_DNA_Soap(i,j) = 2;
elseif rand_num > 2/3 && rand_num < 1
New_DNA_Soap(i,j) = 3;
end
elseif New_DNA_Soap(i,j) == 2
if rand_num > 0.0 && rand_num < 1/3
New_DNA_Soap(i,j) = 0;
elseif rand_num > 1/3 && rand_num < 2/3
New_DNA_Soap(i,j) = 1;
elseif rand_num > 2/3 && rand_num < 1
New_DNA_Soap(i,j) = 3;
end
elseif New_DNA_Soap(i,j) == 3
if rand_num > 0.0 && rand_num < 1/3
New_DNA_Soap(i,j) = 0;
elseif rand_num > 1/3 && rand_num < 2/3
New_DNA_Soap(i,j) = 1;
elseif rand_num > 2/3 && rand_num < 1
New_DNA_Soap(i,j) = 2;
end
end
end
end
end
New_DNA_Soap(soap_size,:)=BestS;
DNA_Soap = New_DNA_Soap;
% 碱基的丢失于插入,此处丢失碱基长度不超过3
for i = 1:soap_size
if rand < prob_deletion + prob_insertion
% 丢失
if rand < 0.5
del_p = floor(dna_length*rand) + 1; % 丢失起点
del_len = floor(del_ins_len*rand) + 1; % 丢失长度
while (del_p + del_len - 1) > dna_length
del_p = floor(dna_length*rand) + 1;
del_len = floor(2*del_ins_len*rand) + 1;
end
% 丢失[dele_p1,dele_p2]的部分
for j = del_p:dna_length - del_len
New_DNA_Soap(i,j) = DNA_Soap(i,j + del_len);
end
% 后面部分由随机产生补上
for j = dna_length - del_len + 1:dna_length
if rand_num > 0.0 && rand_num < 0.25
New_DNA_Soap(i,j) = 0;
elseif rand_num > 0.25 && rand_num < 0.5
New_DNA_Soap(i,j) = 1;
elseif rand_num > 0.5 && rand_num < 0.75
New_DNA_Soap(i,j) = 2;
elseif rand_num > 0.75 && rand_num < 1.0
New_DNA_Soap(i,j) = 3;
end
end
% 插入
else
ins_p = floor(dna_length*rand) + 1; % 插入点
ins_len = floor(del_ins_len*rand) + 1; % 插入长度
while (ins_p + ins_len) > dna_length
ins_p = floor(dna_length*rand) + 1;
ins_len = floor(del_ins_len*rand) + 1;
end
% 插入部分随机产生
for j = ins_p + 1:ins_p + ins_len
if rand_num > 0.0 && rand_num < 0.25
New_DNA_Soap(i,j) = 0;
elseif rand_num > 0.25 && rand_num < 0.5
New_DNA_Soap(i,j) = 1;
elseif rand_num > 0.5 && rand_num < 0.75
New_DNA_Soap(i,j) = 2;
elseif rand_num > 0.75 && rand_num < 1.0
New_DNA_Soap(i,j) = 3;
end
end
for j = ins_len + ins_len + 1:dna_length
New_DNA_Soap(i,j) = DNA_Soap(i,j - ins_len);
end
end
end
end
New_DNA_Soap(soap_size,:)=BestS;
DNA_Soap = New_DNA_Soap;
% 倒位
for i = 1:soap_size
if rand < prob_invertion
% 第一倒位点
inverse_point1 = floor(dna_length*rand) + 1;
% 第二倒位点
inverse_point2 = floor(dna_length*rand) + 1;
% 两个倒位点不能相同,使第二个倒位点在后面
while inverse_point1 == inverse_point2
inverse_point2 = floor(dna_length*rand) + 1;
end
if inverse_point1 > inverse_point2
temp = inverse_point1;
inverse_point1 = inverse_point2;