遗传算法Matlab源代码

更新时间:2023-06-10 06:54:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

完整可以运行的数值优化遗传算法源代码

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)

% Finds a maximum of a function of several variables.

% fga solves problems of the form:

% max F(X) subject to: 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;

%检验初始参数

if nargin<2, error('FMAXGA requires at least three input arguments'); end

if nargin==2, MaxEranum=150;PopSize=100;options=[1 1e-4];pCross=0.85;pMutation=0.1;pInversion=0.25;end

if nargin==3, PopSize=100;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('数据输入错误,请重新输入:');

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);%分配初始解空间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)]';

if options(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,'Please wait...');

while(eranum<=MaxEranum)

for j=1:m

if options(1)==1

%eval(['[fit(j)]=' FUN '(Pop(j,:));']);%但执行字符串速度比直接计算函数值慢

fit(j)=feval(FUN,Pop(j,:));%计算适应度

elseif options(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;

if options(1)==1

Pop=(Pop-Lb)./(Ub-Lb);%将定义域映射到[0,1]:[Lb,Ub]-->[0,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);%还原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,['Evolution complete ',percent,'%']);

eranum=eranum+1;

end

close(H);

% 格式化输出进化结果和解的变化情况

t=1:MaxEranum;

plot(t,Trace,t,Meanfit);

legend('解的变化','种群的变化');

title('函数优化的遗传算法');

xlabel('进化世代数');

ylabel('每一代最优适应度');

[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

hold on;

plot(MaxFvalIn,MaxFval,'*');

text(MaxFvalIn+5,MaxFval,['FMAX=' num2str(MaxFval)]);

str1=sprintf(' Best generation:\n %d\n\n Best X:\n %s\n\n MaxFval\n %f\n',...

MaxFvalIn,num2str(X),MaxFval);

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('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))';%变量范围

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);%The whole zero encoding individual

for i=2:popsize-1

pop=round(rand(1,len));

pop=mod(([0 pop]+[pop 0]),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);%The whole one encoding individual

else

for i=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); %The range of the variables

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

% -- 选择操作 --

完整可以运行的数值优化遗传算法源代码

% 采用基于轮盘赌法的非线性排名选择

% 各个体成员按适应值从大到小分配选择概率:

% 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)

global m n NewPop

fit=fit';

selectprob=fit/sum(fit);%计算各个体相对适应度(0,1)

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%discret crossover

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%arithmetical crossover

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 %AEA recombination

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

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

else %Tsp问题次序杂交

for i=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))];

for del1i=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))];

for del2i=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,:)=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);%掩码为1,父1为子1提供基因

children1(holdposition)=parent2(holdposition);%掩码为0,父2为子1提供基因

children2(crossposition)=parent2(crossposition);%掩码为1,父2为子2提供基因

children2(holdposition)=parent1(holdposition);%掩码为0,父1为子2提供基因

% -二进制串多点交叉算子

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.05*abs(maxfit);

if opts(2)==1|opts(2)==3

while(i<=L)%自适应变异(自增或自减)

Point=unidrnd(n);

T=(1-fit(MutIn(i))/upfit)^2;

q=abs(1-rand^T);

%if q>1%按严格数学推理来说,这段程序是不能缺少的

% q=1

%end

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)==4%AEA变异(任意变量的某一位变异)

while(i<=L)

Point=unidrnd(n);

T=(1-abs(upfit-fit(MutIn(i)))/upfit)^2;

v=1+unidrnd(1+ceil(10*T));

%v=1+unidrnd(5+ceil(10*eranum/MaxEranum));

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);

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

end

elseif opts(1)==0%二进制串变异

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

else%Tsp变异

if opts(2)==1|opts(2)==2|opts(2)==3|opts(2)==4

numMut=ceil(pMutation*m);

r=unidrnd(m,numMut,2);

[LocalMinfit,In]=min(fit(r),[],2);

SelectIn=r((In-1)*numMut+[1:numMut]');

while(i<=numMut)

mPoints=sort(unidrnd(n,1,2));

if mPoints(1)~=mPoints(2)

NewPop(SelectIn(i),1:mPoints(1)-1)=OldPop(SelectIn(i),1:mPoints(1)-1);

NewPop(SelectIn(i),mPoints(1):mPoints(2)-1)=OldPop(SelectIn(i),mPoints(1)+1:mPoints(2)); NewPop(SelectIn(i),mPoints(2))=OldPop(SelectIn(i),mPoints(1));

NewPop(SelectIn(i),mPoints(2)+1:n)=OldPop(SelectIn(i),mPoints(2)+1:n);

else

NewPop(SelectIn(i),:)=OldPop(SelectIn(i),:);

end

i=i+1;

end

else

r=rand(1,m);

MutIn=find(r<=pMutation);

L=length(MutIn);

while i<=L

mPoints=sort(unidrnd(n,1,2));

rIn=randperm(mPoints(2)-mPoints(1)+1);

NewPop(MutIn(i),mPoints(1):mPoints(2))=OldPop(MutIn(i),mPoints(1)+rIn-1);

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

本文来源:https://www.bwwdw.com/article/dut1.html

Top