很久以来就想把遗传算法写出来,一直拖拉到现在,关于遗传算法的原理可以查阅网上的相关资料,算法的流程图附在下边。
按照上边的流程描述,我们考虑一个全局寻优问题,自变量x范围[0,10],目标函数为y=x+10*sin(5*x)+7*cos(4*x)
现在我们就用遗传算法解决这个问题。
%===========函数1:遗传算法
function [top_X,top_Y]=Genet(NP,L,Pc,Pm,G,Xs,Xx)
% % % 遗传算法,用于全局寻优
% % % 输入
%NP 种群中单个样本的数量
%L 对样本的基因信息需要的编码长度
%Pc 种群中参与交叉遗传的样本概率
%Pm 种群中参与变异遗传的样本概率
%G 寻优的最大次数
%Xx 把样本的二进制基因转变为十进制范围的上限
%Xx 把样本的二进制基因转变为十进制范围的下限
% % % 输出
%top_X ,top_Y 得到的最大适应值
top_X=0;top_Y=0;
f=randi([0,1],NP,L);%随机初始化种群的NP个样本,每个样本以L个二进制0 1表示
trace=zeros(1,G); %记录每次寻优中的最大适应度
for k=1:1:G %设置最大寻优次数
x=zeros(1,size(f,1));
Fit=zeros(1,size(f,1));
for i=1:1:size(f,1) %考察每个样本
U=f(i,:);
m=0;
for j=1:1:L
m=U(j)*power(2,j-1)+m; %将每个样本由二进制转变为十进制
end
x(i)=Xx+m*(Xs-Xx)/(power(2,L)-1); %将每个样本的十进制归一化到[Xx,Xs]范围
Fit(i)=fun(x(i)); %计算每个样本的适应度
end
maxFit=max(Fit);
minFit=min(Fit);
bin=find(Fit==maxFit);
fBest=f(bin(1,1),:);
xBest=x(bin(1,1));
if top_Y<=maxFit
top_Y=maxFit;
top_X=xBest;
end
Fit=(Fit-minFit)/(maxFit-minFit); %将适应度归一化到[0,1]
%按照轮盘赌法随机选择样本作为交叉操作的父母
select=roulette(Fit,ceil(NP*Pc));%参与交叉遗传的父母样本的坐标
if mod(length(select),2)==0
num_c=length(select);
else
num_c=length(select)-1;
end
for i=1:2:num_c
q=randi([0,1],1,L);
for j=1:1:L
if q(j)==1
temp=f(select(i),j); %相邻的两个样本进行交叉变换
f(select(i),j)=f(select(i+1),j);
f(select(i+1),j)=temp;
end
end
end
% 对种群进行变异操作
num_tot=randperm(NP); %对NP个数进行随机排列
num=round(NP*Pm); %选择num个样本参与变异
num_s=num_tot(1:num);
for i=1:1:num %对num个样本进行变异
h=num_s(i);
for j=1:1:round(L*Pm) %有(L*Pm)个染色体参与变异
g=randi([1,L],1,1); %从L个染色体随机选择
f(h,g)=~f(h,g);
end
end
f=[fBest;f];
trace(k)=maxFit;
end
%绘制寻优结果
figure(1);clf
plot(trace);
xlabel('寻优次数');ylabel('最大适应度');
title('寻优曲线');
figure(2);clf
t=Xx:0.01:Xs;
T=fun(t);
plot(t,T);hold on
plot(top_X,top_Y,'go');%用绿色的圆圈表示找到的最优点
hold off
%===========函数2:轮盘赌法
function index=roulette(V,m)
%用轮盘赌法选择m个个体
% Input:
% V -----待挑选种群中每个个体的重要性指标(如适应度等)
% m -----选择的个体数
% Output:
% index -----挑选的m个体的位置索引
%Tips:当V为全零向量时,该算法无效,将随机选择个体;否则算法将从重要性指标不为0的个体中选择。
n=size(V,2);%待挑选的个体数
if max(V)==0&&min(V)==0%如果V是全零向量,随机选择
index=ceil(rand(1,m)*n);
else
%将适应度为0的个体驱逐出待选择范围
temindex=find(V~=0);
n=length(temindex);%待挑选的个体数目降低
V=V(temindex);
index=zeros(1,m);
%[V,I]=sort(V,'descend');
V=cumsum(V)/sum(V);
pp=rand(1,m);
for i=1:m,
for j=1:n,
if pp(i)<V(j)
index(i)=j;
break
end
end
end
index(i)=temindex(index(i));
end
%============函数3:适应度函数
function res=fun(x)
res=x+10*sin(5*x)+7*cos(4*x);
end
%=============遗传算法演示与结果
[X,Y]=Genet(50,20,0.8,0.1,100,10,0);
X =
7.8567
Y =
24.8554