您的位置:首页 > 其它

基于二进制编码的遗传算法求解函数最大值

2017-12-09 22:20 351 查看

问题描述

求函数f(x)=x+10sin(5x)+7cos(4x)的最大值,其中x的取值范围是[0,10]

该函数有多个局部极值



Matlab遗传算法代码

采用二进制编码

轮盘赌选择法

脚本

初始化参数

clear all;      %清除所有变量
close all;      %清图
clc;            %清屏
NP=50;          %种群数量,一般取10~200,即染色体数目,将定义域划分50个(不等距)
L=20;           %二进制位串长度,即染色体上基因数目,和计算要求的精度有关,如
%精度10^-5,则2^19<10*10^5<2^20,至少需要20位
Pc=0.8;         %交叉率,一般取0.25~1
Pm=0.1;         %变异率,一般取0.001~0.1
G=100;          %最大遗传代数,一般100~1000
Xs=10;          %定义域上限
Xx=0;           %定义域下限
f=randi([0,1],NP,L);  %随机获得初始种群
trace=zeros(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数组中的位置,返回一个数组,因为可能有几个相同的最大值
%这点要特别注意,所以下面不能直接用rr
fBest=f(rr(1,1),:);         %最优适应度,有多个相同值时只取第一个
xBest=x(rr(1,1));           %最优适应度对应的染色体
Fit=(Fit-minFit)/(maxFit-minFit);   %归一化适应度值


在本代挑选交配的父母染色体

sum_Fit=sum(Fit);
fitvalue=Fit./sum_Fit;      %可以看作概率密度f
fitvalue=cumsum(fitvalue);  %可以看作概率累计F
ms=sort(rand(NP,1));        %随机生成(0,1)的升序概率密度NP向量
fiti=1;
newi=1;
%由ms可以看出这是一种随机的复制方式,但总趋势是将适应度比较大的遗传下去
while newi <=NP   %父母双方以同样的方式挑选
if (ms(newi)<fitvalue(fiti))
nf(newi,:)=f(fiti,:);
newi=newi+1;
else
fiti=fiti+1;
end
end


随机交叉

for i=1:2:NP
p=rand;
if p<Pc                     %控制交叉的染色体总数
q=randi([0,1],1,L);     %随机生成要交叉的基因位置
for j=1:L
if q(j)==1
temp=nf(i+1,j);
nf(i+1,j)=nf(i,j);
nf(i,j)=temp;   %父母染色体在指定位置进行交叉
end
end
end
end


变异操作

i=1;
while i<=round(NP*Pm)       %控制变异染色体总数
h=randi([1,NP],1,1);    %随机选取一个染色体
for j=1:round(L*Pm)     %控制染色体上变异基因总数
g=randi([1,L],1,1); %随机选取一个基因进行变异
nf(h,g)=~nf(h,g);   %变异,即取反
end
i=i+1;
end


完整代码

%%%%%标准遗传算法求函数极值%%%%
%%%%%初始化参数%%%%%
clear all; %清除所有变量 close all; %清图 clc; %清屏 NP=50; %种群数量,一般取10~200,即染色体数目,将定义域划分50个(不等距) L=20; %二进制位串长度,即染色体上基因数目,和计算要求的精度有关,如 %精度10^-5,则2^19<10*10^5<2^20,至少需要20位 Pc=0.8; %交叉率,一般取0.25~1 Pm=0.1; %变异率,一般取0.001~0.1 G=100; %最大遗传代数,一般100~1000 Xs=10; %定义域上限 Xx=0; %定义域下限 f=randi([0,1],NP,L); %随机获得初始种群 trace=zeros(1,G); %预先分配内存
%%%%%%%%遗传算法循环%%%%%%%%
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数组中的位置,返回一个数组,因为可能有几个相同的最大值
%这点要特别注意,所以下面不能直接用rr
fBest=f(rr(1,1),:); %最优适应度,有多个相同值时只取第一个
xBest=x(rr(1,1)); %最优适应度对应的染色体
Fit=(Fit-minFit)/(maxFit-minFit); %归一化适应度值
%%%%%至此本代最优已筛选出来,下面开始为下一代作准备%%%%
%%%%%基于轮盘赌的复制操作,在本代挑选出交配的父母双方%%%%
sum_Fit=sum(Fit);
fitvalue=Fit./sum_Fit; %可以看作概率密度f
fitvalue=cumsum(fitvalue); %可以看作概率累计F
ms=sort(rand(NP,1)); %随机生成(0,1)的有序概率密度NP大小向量
fiti=1;
newi=1;
%由ms可以看出这是一种随机的复制方式,但总趋势是将适应度比较大的遗传下去
while newi <=NP
if (ms(newi)<fitvalue(fiti))
nf(newi,:)=f(fiti,:);
newi=newi+1;
else
fiti=fiti+1;
end
end
%%%%%%%%基于概率的交叉操作%%%%%%%%
for i=1:2:NP
p=rand;
if p<Pc %控制交叉的染色体总数
q=randi([0,1],1,L); %随机生成要交叉的基因位置
for j=1:L
if q(j)==1
temp=nf(i+1,j);
nf(i+1,j)=nf(i,j);
nf(i,j)=temp; %两条相邻染色体在指定位置进行交叉
end
end
end
end
%%%%%%%%%基于概率的变异操作%%%%%%%%%%%%
i=1;
while i<=round(NP*Pm) %控制变异染色体总数
h=randi([1,NP],1,1); %随机选取一个染色体进行变异
for j=1:round(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; %历代最优是应当由,即最大函数值
end
disp('最优解');
disp(xBest); %最优个体,也就是最优解
figure
plot(trace)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')


函数

function fit=func1(x)
fit=x+10*sin(5*x)+7*cos(4*x);
end


计算结果

函数最大值出现在x=7.86附近,约为24.86

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: