%使用遗传算法求解
% f(x1,x2)=x1^2+x2^2-0.3*cos(3*pi*x1)-0.4*cos(4*pi*x2)+0.7的极小值,并画出每一代中个体适配函
% 数的平均值和最小值随迭代次数的变化关系
%程序总体说明:
% 编码方式说明: 由于期望所求的函数极小值包含了平方项,而正弦和余弦项的范围只能是-1---1,因此优化范围的x1,x2只能在-1--1之间,编码时
% 首先将x1,x2加1变到0--2之间,之后为了编码需要,设采样精度是0.01 ,将0--2之间的数乘以100,得到0--200之间的整数,另外为了编码的需要,
%设编码为8位,编码成0--255的二进制码。,每个个体用16位的二进制串表示,的前8位是x1,后8位是x2
%适配制计算说明:%根据编码方式,将每一个个体的编码变化到-1--1之间,之后按照函数f计算
%可以选择 1--直接利用函数的倒数作为适配值计算; 2--使用排序法计算, 3--使用1-J(i)/sum(J)方法计算
%复制操所机制:1--轮盘赌方法 ; 2--保留最优淘汰法
%交叉机制: 使用掩码法进行交叉操作.
clear all;
%使用
disp 'f(x1,x2)=x1^2+x2^2-0.3*cos(3*pi*x1)-0.4*cos(4*pi*x2)+0.7'
disp '输入初始化参数'
inum=input('请输入种群大小(回车为缺省值30个个体): ');
if isempty(inum)
inum=50; %种群中的个体数
end
count=input('请输入迭代次数(回车为缺省值100代): ');
if isempty(count)
count=100; %迭代次数
end
pcross=input('请输入交叉概率(回车为缺省值0.6): ');
if isempty(pcross)
pcross=0.6; %交叉概率
end
pchange=input('请输入变异概率(回车为缺省值0.001): ');
if isempty(pchange)
pchange=0.001; %变异概率
end
disp '程序实现机制选择'
%程序实现机制选择
Fitflag=input('请输入适配度的计算方法(1为1/f(x1,x2), 2为排序法,3为1-J(i)/sum(J),缺省为2 ): ' );
if (isempty(Fitflag))||(Fitflag>3)
Fitflag=2;
end
Copyflag=input('请输入适配度的计算方法(1为轮盘赌法,2为最优保存淘汰法,缺省为2): ');
if (isempty(Copyflag))||(Copyflag>2)
Copyflag=2;
end
%程序计算开始
constk=5; %用来控制适配制之间的常数
%初始种群
Individual=rand(inum,16); % 表示的个体的矩阵
Individual=round(Individual); %变成01 串
J=zeros(inum,1); %存储各个个体的函数值
Jorder=zeros(inum,1); %函数值的大小顺序
Adap=zeros(inum,1); %适配度
MeanAdap=zeros(count,1); %存储每一代的适配度均值
MinAdap=zeros(count,1); %存储每一代的适配度最小值
%初始化随便找一个Xg;
%迭代
for k=1:count
[inum1 col]=size(Individual);
for i=1:inum1 %每一个个体计算
%适配度计算
%转化成十进制数
x1=0;
x2=0;
for j=1:8
ex=8-j;
x1=x1+Individual(i,j)*2^ex; % 计算x1 0--256
x2=x2+Individual(i,j+8)*2^ex; % 计算x2 0--256
end %end of j
x1=x1/100-1.28; % 变换 x1到 -1.28:1.28
x2=x2/100-1.28; % 变换 x2到 -1.28:1.28
%适配度计算
J(i,k)=(x1^2+x2^2-0.3*cos(3*pi*x1)-0.4*cos(4*pi*x2)+0.7);
end %end of i
switch Fitflag
case 1 %1为1/f(x1,x2), 2为排序法,3为1-J(i)/sum(J)
Adap=1/J(:,k);
case 2
%排序,按照顺序计算适配值
[B,Jorder] = sort(J(:,k)); %次序是从小到大排列
for i=1:inum1
tempi=Jorder(i);
Adap(tempi)=constk*(inum1-i)/inum1;
end
case 3
tempj=ones(inum1,1);
Adap=tempj-J(:,k)/sum(J(:,k));
end %end of switch
MeanAdap(k)=mean(Adap);
MinAdap(k)=min(Adap);
MeanJ(k)=mean(J(:,k));
[MinJ(k),Indexmin]=min(J(:,k));
%得到最优解,保存在Xg中
if (k==1)
Xg(1)=MinJ(k);
MinIndividual=Individual(Indexmin,:);
else
if (MinJ(k)<Xg(k-1))
Xg(k)=MinJ(k);
MinIndividual=Individual(Indexmin,:);
else
Xg(k)=Xg(k-1);
end
end % end of if
Adap1=Adap/sum(Adap); %适配度的比例
TempIndividual=Individual;
Individual=zeros(inum,16);
%复制
switch Copyflag
case 1 %1为轮盘赌法,2为最优保存淘汰法
%随机产生一个数
for i=1:inum1
if (i==1)
route(i)=Adap1(i); %产生轮盘
else
route(i)=route(i-1)+Adap1(i);
end
end
for i=1:inum %复制产生inum个个体
prob=rand;
for j=1:inum1 % 根据轮盘赌概率决定哪个个体被复制
if (j==1) %第一个个体的概率
if (prob<route(j))
Individual(i,:)=TempIndividual(j,:);
break;
else
continue;
end %第一个节点判断完成
else %不是第一个
if (route(j-1)<prob)&&(prob<route(j))
Individual(i,:)=TempIndividual(j,:);
break;
else
continue;
end
end % end of j==1
end %end of j
end %end of i
% end of case 1 轮盘赌法复制结束
case 2
[B,Jorder] = sort(J(:,k)); %次序是从小到大排列
for i=1:inum
Individual(i,:)=TempIndividual(Jorder(i),:);
end %end of i
% end of case 2 最优个体保存法复制 结束
end % end of switch 复制结束
%交叉
ptemp=rand;
if (ptemp<pcross) %产生交叉
%掩码交叉
rand1=randperm(inum); %产生随机数,然后每两个两两交叉.
for i=1:inum/2
p1=rand1(2*(i-1)+1);
p2=rand1(2*(i-1)+2);
%产生父母
parent1=Individual(p1,:);
parent2=Individual(p2,:);
%产生个体
%产生掩码
maskcode=rand(inum,16); %产生掩码
maskcode=round(maskcode); %变成01 串
for j=1:col
if (maskcode(j)==1) %是1则父母的位交换
Child1(j)=parent2(j); %子1
Child2(j)=parent1(j); %子2
else %是0不交换
Child1(j)=parent1(j); %子1
Child2(j)=parent2(j); %子2
end % end if
end % 按位交叉变异 end of j
end %end of i
Individual(inum+1,:)=Child1;
Individual(inum+2,:)=Child2;
else %不产生交叉,就随机生成2个子代供选择
Temp=rand(1,16); % 表示的个体
Individual(inum+1,:)=round(Temp); %变成01 串
Temp1=rand(1,16); % 表示的个体
Individual(inum+2,:)=round(Temp1); %变成01 串
end %end of if 交叉
%变异
ptempchange=rand;
if (ptempchange<pchange) %发生变异
rand2=randperm(inum);
p1=rand2(1); %取出随机产生的一个个体变异
randbyte=randperm(16);
Individual(p1,randbyte)=abs(Individual(p1,randbyte)-1); % 减一取绝对值,变化0,1
end % end of if 变异
end %迭代结束
%显示结果
figure('color','white');
k=1:count;
plot(k,MeanJ);
title('函数值均值随迭代次数的变化');
figure('color','white');
plot(k,MinJ);
title('函数值最小值随迭代次数的变化');
disp '最小的函数值'
min(Xg)
x1=0;
x2=0;
for j=1:8
ex=8-j;
x1=x1+MinIndividual(j)*2^ex; % 计算x1 0--256
x2=x2+MinIndividual(j+8)*2^ex; % 计算x2 0--256
end %end of j
disp '取得最小值时的变量x1,x2的值'
x1=x1/100-1.28 % 变换 x1到 -1.28:1.28
x2=x2/100-1.28 % 变换 x2到 -1.28:1.28
%适配度计算
Result=(x1^2+x2^2-0.3*cos(3*pi*x1)-0.4*cos(4*pi*x2)+0.7)
figure('color','white');
plot(k,Xg);
t=strcat('最优解随迭代次数的变化,最优解= ',num2str(Xg(count)));
title(t);
figure('color','white');
plot(k,MeanAdap);
title('适配值的均值');
figure('color','white');
plot(k,MinAdap);
title('适配值的最小值');