标准遗传算法求解函数最大值(基于MATLAB)
声明:
1.本文源代码来自书目《智能优化算法及其MATLAB实例(第3版)》,目的在于为MATLAB初学者提供更简明的代码解析,方便读者了解算法及MATLAB编程基本原理。
2.文中代码每一行后都有相应注释,因此本文是一篇适合所有代码水平的学习者阅读的文章。如果觉得有帮助,麻烦点个赞哦!
例2.1 用标准遗传算法求函数发f(x)=x+10sin(5x)+7cos(4x)的最大值,其中x取值范围【0,10】。
话不多说,直接上代码片:
%%%%%%%%f(x)=x+10sin(5x)+7cos(4x)%%%%%%%%%
%%%%%%%%先画图看看函数形状%%%%%%%%%%%%%%%%%
clear all; %清除所有变量
close all; %清图
clc; %清屏
x=0:0.01:10;
y=x+10*sin(5*x)+7*cos(4*x);
plot(x,y)
xlabel('x')
ylabel('f(x)')
title('f(x)=x+10sin(5x)+7cos(4x)')
%%%%%%%%标准遗传算法求函数极值%%%%%%%%%%
%%%%%%%%%%%初始化参数%%%%%%%%%%%%%%%%%%
clear all; %清除所有变量
clc; %清屏
NP=50; %种群数量
L=20; %二进制位串长度
Pc=0.8; %交叉率
Pm=0.1; %变异率
G=100; %最大遗传代数
Xs=10; %上限
Xx=0; %下限
f=randi([0,1],NP,L);%随机获得初始种群(二维数组)
%%%%%%%%遗传算法循环%%%%%%%%%%%%%%%%%%
for k=1:G
%%%%%%%将二进制解码为定义域范围内十进制%%%%%%%
for i=1:NP %对种群中每个个体
U=f(i,:); %求种群中每个个体的染色体二进制编码数组
m=0;
for j=1:L %遍历某个个体的每一位
m=U(j)*2^(j-1)+m;%求出该个体的二进制编码的十进制数
end
x(i)=Xx+m*(Xs-Xx)/(2^L-1);%映射到所要求的的自变量区间上
Fit(i)=func1(x(i));%调用适应度函数
end
maxFit=max(Fit); %定义适应度中的最大值
minFit=min(Fit); %定义适应度中的最小值
rr=find(Fit==maxFit); %返回适应度函数值组成的数组Fit中等于最大值的所有元素索引值组成的数组
fBest=f(rr(1,1),:); %得到第k代最优个体的染色体编码数组
xBest=x(rr(1,1)); %得到最优个体对应十进制映射数值
Fit=(Fit-minFit)/(maxFit-minFit);%归一化适应度函数值
%%%%%%%基于轮盘赌的复制操作%%%%%%%%%%
sum_Fit=sum(Fit); %定义适应度函数值总和
fitvalue=Fit./sum_Fit; %得到个体被选择概率数组=适应度函数值数组./适应度函数总和(轮盘赌)
fitvalue=cumsum(fitvalue);%cumsum函数返回与原先同等维度和结构的累加和形式数组
ms=sort(rand(NP,1)); %随机生成NP行1列的【0,1】范围小数的列向量并且升序排序
fiti=1; %计数变量,表示原种群中当前被比较的个体序号
newi=1; %计数变量,表示现在被选择进入下一代的个体序号
while newi<=NP
if (ms(newi))<fitvalue(fiti) %当ms随机数数组中第newi个随机小数小于适应度第fiti个累计值时
nf(newi,:)=f(fiti,:); %进行选择个体操作,生成子代种群nf第newi个个体并赋值染色体
newi=newi+1; %进入下一代个体数加1
else
fiti=fiti+1; %若不满足,则该个体不被选择,进入下一个个体的判断
end
end
%%%%%%%%基于概率的交叉操作%%%%%%%%
for i=1:2:NP %步长为2,代表从原种群数组中选取相邻两个为一对考虑是否进行交叉操作
p=rand; %生成【0,1】随机小数
if p<Pc %若p小于交叉概率
q=randi([0,1],1,L); %生成一条(0,1)分布的二进制数串
for j=1:L %对该数串上的每一位
if q(j)==1 %如果第j位上的值为1,则进行第i组个体的第j位交叉操作
temp=nf(i+1,j);
nf(i+1,j)=nf(i,j);
nf(i,j)=temp; %上三步完成了第j位交叉互换
end
end
end
end
%%%%%%%%基于概率的变异操作%%%%%%%%%
i=1;
while i<=round(NP*Pm) %round表示四舍五入法取整,表示总共要对NP*Pm个个体进行变异
h=randi([1,NP],1,1); %随机选取一条需要变异的染色体
for j=1:round(L*Pm) %在需要变异的某条染色体总共进行L*Pm个基因变异
g=randi([1,L],1,1); %随机选取需要变异的基因序号
nf(h,g)=~nf(h,g); %取反完成变异
end
i=i+1;
end
f=nf;
f(1,:)=fBest; %保留最优个体在新种群中
trace(k)=maxFit; %把第k代最优适应度保存到数组trace中
end
disp(['最终函数最大值点为',num2str(xBest)])%循环结束后在命令行输出最后一代的最优个体对应的映射值
figure
plot(trace) %画图画出历代函数最大值(即适应度函数最大值)进化曲线
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')
%%%%%%%%适应度函数%%%%%%%%%%
function result=func1(x) %定义函数名为func1和返回形式参数名为result的适应度函数
fit=x+10*sin(5*x)+7*cos(4*x); %直接把目标函数作为适应度函数,这也就解释了为什么适应度最大就最优
result=fit;
end
得到最终效果如下所示: