遗传算法Matlab源代码.docx
《遗传算法Matlab源代码.docx》由会员分享,可在线阅读,更多相关《遗传算法Matlab源代码.docx(19页珍藏版)》请在冰点文库上搜索。
![遗传算法Matlab源代码.docx](https://file1.bingdoc.com/fileroot1/2023-5/1/a157384a-5a10-4f40-919c-9daa4a09d43f/a157384a-5a10-4f40-919c-9daa4a09d43f1.gif)
遗传算法Matlab源代码
function[X,MaxFval,BestPop,Trace]=fga(FUN,bounds,MaxEranum,PopSize,options,pCross,pMutation,pInversion)
%[X,MaxFval,BestPop,Trace]=fga(FUN,bounds,MaxEranum,PopSize,options,pCross,pMutation,pInversion)
%Findsamaximumofafunctionofseveralvariables.
%fgasolvesproblemsoftheform:
%maxF(X)subjectto:
LB<=X<=UB(LB=bounds(:
1),UB=bounds(:
2))
%X-最优个体对应自变量值
%MaxFval-最优个体对应函数值
%BestPop-最优的群体即为最优的染色体群
%Trace-每代最佳个体所对应的目标函数值
%FUN-目标函数
%bounds-自变量范围
%MaxEranum-种群的代数,取50--500(默认200)
%PopSize-每一代种群的规模;此可取50--200(默认100)
%pCross-交叉概率,一般取0.5--0.85之间较好(默认0.8)
%pMutation-初始变异概率,一般取0.05-0.2之间较好(默认0.1)
%pInversion-倒位概率,一般取0.05-0.3之间较好(默认0.2)
%options-1*2矩阵,options
(1)=0二进制编码(默认0),option
(1)~=0十进制编码,option
(2)设定求解精度(默认1e-4)
T1=clock;
%检验初始参数
ifnargin<2,error('FMAXGArequiresatleastthreeinputarguments');end
ifnargin==2,MaxEranum=150;PopSize=100;options=[11e-4];pCross=0.85;pMutation=0.1;pInversion=0.25;end
ifnargin==3,PopSize=100;options=[11e-4];pCross=0.85;pMutation=0.1;pInversion=0.25;end
ifnargin==4,options=[11e-4];pCross=0.85;pMutation=0.1;pInversion=0.25;end
ifnargin==5,pCross=0.85;pMutation=0.1;pInversion=0.25;end
ifnargin==6,pMutation=0.1;pInversion=0.25;end
ifnargin==7,pInversion=0.25;end
if(options
(1)==0|options
(1)==1)&find((bounds(:
1)-bounds(:
2))>0)
error('数据输入错误,请重新输入:
');
end
%定义全局变量
globalmnNewPopchildren1children2VarNum
%初始化种群和变量
precision=options
(2);
bits=ceil(log2((bounds(:
2)-bounds(:
1))'./precision));%由设定精度划分区间
VarNum=size(bounds,1);
[Pop]=InitPop(PopSize,bounds,bits,options);%初始化种群
[m,n]=size(Pop);
fit=zeros(1,m);
NewPop=zeros(m,n);
children1=zeros(1,n);
children2=zeros(1,n);
pm0=pMutation;
BestPop=zeros(MaxEranum,n);%分配初始解空间BestPop,Trace
Trace=zeros(1,MaxEranum);
Lb=ones(PopSize,1)*bounds(:
1)';
Ub=ones(PopSize,1)*bounds(:
2)';
%二进制编码采用多点交叉和均匀交叉,并逐步增大均匀交叉概率
%浮点编码采用离散交叉(前期)、算术交叉(中期)、AEA重组(后期)
OptsCrossOver=[ones(1,MaxEranum)*options
(1);...
round(unidrnd(2*(MaxEranum-[1:
MaxEranum]))/MaxEranum)]';
%浮点编码时采用两种自适应变异和一种随机变异(自适应变异发生概率为随机变异发生的2倍)
OptsMutation=[ones(1,MaxEranum)*options
(1);unidrnd(5,1,MaxEranum)]';
ifoptions
(1)==3
D=zeros(n);
CityPosition=bounds;
D=sqrt((CityPosition(:
ones(1,n))-CityPosition(:
ones(1,n))').^2+...
(CityPosition(:
2*ones(1,n))-CityPosition(:
2*ones(1,n))').^2);
end
%==========================================================================
%进化主程序%
%==========================================================================
eranum=1;
H=waitbar(0,'Pleasewait...');
while(eranum<=MaxEranum)
forj=1:
m
ifoptions
(1)==1
%eval(['[fit(j)]='FUN'(Pop(j,:
));']);%但执行字符串速度比直接计算函数值慢
fit(j)=feval(FUN,Pop(j,:
));%计算适应度
elseifoptions
(1)==0
%eval(['[fit(j)]='FUN'(b2f(Pop(j,:
),bounds,bits));']);
fit(j)=feval(FUN,(b2f(Pop(j,:
),bounds,bits)));
else
fit(j)=-feval(FUN,Pop(j,:
),D);
end
end
[Maxfit,fitIn]=max(fit);%得到每一代最大适应值
Meanfit(eranum)=mean(fit);
BestPop(eranum,:
)=Pop(fitIn,:
);
Trace(eranum)=Maxfit;
ifoptions
(1)==1
Pop=(Pop-Lb)./(Ub-Lb);%将定义域映射到[0,1]:
[Lb,Ub]-->[0,1],Pop-->(Pop-Lb)./(Ub-Lb)
end
switchround(unifrnd(0,eranum/MaxEranum))%进化前期尽量使用实行锦标赛选择,后期逐步增大非线性排名选择
case{0}
[selectpop]=TournamentSelect(Pop,fit,bits);%锦标赛选择
case{1}
[selectpop]=NonlinearRankSelect(Pop,fit,bits);%非线性排名选择
end
[CrossOverPop]=CrossOver(selectpop,pCross,OptsCrossOver(eranum,:
));%交叉
[MutationPop]=Mutation(CrossOverPop,fit,pMutation,VarNum,OptsMutation(eranum,:
));%变异
[InversionPop]=Inversion(MutationPop,pInversion);%倒位
%更新种群
ifoptions
(1)==1
Pop=Lb+InversionPop.*(Ub-Lb);%还原Pop
else
Pop=InversionPop;
end
pMutation=pm0+(eranum^3)*(pCross/2-pm0)/(eranum^4);%逐步增大变异率至1/2交叉率
percent=num2str(round(100*eranum/MaxEranum));
waitbar(eranum/MaxEranum,H,['Evolutioncomplete',percent,'%']);
eranum=eranum+1;
end
close(H);
%格式化输出进化结果和解的变化情况
t=1:
MaxEranum;
plot(t,Trace,t,Meanfit);
legend('解的变化','种群的变化');
title('函数优化的遗传算法');
xlabel('进化世代数');
ylabel('每一代最优适应度');
[MaxFval,MaxFvalIn]=max(Trace);
ifoptions
(1)==1|options
(1)==3
X=BestPop(MaxFvalIn,:
);
elseifoptions
(1)==0
X=b2f(BestPop(MaxFvalIn,:
),bounds,bits);
end
holdon;
plot(MaxFvalIn,MaxFval,'*');
text(MaxFvalIn+5,MaxFval,['FMAX='num2str(MaxFval)]);
str1=sprintf('Bestgeneration:
\n%d\n\nBestX:
\n%s\n\nMaxFval\n%f\n',...
MaxFvalIn,num2str(X),MaxFval);
disp(str1);
%-计时
T2=clock;
elapsed_time=T2-T1;
ifelapsed_time(6)<0
elapsed_time(6)=elapsed_time(6)+60;elapsed_time(5)=elapsed_time(5)-1;
end
ifelapsed_time(5)<0
elapsed_time(5)=elapsed_time(5)+60;elapsed_time(4)=elapsed_time(4)-1;
end
str2=sprintf('elapsed_time\n%d(h)%d(m)%.4f(s)',elapsed_time(4),elapsed_time(5),elapsed_time(6));
disp(str2);
%==========================================================================
%遗传操作子程序%
%==========================================================================
%--初始化种群--
%采用浮点编码和二进制Gray编码(为了克服二进制编码的Hamming悬崖缺点)
function[initpop]=InitPop(popsize,bounds,bits,options)
numVars=size(bounds,1);%变量数目
rang=(bounds(:
2)-bounds(:
1))';%变量范围
ifoptions
(1)==1
initpop=zeros(popsize,numVars);
initpop=(ones(popsize,1)*rang).*(rand(popsize,numVars))+(ones(popsize,1)*bounds(:
1)');
elseifoptions
(1)==0
precision=options
(2);%由求解精度确定二进制编码长度
len=sum(bits);
initpop=zeros(popsize,len);%Thewholezeroencodingindividual
fori=2:
popsize-1
pop=round(rand(1,len));
pop=mod(([0pop]+[pop0]),2);
%i=1时,b
(1)=a
(1);i>1时,b(i)=mod(a(i-1)+a(i),2)
%其中原二进制串:
a
(1)a
(2)...a(n),Gray串:
b
(1)b
(2)...b(n)
initpop(i,:
)=pop(1:
end-1);
end
initpop(popsize,:
)=ones(1,len);%Thewholeoneencodingindividual
else
fori=1:
popsize
initpop(i,:
)=randperm(numVars);%为Tsp问题初始化种群
end
end
%--二进制串解码--
function[fval]=b2f(bval,bounds,bits)
%fval-表征各变量的十进制数
%bval-表征各变量的二进制编码串
%bounds-各变量的取值范围
%bits-各变量的二进制编码长度
scale=(bounds(:
2)-bounds(:
1))'./(2.^bits-1);%Therangeofthevariables
numV=size(bounds,1);
cs=[0cumsum(bits)];
fori=1:
numV
a=bval((cs(i)+1):
cs(i+1));
fval(i)=sum(2.^(size(a,2)-1:
-1:
0).*a)*scale(i)+bounds(i,1);
end
%--选择操作--
%采用基于轮盘赌法的非线性排名选择
%各个体成员按适应值从大到小分配选择概率:
%P(i)=(q/1-(1-q)^n)*(1-q)^i,其中P(0)>P
(1)>...>P(n),sum(P(i))=1
function[NewPop]=NonlinearRankSelect(OldPop,fit,bits)
globalmnNewPop
fit=fit';
selectprob=fit/sum(fit);%计算各个体相对适应度(0,1)
q=max(selectprob);%选择最优的概率
x=zeros(m,2);
x(:
1)=[m:
-1:
1]';
[yx(:
2)]=sort(selectprob);
r=q/(1-(1-q)^m);%标准分布基值
newfit(x(:
2))=r*(1-q).^(x(:
1)-1);%生成选择概率
newfit=[0cumsum(newfit)];%计算各选择概率之和
rNums=rand(m,1);
newIn=1;
while(newIn<=m)
NewPop(newIn,:
)=OldPop(length(find(rNums(newIn)>newfit)),:
);
newIn=newIn+1;
end
%--锦标赛选择(含精英选择)--
function[NewPop]=TournamentSelect(OldPop,fit,bits)
globalmnNewPop
num=floor(m./2.^(1:
10));
num(find(num==0))=[];
L=length(num);
a=sum(num);
b=m-a;
PopIn=1;
while(PopIn<=L)
r=unidrnd(m,num(PopIn),2^PopIn);
[LocalMaxfit,In]=max(fit(r),[],2);
SelectIn=r((In-1)*num(PopIn)+[1:
num(PopIn)]');
NewPop(sum(num(1:
PopIn))-num(PopIn)+1:
sum(num(1:
PopIn)),:
)=OldPop(SelectIn,:
);
PopIn=PopIn+1;
r=[];In=[];LocalMaxfit=[];
end
ifb>1
NewPop((sum(num)+1):
(sum(num)+b-1),:
)=OldPop(unidrnd(m,1,b-1),:
);
end
[GlobalMaxfit,I]=max(fit);%保留每一代中最佳个体
NewPop(end,:
)=OldPop(I,:
);
%--交叉操作--
function[NewPop]=CrossOver(OldPop,pCross,opts)
globalmnNewPop
r=rand(1,m);
y1=find(ry2=find(r>=pCross);
len=length(y1);
iflen==1|(len>2&mod(len,2)==1)%如果用来进行交叉的染色体的条数为奇数,将其调整为偶数
y2(length(y2)+1)=y1(len);
y1(len)=[];
end
i=0;
iflength(y1)>=2
ifopts
(1)==1%浮点编码交叉
while(i<=length(y1)-2)
NewPop(y1(i+1),:
)=OldPop(y1(i+1),:
);
NewPop(y1(i+2),:
)=OldPop(y1(i+2),:
);
ifopts
(2)==0&n>1%discretcrossover
Points=sort(unidrnd(n,1,2));
NewPop(y1(i+1),Points
(1):
Points
(2))=OldPop(y1(i+2),Points
(1):
Points
(2));
NewPop(y1(i+2),Points
(1):
Points
(2))=OldPop(y1(i+1),Points
(1):
Points
(2));
elseifopts
(2)==1%arithmeticalcrossover
Points=round(unifrnd(0,pCross,1,n));
CrossPoints=find(Points==1);
r=rand(1,length(CrossPoints));
NewPop(y1(i+1),CrossPoints)=r.*OldPop(y1(i+1),CrossPoints)+(1-r).*OldPop(y1(i+2),CrossPoints);
NewPop(y1(i+2),CrossPoints)=r.*OldPop(y1(i+2),CrossPoints)+(1-r).*OldPop(y1(i+1),CrossPoints);
else%AEArecombination
Points=round(unifrnd(0,pCross,1,n));
CrossPoints=find(Points==1);
v=unidrnd(4,1,2);
NewPop(y1(i+1),CrossPoints)=(floor(10^v
(1)*OldPop(y1(i+1),CrossPoints))+...
10^v
(1)*OldPop(y1(i+2),CrossPoints)-floor(10^v
(1)*OldPop(y1(i+2),CrossPoints)))/10^v
(1);
NewPop(y1(i+2),CrossPoints)=(floor(10^v
(2)*OldPop(y1(i+2),CrossPoints))+...
10^v
(2)*OldPop(y1(i+1),CrossPoints)-floor(10^v
(2)*OldPop(y1(i+1),CrossPoints)))/10^v
(2);
end
i=i+2;
end
elseifopts
(1)==0%二进制编码交叉
while(i<=length(y1)-2)
ifopts
(2)==0
[NewPop(y1(i+1),:
),NewPop(y1(i+2),:
)]=EqualCrossOver(OldPop(y1(i+1),:
),OldPop(y1(i+2),:
));
else
[NewPop(y1(i+1),:
),NewPop(y1(i+2),:
)]=MultiPointCross(OldPop(y1(i+1),:
),OldPop(y1(i+2),:
));
end
i=i+2;
end
else%Tsp问题次序杂交
fori=0:
2:
length(y1)-2
xPoints=sort(unidrnd(n,1,2));
NewPop([y1(i+1)y1(i+2)],xPoints
(1):
xPoints
(2))=OldPop([y1(i+2)y1(i+1)],xPoints
(1):
xPoints
(2));
%NewPop(y1(i+2),xPoints
(1):
xPoints
(2))=OldPop(y1(i+1),xPoints
(1):
xPoints
(2));
temp=[OldPop(y1(i+1),xPoints
(2)+1:
n)OldPop(y1(i+1),1:
xPoints
(2))];
fordel1i=xPoints
(1):
xPoints
(2)
temp(find(temp==OldPop(y1(i+2),del1i)))=[];
end
NewPop(y1(i+1),(xPoints
(2)+1):
n)=temp(1:
(n-xPoints
(2)));
NewPop(y1(i+1),1:
(xPoints
(1)-1))=temp((n-xPoints
(2)+1):
end);
temp=[OldPop(y1(i+2),xPoints
(2)+1:
n)OldPop(y1(i+2),1:
xPoints
(2))];
fordel2i=xPoints
(1):
xPoints
(2)
temp(find(temp==OldPop(y1(i+1),del2i)))=[];
end
NewPop(y1(i+2),(xPoints
(2)+1):
n)=temp(1:
(n-xPoints
(2)));
NewPop(y1(i+2),1:
(xPoints
(1)-1))=temp((n-xPoints
(2)+1):
end);
end
end
end
NewPop(y2