?? fmax_ga.m
字號(hào):
function [X,MaxFval,BestPop,Trace]=fmax_ga(FUN,bounds,MaxEranum,PopSize,options,pCross,pMutation,pInversion)
% [X,MaxFval,BestPop,Trace]=fga(FUN,bounds,MaxEranum,PopSize,options,pCross,pMutation,pInversion)
% Finds a maximum of a function of several variables.
% fga solves problems of the form:
% max F(X) subject to: LB <= X <= UB
% X - 最優(yōu)解
% MaxFval - 最大函數(shù)值
% BestPop - 最優(yōu)的群體即為最優(yōu)的染色體群
% Trace - 每代最佳個(gè)體所對(duì)應(yīng)的目標(biāo)函數(shù)值
% FUN - 目標(biāo)函數(shù)
% bounds - 自變量范圍
% MaxEranum - 種群的代數(shù),取50--500(默認(rèn)200)
% PopSize - 每一代種群的規(guī)模;此可取20--100(默認(rèn)50)
% pCross - 交叉概率,一般取0.5--0.85之間較好(默認(rèn)0.8)
% pMutation - 初始變異概率,一般取0.05-0.2之間較好(默認(rèn)0.1)
% pInversion - 倒位概率,一般取0.05-0.3之間較好(默認(rèn)0.2)
% options - 1*2矩陣,options(1)=0二進(jìn)制編碼,option(1)=1(默認(rèn))十進(jìn)制編碼,option(2)設(shè)定求解精度(默認(rèn)1e-4)
T1=clock;
if nargin<2, error('FMAXGA requires at least three input arguments'); end
if nargin==2, MaxEranum=200;PopSize=50;options=[1 1e-4];pCross=0.85;pMutation=0.1;pInversion=0.25;end
if nargin==3, PopSize=50;options=[1 1e-4];pCross=0.85;pMutation=0.1;pInversion=0.25;end
if nargin==4, options=[1 1e-4];pCross=0.85;pMutation=0.1;pInversion=0.25;end
if nargin==5, pCross=0.85;pMutation=0.1;pInversion=0.25;end
if nargin==6, pMutation=0.1;pInversion=0.25;end
if nargin==7, pInversion=0.25;end
if (options(1)==0|options(1)==1)&find((bounds(:,1)-bounds(:,2))>0)
error('數(shù)據(jù)輸入錯(cuò)誤,請(qǐng)重新輸入:');
end
global m n NewPop children1 children2 VarNum
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);
Trace = zeros(1,MaxEranum);
Lb = ones(PopSize,1)*bounds(:,1)';
Ub = ones(PopSize,1)*bounds(:,2)';
OptsCrossOver = [ones(1,MaxEranum)*options(1);...
round(unidrnd(2*(MaxEranum-[1:MaxEranum]))/MaxEranum)]';
OptsMutation = [ones(1,MaxEranum)*options(1);unidrnd(7,1,MaxEranum)]';
eranum = 1;
while(eranum<=MaxEranum)
for j=1:m
if options(1)==1
fit(j)=feval(FUN,Pop(j,:));
elseif options(1)==0
fit(j)=feval(FUN,(b2f(Pop(j,:),bounds,bits)));
else
fit(j)=-feval(FUN,Pop(j,:),D);
end
end
[Maxfit,fitIn]=max(fit);
BestPop(eranum,:)=Pop(fitIn,:);
Trace(eranum)=Maxfit;
if options(1)==1
Pop=(Pop-Lb)./(Ub-Lb);
end
switch round(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);
if options(1)==1
Pop=Lb+InversionPop.*(Ub-Lb);
else
Pop=InversionPop;
end
pMutation=pm0+(eranum^3)*(pCross/4-pm0)/(eranum^3);
eranum=eranum+1;
end
t=1:MaxEranum;
plot(t,Trace);
title('函數(shù)優(yōu)化的遺傳算法');
xlabel('進(jìn)化世代數(shù)');
ylabel('每一代最優(yōu)適應(yīng)度');
[MaxFval,MaxFvalIn]=max(Trace);
if options(1)==1|options(1)==3
X=BestPop(MaxFvalIn,:);
elseif options(1)==0
X=b2f(BestPop(MaxFvalIn,:),bounds,bits);
end
%X,MaxFval
hold on;
plot(MaxFvalIn,MaxFval,'*');
text(MaxFvalIn+5,MaxFval,['FMAX=' num2str(MaxFval)]);
str1=sprintf('進(jìn)化到 %d 代 ,自變量為 %s 時(shí),得最優(yōu)值 %f\n對(duì)應(yīng)個(gè)體是:%s',...
MaxFvalIn,num2str(X),MaxFval,num2str(BestPop(MaxFvalIn,:)));
disp(str1);
T2=clock;
elapsed_time=T2-T1;
if elapsed_time(6)<0
elapsed_time(6)=elapsed_time(6)+60; elapsed_time(5)=elapsed_time(5)-1;
end
if elapsed_time(5)<0
elapsed_time(5)=elapsed_time(5)+60;elapsed_time(4)=elapsed_time(4)-1;
end
str2=sprintf('程序運(yùn)行耗時(shí) %d 小時(shí) %d 分鐘 %.4f 秒',elapsed_time(4),elapsed_time(5),elapsed_time(6));
disp(str2);
function [initpop]=InitPop(popsize,bounds,bits,options)
numVars=size(bounds,1);
rang=(bounds(:,2)-bounds(:,1))';
if options(1)==1
initpop=zeros(popsize,numVars);
initpop=(ones(popsize,1)*rang).*(rand(popsize,numVars))+(ones(popsize,1)*bounds(:,1)');
elseif options(1)==0
precision=options(2);
len=sum(bits);
initpop=zeros(popsize,len);
for i=2:popsize-1
pop=round(rand(1,len));
pop=mod(([0 pop]+[pop 0]),2);
initpop(i,:)=pop(1:end-1);
end
initpop(popsize,:)=ones(1,len);
else
for i=1:popsize
initpop(i,:)=randperm(numVars);
end
end
function [fval] = b2f(bval,bounds,bits)
scale=(bounds(:,2)-bounds(:,1))'./(2.^bits-1);
numV=size(bounds,1);
cs=[0 cumsum(bits)];
for i=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
function [NewPop]=NonlinearRankSelect(OldPop,fit,bits)
global m n NewPop
fit=fit';
selectprob=fit/sum(fit);
q=max(selectprob);
x=zeros(m,2);
x(:,1)=[m:-1:1]';
[y x(:,2)]=sort(selectprob);
r=q/(1-(1-q)^m);
newfit(x(:,2))=r*(1-q).^(x(:,1)-1);
newfit=[0 cumsum(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)
global m n NewPop
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
if b>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)
global m n NewPop
r=rand(1,m);
y1=find(r<pCross);
y2=find(r>=pCross);
len=length(y1);
if len==1|(len>2&mod(len,2)==1)
y2(length(y2)+1)=y1(len);
y1(len)=[];
end
i=0;
if length(y1)>=2
if opts(1)==1
while(i<=length(y1)-2)
NewPop(y1(i+1),:)=OldPop(y1(i+1),:);
NewPop(y1(i+2),:)=OldPop(y1(i+2),:);
if opts(2)==0&n>1
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));
elseif opts(2)==1
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
Points=round(unifrnd(0,pCross,1,n));
CrossPoints=find(Points==1);
v=unidrnd(10,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
elseif opts(1)==0
while(i<=length(y1)-2)
if opts(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
end
end
NewPop(y2,:)=OldPop(y2,:);
function [children1,children2]=EqualCrossOver(parent1,parent2)
global n children1 children2
hidecode=round(rand(1,n));
crossposition=find(hidecode==1);
holdposition=find(hidecode==0);
children1(crossposition)=parent1(crossposition);
children1(holdposition)=parent2(holdposition);
children2(crossposition)=parent2(crossposition);
children2(holdposition)=parent1(holdposition);
function [Children1,Children2]=MultiPointCross(Parent1,Parent2)
global n Children1 Children2 VarNum
Children1=Parent1;
Children2=Parent2;
Points=sort(unidrnd(n,1,2*VarNum));
for i=1:VarNum
Children1(Points(2*i-1):Points(2*i))=Parent2(Points(2*i-1):Points(2*i));
Children2(Points(2*i-1):Points(2*i))=Parent1(Points(2*i-1):Points(2*i));
end
function [NewPop]=Mutation(OldPop,fit,pMutation,VarNum,opts)
global m n NewPop
NewPop=OldPop;
r=rand(1,m);
MutIn=find(r<=pMutation);
L=length(MutIn);
i=1;
if opts(1)==1
maxfit=max(fit);
upfit=maxfit+0.06*abs(maxfit);
if opts(2)==6
while(i<=L)
Point=unidrnd(n);
if round(rand)
NewPop(MutIn(i),Point)=OldPop(MutIn(i),Point)*(1-rand);
else
NewPop(MutIn(i),Point)=OldPop(MutIn(i),Point)+(1-OldPop(MutIn(i),Point))*rand;
end
i=i+1;
end
elseif opts(2)==1|opts(2)==4
while(i<=L)
Point=unidrnd(n);
T=(1-fit(MutIn(i))/upfit)^2;
temp=rand^T;
q=abs(1-rand^T);
p=OldPop(MutIn(i),Point)*(1-q);
if unidrnd(2)==1
NewPop(MutIn(i),Point)=p+q;
else
NewPop(MutIn(i),Point)=p;
end
i=i+1;
end
elseif opts(2)==2|opts(2)==3|opts(2)==5
while(i<=L)
Point=unidrnd(n);
T=(1-abs(upfit-fit(MutIn(i)))/upfit)^2;
v=1+unidrnd(1+ceil(10*T));
q=mod(floor(OldPop(MutIn(i),Point)*10^v),10);
NewPop(MutIn(i),Point)=OldPop(MutIn(i),Point)-(q-unidrnd(9))/10^v;
i=i+1;
end
else
while(i<=L)
point=unidrnd(n);
a=round(rand(1,16));
if round(rand)
delt=0.1*sum(a.*2.^(0:-1:-15));
else
delt=-0.1*sum(a.*2.^(0:-1:-15));
end
NewPop(MutIn(i),point)=OldPop(MutIn(i),point)+delt;
if NewPop(MutIn(i),point)>=1|NewPop(MutIn(i),point)<=0
NewPop(MutIn(i),point)=(NewPop(MutIn(i),point)+0.2)/1.4;
end
i=i+1;
end
end
else
if L>=1
while i<=L
k=unidrnd(n,1,VarNum);
for j=1:length(k)
if NewPop(MutIn(i),k(j))==1
NewPop(MutIn(i),k(j))=0;
else
NewPop(MutIn(i),k(j))=1;
end
end
i=i+1;
end
end
end
function [NewPop]=Inversion(OldPop,pInversion)
global m n NewPop
NewPop=OldPop;
r=rand(1,m);
PopIn=find(r<=pInversion);
len=length(PopIn);
i=1;
if len>=1
while(i<=len)
d=sort(unidrnd(n,1,2));
NewPop(PopIn(i),d(1):d(2))=OldPop(PopIn(i),d(2):-1:d(1));
i=i+1;
end
end
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -