D=code;
N=50; % Tunable
maxgen=50; % Tunable
crossrate=0.5; %Tunable
muterate=0.08; %Tunable
generation=1;
num = length(D);
fatherrand=randint(num,N,3);
score = zeros(maxgen,N);
while generation<=maxgen
ind=randperm(N-2)+2; % 随机配对交叉
A=fatherrand(:,ind(1:(N-2)/2));
B=fatherrand(:,ind((N-2)/2+1:end));
% 多点交叉
rnd=rand(num,(N-2)/2);
ind=rnd tmp=A(ind);
A(ind)=B(ind);
B(ind)=tmp;
% % 两点交叉
% for kk=1:(N-2)/2
% rndtmp=randint(1,1,num)+1;
% tmp=A(1:rndtmp,kk);
% A(1:rndtmp,kk)=B(1:rndtmp,kk);
% B(1:rndtmp,kk)=tmp;
% end
fatherrand=[fatherrand(:,1:2),A,B];
% 变异
rnd=rand(num,N);
ind=rnd [m,n]=size(ind);
tmp=randint(m,n,2)+1;
tmp(:,1:2)=0;
fatherrand=tmp+fatherrand;
fatherrand=mod(fatherrand,3);
% fatherrand(ind)=tmp;
%评价、选择
scoreN=scorefun(fatherrand,D);% 求得N个个体的评价函数
score(generation,:)=scoreN;
[scoreSort,scoreind]=sort(scoreN);
sumscore=cumsum(scoreSort);
sumscore=sumscore./sumscore(end);
childind(1:2)=scoreind(end-1:end);
for k=3:N
tmprnd=rand;
tmpind=tmprnd difind=[0,diff(tmpind)];
if ~any(difind)
difind(1)=1;
end
childind(k)=scoreind(logical(difind));
end
fatherrand=fatherrand(:,childind);
generation=generation+1;
end
% score
maxV=max(score,[],2);
minV=11*300-maxV;
plot(minV,'*');title('各代的目标函数值');
F4=D(:,4);
FF4=F4-fatherrand(:,1);
FF4=max(FF4,1);
D(:,5)=FF4;
save DData D
function D=code
load youhua.mat
% properties F2 and F3
F1=A(:,1);
F2=A(:,2);
F3=A(:,3);
if (max(F2)>1450)||(min(F2)<=900)
error('DATA property F2 exceed it''s range (900,1450]')
end
% get group property F1 of data, according to F2 value
F4=zeros(size(F1));
for ite=11:-1:1
index=find(F2<=900+ite*50);
F4(index)=ite;
end
D=[F1,F2,F3,F4];
function ScoreN=scorefun(fatherrand,D)
F3=D(:,3);
F4=D(:,4);
N=size(fatherrand,2);
FF4=F4*ones(1,N);
FF4rnd=FF4-fatherrand;
FF4rnd=max(FF4rnd,1);
ScoreN=ones(1,N)*300*11;
% 这里有待优化
for k=1:N
FF4k=FF4rnd(:,k);
for ite=1:11
F0index=find(FF4k==ite);
if ~isempty(F0index)
tmpMat=F3(F0index);
tmpSco=sum(tmpMat);
ScoreBin(ite)=mod(tmpSco,300);
end
end
Scorek(k)=sum(ScoreBin);
end
ScoreN=ScoreN-Scorek;
遗传算法实例:
% 下面举例说明遗传算法 %
% 求下列函数的最大值 %
% f(x)=10*sin(5x)+7*cos(4x) x∈[0,10] %
% 将 x 的值用一个10位的二值形式表示为二值问题,一个10位的二值数提供的分辨率是每为 (10-0)/(2^10-1)≈0.01 。 %
% 将变量域 [0,10] 离散化为二值域 [0,1023], x=0+10*b/1023, 其中 b 是 [0,1023] 中的一个二值数。 %
% %
%--------------------------------------------------------------------------------------------------------------%
%--------------------------------------------------------------------------------------------------------------%
% 编程
%-----------------------------------------------
% 2.1初始化(编码)
% initpop.m函数的功能是实现群体的初始化,popsize表示群体的大小,chromlength表示染色体的长度(二值数的长度),
% 长度大小取决于变量的二进制编码的长度(在本例中取10位)。
%遗传算法子程序
%Name: initpop.m
%初始化
function pop=initpop(popsize,chromlength)
pop=round(rand(popsize,chromlength)); % rand随机产生每个单元为 {0,1} 行数为popsize,列数为chromlength的矩阵,
% roud对矩阵的每个单元进行圆整。这样产生的初始种群。
% 2.2 计算目标函数值
% 2.2.1 将二进制数转化为十进制数(1)
%遗传算法子程序
%Name: decodebinary.m
%产生 [2^n 2^(n-1) ... 1] 的行向量,然后求和,将二进制转化为十进制
function pop2=decodebinary(pop)
[px,py]=size(pop); %求pop行和列数
for i=1:py
pop1(:,i)=2.^(py-i).*pop(:,i);
end
pop2=sum(pop1,2); %求pop1的每行之和
% 2.2.2 将二进制编码转化为十进制数(2)
% decodechrom.m函数的功能是将染色体(或二进制编码)转换为十进制,参数spoint表示待解码的二进制串的起始位置
% (对于多个变量而言,如有两个变量,采用20为表示,每个变量为10,则第一个变量从1开始,另一个变量从11开始。本例为1),
% 参数1ength表示所截取的长度(本例为10)。
%遗传算法子程序
%Name: decodechrom.m
%将二进制编码转换成十进制
function pop2=decodechrom(pop,spoint,length)
pop1=pop(:,spoint:spoint+length-1);
pop2=decodebinary(pop1);
% 2.2.3 计算目标函数值
% calobjvalue.m函数的功能是实现目标函数的计算,其公式采用本文示例仿真,可根据不同优化问题予以修改。
%遗传算法子程序
%Name: calobjvalue.m
%实现目标函数的计算
function [objvalue]=calobjvalue(pop)
temp1=decodechrom(pop,1,10); %将pop每行转化成十进制数
x=temp1*10/1023; %将二值域 中的数转化为变量域 的数
objvalue=10*sin(5*x)+7*cos(4*x); %计算目标函数值
% 2.3 计算个体的适应值
%遗传算法子程序
%Name:calfitvalue.m
%计算个体的适应值
function fitvalue=calfitvalue(objvalue)
global Cmin;
Cmin=0;
[px,py]=size(objvalue);
for i=1:px
if objvalue(i)+Cmin>0
temp=Cmin+objvalue(i);
else
temp=0.0;
end
fitvalue(i)=temp;
end
fitvalue=fitvalue';
% 2.4 选择复制
% 选择或复制操作是决定哪些个体可以进入下一代。程序中采用赌轮盘选择法选择,这种方法较易实现。
% 根据方程 pi=fi/∑fi=fi/fsum ,选择步骤:
% 1) 在第 t 代,由(1)式计算 fsum 和 pi
% 2) 产生 {0,1} 的随机数 rand( .),求 s=rand( .)*fsum
% 3) 求 ∑fi≥s 中最小的 k ,则第 k 个个体被选中
% 4) 进行 N 次2)、3)操作,得到 N 个个体,成为第 t=t+1 代种群
%遗传算法子程序
%Name: selection.m
%选择复制
function [newpop]=selection(pop,fitvalue)
totalfit=sum(fitvalue); %求适应值之和
fitvalue=fitvalue/totalfit; %单个个体被选择的概率
fitvalue=cumsum(fitvalue); %如 fitvalue=[1 2 3 4],则 cumsum(fitvalue)=[1 3 6 10]
[px,py]=size(pop);
ms=sort(rand(px,1)); %从小到大排列
fitin=1;
newin=1;
while newin<=px
if(ms(newin)) newin=newin+1; else fitin=fitin+1; end end % 2.5 交叉 % 交叉(crossover),群体中的每个个体之间都以一定的概率 pc 交叉,即两个个体从各自字符串的某一位置 % (一般是随机确定)开始互相交换,这类似生物进化过程中的基因与重组。例如,假设2个父代个体x1,x2为: % x1=0100110 % x2=1010001 % 从每个个体的第3位开始交叉,交又后得到2个新的子代个体y1,y2分别为: % y1=0100001 % y2=1010110 % 这样2个子代个体就分别具有了2个父代个体的某些特征。利用交又我们有可能由父代个体在子代组合成具有更高适合度的个体。 % 事实上交又是遗传算法区别于其它传统优化方法的主要特点之一。 %遗传算法子程序 %Name: crossover.m %交叉 function [newpop]=crossover(pop,pc) [px,py]=size(pop); newpop=ones(size(pop)); for i=1:2:px-1 if(rand newpop(i,:)=[pop(i,1:cpoint),pop(i+1,cpoint+1:py)]; newpop(i+1,:)=[pop(i+1,1:cpoint),pop(i,cpoint+1:py)]; else newpop(i,:)=pop(i); newpop(i+1,:)=pop(i+1); end end % 2.6 变异 % 变异(mutation),基因的突变普遍存在于生物的进化过程中。变异是指父代中的每个个体的每一位都以概率 pm 翻转,即由“1”变为“0”, % 或由“0”变为“1”。遗传算法的变异特性可以使求解过程随机地搜索到解可能存在的整个空间,因此可以在一定程度上求得全局最优解。 %遗传算法子程序 %Name: mutation.m %变异 function [newpop]=mutation(pop,pm) [px,py]=size(pop); newpop=ones(size(pop)); for i=1:px if(rand if mpoint<=0 mpoint=1; end newpop(i)=pop(i); if any(newpop(i,mpoint))==0 newpop(i,mpoint)=1; else newpop(i,mpoint)=0; end else newpop(i)=pop(i); end end % 2.7 求出群体中最大得适应值及其个体 %遗传算法子程序 %Name: best.m %求出群体中适应值最大的值 function [bestindividual,bestfit]=best(pop,fitvalue) [px,py]=size(pop); bestindividual=pop(1,:); bestfit=fitvalue(1); for i=2:px if fitvalue(i)>bestfit bestindividual=pop(i,:); bestfit=fitvalue(i); end end % 2.8 主程序 %遗传算法主程序 %Name:genmain05.m clear clf popsize=20; %群体大小 chromlength=10; %字符串长度(个体长度) pc=0.6; %交叉概率 pm=0.001; %变异概率 pop=initpop(popsize,chromlength); %随机产生初始群体 for i=1:20 %20为迭代次数 [objvalue]=calobjvalue(pop); %计算目标函数 fitvalue=calfitvalue(objvalue); %计算群体中每个个体的适应度 [newpop]=selection(pop,fitvalue); %复制 [newpop]=crossover(pop,pc); %交叉 [newpop]=mutation(pop,pc); %变异 [bestindividual,bestfit]=best(pop,fitvalue); %求出群体中适应值最大的个体及其适应值 y(i)=max(bestfit); n(i)=i; pop5=bestindividual; x(i)=decodechrom(pop5,1,chromlength)*10/1023; pop=newpop; end fplot('10*sin(5*x)+7*cos(4*x)',[0 10]) hold on plot(x,y,'r*') hold off [z index]=max(y); %计算最大值及其位置 x5=x(index)%计算最大值对应的x值 y=z 【问题】求f(x)=x 10*sin(5x) 7*cos(4x)的最大值,其中0<=x<=9 【分析】选择二进制编码,种群中的个体数目为10,二进制编码长度为20,交叉概率为0.95,变异概率为0.08 【程序清单】 %编写目标函数 function[sol,eval]=fitness(sol,options) x=sol(1); eval=x 10*sin(5*x) 7*cos(4*x); %把上述函数存储为fitness.m文件并放在工作目录下 initPop=initializega(10,[0 9],'fitness');%生成初始种群,大小为10 [x endPop,bPop,trace]=ga([0 9],'fitness',[],initPop,[1e-6 1 1],'maxGenTerm',25,'normGeomSelect',... [0.08],['arithXover'],[2],'nonUnifMutation',[2 25 3]) %25次遗传迭代 运算借过为:x = 7.8562 24.8553(当x为7.8562时,f(x)取最大值24.8553) 注:遗传算法一般用来取得近似最优解,而不是最优解。 遗传算法实例2 【问题】在-5<=Xi<=5,i=1,2区间内,求解 f(x1,x2)=-20*exp(-0.2*sqrt(0.5*(x1.^2 x2.^2)))-exp(0.5*(cos(2*pi*x1) cos(2*pi*x2))) 22.71282的最小值。 【分析】种群大小10,最大代数1000,变异率0.1,交叉率0.3 【程序清单】 %源函数的matlab代码 function [eval]=f(sol) numv=size(sol,2); x=sol(1:numv); eval=-20*exp(-0.2*sqrt(sum(x.^2)/numv)))-exp(sum(cos(2*pi*x))/numv) 22.71282; %适应度函数的matlab代码 function [sol,eval]=fitness(sol,options) numv=size(sol,2)-1; x=sol(1:numv); eval=f(x); eval=-eval; %遗传算法的matlab代码 bounds=ones(2,1)*[-5 5]; [p,endPop,bestSols,trace]=ga(bounds,'fitness') 注:前两个文件存储为m文件并放在工作目录下,运行结果为 p = 0.0000 -0.0000 0.0055 大家可以直接绘出f(x)的图形来大概看看f(x)的最值是多少,也可是使用优化函数来验证。matlab命令行执行命令: fplot('x 10*sin(5*x) 7*cos(4*x)',[0,9]) evalops是传递给适应度函数的参数,opts是二进制编码的精度,termops是选择maxGenTerm结束函数时传递个maxGenTerm的参数,即遗传代数。xoverops是传递给交叉函数的参数。mutops是传递给变异函数的参数。 【问题】求f(x)=x+10*sin(5x)+7*cos(4x)的最大值,其中0<=x<=9 【分析】选择二进制编码,种群中的个体数目为10,二进制编码长度为20,交叉概率为0.95,变异概率为0.08 【程序清单】 %编写目标函数 function[sol,eval]=fitness(sol,options) x=sol(1); eval=x+10*sin(5*x)+7*cos(4*x); %把上述函数存储为fitness.m文件并放在工作目录下 initPop=initializega(10,[0 9],'fitness');%生成初始种群,大小为10 [x endPop,bPop,trace]=ga([0 9],'fitness',[],initPop,[1e-6 1 1],'maxGenTerm',25,'normGeomSelect',... [0.08],['arithXover'],[2],'nonUnifMutation',[2 25 3]) %25次遗传迭代 运算借过为:x = 7.8562 24.8553(当x为7.8562时,f(x)取最大值24.8553) 注:遗传算法一般用来取得近似最优解,而不是最优解。 遗传算法实例2 【问题】在-5<=Xi<=5,i=1,2区间内,求解 f(x1,x2)=-20*exp(-0.2*sqrt(0.5*(x1.^2+x2.^2)))-exp(0.5*(cos(2*pi*x1)+cos(2*pi*x2)))+22.71282的最小值。 【分析】种群大小10,最大代数1000,变异率0.1,交叉率0.3 【程序清单】 %源函数的matlab代码 function [eval]=f(sol) numv=size(sol,2); x=sol(1:numv); eval=-20*exp(-0.2*sqrt(sum(x.^2)/numv)))-exp(sum(cos(2*pi*x))/numv)+22.71282; %适应度函数的matlab代码 function [sol,eval]=fitness(sol,options) numv=size(sol,2)-1; x=sol(1:numv); eval=f(x); eval=-eval; %遗传算法的matlab代码 bounds=ones(2,1)*[-5 5]; [p,endPop,bestSols,trace]=ga(bounds,'fitness') 注:前两个文件存储为m文件并放在工作目录下,运行结果为 p = 0.0000 -0.0000 0.0055 大家可以直接绘出f(x)的图形来大概看看f(x)的最值是多少,也可是使用优化函数来验证。matlab命令行执行命令: fplot('x+10*sin(5*x)+7*cos(4*x)',[0,9]) evalops是传递给适应度函数的参数,opts是二进制编码的精度,termops是选择maxGenTerm结束函数时传递个maxGenTerm的参数,即遗传代数。xoverops是传递给交叉函数的参数。mutops是传递给变异函数的参数。 参考资料:不记得了,抱歉 function Main() %定义全局变量 global VariableNum POPSIZE MaxGens PXOVER PMutation VariableNum=3 %变量个数 POPSIZE=50 %种群大小 MaxGens=1000 %种群代数 PXOVER=0.8 %交叉概率 PMutation=0.2 %变异概率 %读取数据文件 load E:\现代优化算法\遗传算法\\bound.txt VarBound=bound(:,1:2); global Pop newPop Pop=zeros(POPSIZE+1,VariableNum); newPop=zeros(POPSIZE+1,VariableNum); %初始化种群 for i=1:POPSIZE for j=1:VariableNum Pop(i,j)=VarBound(j,1)+rand()*(VarBound(j,2)-VarBound(j,1)); end end %计算适应值 fitnessList=zeros(POPSIZE,1); for i=1:POPSIZE fitnessList(i,1)=fitness(Pop(i,1:VariableNum)); end %保存最好值和最坏值 Best=zeros(1,VariableNum+1); Worst=zeros(1,VariableNum+1); maxvalue=max(fitnessList); indexMax=find(fitnessList==maxvalue,1,'first'); Best(1,1:VariableNum)=Pop(indexMax,1:VariableNum); Best(1,VariableNum+1)=maxvalue; minvalue=min(fitnessList); indexMin=find(fitnessList==minvalue,1,'first'); Worst(1,1:VariableNum)=Pop(indexMin,1:VariableNum); Worst(1,VariableNum+1)=minvalue; genetation=1; while genetation sumfit=sum(abs(fitnessList)); relativeFitness=zeros(POPSIZE,1); relativeFitness=abs(fitnessList)/sumfit; for i=2:POPSIZE relativeFitness(i)=relativeFitness(i-1)+relativeFitness(i); end %选择操作 newPop=Select(Pop,relativeFitness); %交叉操作 newPop=Xcross(newPop,VariableNum,PXOVER); %变异操作 newPop=Mutation(newPop,VariableNum,PMutation,VarBound); %计算新种群适应值 for i=1:POPSIZE fitnessList(i,1)=fitness(newPop(i,1:VariableNum)); end %保存最好值和替换最坏值 maxvalue=max(fitnessList); indexMax=find(fitnessList==maxvalue,1,'first'); minvalue=min(fitnessList); indexMin=find(fitnessList==minvalue,1,'first'); if Best Best(1,VariableNum+1)=maxvalue; else newPop(indexMin,1:VariableNum)=Best(1,1:VariableNum); fitnessList(indexMin,1)=Best(1,VariableNum+1); end %用子代替换父代 Pop=newPop; genetation=genetation+1; end Best ========================================================= %选择操作 function newPop=Select(Pop,Rfitness) for i=1:length(Rfitness) r=rand(); index=1; for j=1:length(Rfitness) if r<=Rfitness(j,1) index=j; break; end end newPop(i,:)=Pop(index,:); end ====================================== %交叉操作 function newPop=Xcross(Pop,VariableNUM,CrossRate) point=1; sizePop=length(Pop); for i=0:sizePop/2 Xrate=rand(); if Xrate second_index=round(rand()*(sizePop-2)+1); while first_index==second_index %排除两个个体一样的情况 second_index=round(rand()*(sizePop-2)+1); end if VariableNUM>1 if VariableNUM==2 point=1; else point=round(rand()*(VariableNUM-2)+1); end tempOne=zeros(1,point); tempOne(1,1:point)=Pop(first_index,1:point); Pop(first_index,1:point)=Pop(second_index,1:point); Pop(second_index,1:point)=tempOne(1,1:point); end end end newPop=zeros(size(Pop),1); newPop=Pop; ==================================================== %变异操作 function newPop=Mutation(Pop,VariableNUM,MutationRate,bound) point=1; sizePop=length(Pop); for i=1:sizePop for j=1:VariableNUM Mrate=rand(); if Mrate end end end newPop=zeros(size(Pop),1); newPop=Pop; ================================================= %适应值函数或目标函数 %函数 x1^2-x1*x2+x3 function value=fitness(varargin) n=varargin{1,1}; value=n(1,1)^2-n(1,1)*n(1,2)+n(1,3); 已知n个城市之间的相互距离,现有一个推销员必须遍访这n个城市,并且每个城市 只能访问一次,最后又必须返回出发城市。如何安排他对这些城市的访问次序,可使其 旅行路线的总长度最短? 用图论的术语来说,假设有一个图g=(v,e),其中v是顶点集,e是边集,设d=(dij) 是由顶点i和顶点j之间的距离所组成的距离矩阵,旅行商问题就是求出一条通过所有顶 点且每个顶点只通过一次的具有最短距离的回路。 这个问题可分为对称旅行商问题(dij=dji,,任意i,j=1,2,3,…,n)和非对称旅行商 问题(dij≠dji,,任意i,j=1,2,3,…,n)。 若对于城市v={v1,v2,v3,…,vn}的一个访问顺序为t=(t1,t2,t3,…,ti,…,tn),其中 ti∈v(i=1,2,3,…,n),且记tn+1= t1,则旅行商问题的数学模型为: min l=σd(t(i),t(i+1)) (i=1,…,n) 旅行商问题是一个典型的组合优化问题,并且是一个np难问题,其可能的路径数目 与城市数目n是成指数型增长的,所以一般很难精确地求出其最优解,本文采用遗传算法 求其近似解。 遗传算法: 初始化过程:用v1,v2,v3,…,vn代表所选n个城市。定义整数pop-size作为染色体的个数 ,并且随机产生pop-size个初始染色体,每个染色体为1到18的整数组成的随机序列。 适应度f的计算:对种群中的每个染色体vi,计算其适应度,f=σd(t(i),t(i+1)). 评价函数eval(vi):用来对种群中的每个染色体vi设定一个概率,以使该染色体被选中 的可能性与其种群中其它染色体的适应性成比例,既通过轮盘赌,适应性强的染色体被 选择产生后台的机会要大,设alpha∈(0,1),本文定义基于序的评价函数为eval(vi)=al pha*(1-alpha).^(i-1) 。[随机规划与模糊规划] 选择过程:选择过程是以旋转赌轮pop-size次为基础,每次旋转都为新的种群选择一个 染色体。赌轮是按每个染色体的适应度进行选择染色体的。 step1 、对每个染色体vi,计算累计概率qi,q0=0;qi=σeval(vj) j=1,…,i;i=1, …pop-size. step2、从区间(0,pop-size)中产生一个随机数r; step3、若qi-1 step4、重复step2和step3共pop-size次,这样可以得到pop-size个复制的染色体。 grefenstette编码:由于常规的交叉运算和变异运算会使种群中产生一些无实际意义的 染色体,本文采用grefenstette编码《遗传算法原理及应用》可以避免这种情况的出现 。所谓的grefenstette编码就是用所选队员在未选(不含淘汰)队员中的位置,如: 8 15 2 16 10 7 4 3 11 14 6 12 9 5 18 13 17 1 对应: 8 14 2 13 8 6 3 2 5 7 3 4 3 2 4 2 2 1。 交叉过程:本文采用常规单点交叉。为确定交叉操作的父代,从 到pop-size重复以下过 程:从[0,1]中产生一个随机数r,如果r 将所选的父代两两组队,随机产生一个位置进行交叉,如: 8 14 2 13 8 6 3 2 5 7 3 4 3 2 4 2 2 1 6 12 3 5 6 8 5 6 3 1 8 5 6 3 3 2 1 1 交叉后为: 8 14 2 13 8 6 3 2 5 1 8 5 6 3 3 2 1 1 6 12 3 5 6 8 5 6 3 7 3 4 3 2 4 2 2 1 变异过程:本文采用均匀多点变异。类似交叉操作中选择父代的过程,在r 选择多个染色体vi作为父代。对每一个选择的父代,随机选择多个位置,使其在每位置 按均匀变异(该变异点xk的取值范围为[ukmin,ukmax],产生一个[0,1]中随机数r,该点 变异为x'k=ukmin+r(ukmax-ukmin))操作。如: 8 14 2 13 8 6 3 2 5 7 3 4 3 2 4 2 2 1 变异后: 8 14 2 13 10 6 3 2 2 7 3 4 5 2 4 1 2 1 反grefenstette编码:交叉和变异都是在grefenstette编码之后进行的,为了循环操作 和返回最终结果,必须逆grefenstette编码过程,将编码恢复到自然编码。 循环操作:判断是否满足设定的带数xzome,否,则跳入适应度f的计算;是,结束遗传 操作,跳出。 matlab 代码 distTSP.txt 0 6 18 4 8 7 0 17 3 7 4 4 0 4 5 20 19 24 0 22 8 8 16 6 0 %GATSP.m function gatsp1() clear; load distTSP.txt; distance=distTSP; N=5; ngen=100; ngpool=10; %ngen=input('# of generations to evolve = '); %ngpool=input('# of chromosoms in the gene pool = '); % size of genepool gpool=zeros(ngpool,N+1); % gene pool for i=1:ngpool, % intialize gene pool gpool(i,:)=[1 randomize([2:N]')' 1]; for j=1:i-1 while gpool(i,:)==gpool(j,:) gpool(i,:)=[1 randomize([2:N]')' 1]; end end end costmin=100000; tourmin=zeros(1,N); cost=zeros(1,ngpool); increase=1;resultincrease=1; for i=1:ngpool, cost(i)=sum(diag(distance(gpool(i,:)',rshift(gpool(i,:))'))); end % record current best solution [costmin,idx]=min(cost); tourmin=gpool(idx,:); disp([num2str(increase) 'minmum trip length = ' num2str(costmin)]) costminold2=200000;costminold1=150000;resultcost=100000; tourminold2=zeros(1,N); tourminold1=zeros(1,N); resulttour=zeros(1,N); while (abs(costminold2-costminold1) ;100)&(abs(costminold1-costmin) ;100)&(increase ;500) costminold2=costminold1; tourminold2=tourminold1; costminold1=costmin;tourminold1=tourmin; increase=increase+1; if resultcost>costmin resultcost=costmin; resulttour=tourmin; resultincrease=increase-1; end for i=1:ngpool, cost(i)=sum(diag(distance(gpool(i,:)',rshift(gpool(i,:))'))); end % record current best solution [costmin,idx]=min(cost); tourmin=gpool(idx,:); %============== % copy gens in th gpool according to the probility ratio % >1.1 copy twice % >=0.9 copy once % ;0.9 remove [csort,ridx]=sort(cost); % sort from small to big. csum=sum(csort); caverage=csum/ngpool; cprobilities=caverage./csort; copynumbers=0;removenumbers=0; for i=1:ngpool, if cprobilities(i) >1.1 copynumbers=copynumbers+1; end if cprobilities(i) <0.9 removenumbers=removenumbers+1; end end copygpool=min(copynumbers,removenumbers); for i=1:copygpool for j=ngpool:-1:2*i+2 gpool(j,:)=gpool(j-1,:); end gpool(2*i+1,:)=gpool(i,:); end if copygpool==0 gpool(ngpool,:)=gpool(1,:); end %========= %when genaration is more than 50,or the patterns in a couple are too close,do mutation for i=1:ngpool/2 % sameidx=[gpool(2*i-1,:)==gpool(2*i,:)]; diffidx=find(sameidx==0); if length(diffidx)<=2 gpool(2*i,:)=[1 randomize([2:12]')' 1]; end end %=========== %cross gens in couples for i=1:ngpool/2 [gpool(2*i-1,:),gpool(2*i,:)]=crossgens(gpool(2*i-1,:),gpool(2*i,:)); end for i=1:ngpool, cost(i)=sum(diag(distance(gpool(i,:)',rshift(gpool(i,:))'))); end % record current best solution [costmin,idx]=min(cost); tourmin=gpool(idx,:); disp([num2str(increase) 'minmum trip length = ' num2str(costmin)]) end disp(['cost function evaluation: ' int2str(increase) ' times!']) disp(['n:' int2str(resultincrease)]) disp(['minmum trip length = ' num2str(resultcost)]) disp('optimum tour = ') disp(num2str(resulttour)) %==================================================== function B=randomize(A,rowcol) % Usage: B=randomize(A,rowcol) % randomize row orders or column orders of A matrix % rowcol: if =0 or omitted, row order (default) % if = 1, column order rand('state',sum(100*clock)) if nargin == 1, rowcol=0; end if rowcol==0, [m,n]=size(A); p=rand(m,1); [p1,I]=sort(p); B=A(I,:); elseif rowcol==1, Ap=A'; [m,n]=size(Ap); p=rand(m,1); [p1,I]=sort(p); B=Ap(I,:)'; end %===================================================== function y=rshift(x,dir) % Usage: y=rshift(x,dir) % rotate x vector to right (down) by 1 if dir = 0 (default) % or rotate x to left (up) by 1 if dir = 1 if nargin ;2, dir=0; end [m,n]=size(x); if m>1, if n == 1, col=1; elseif n>1, error('x must be a vector! break'); end % x is a column vectorelseif m == 1, if n == 1, y=x; return elseif n>1, col=0; % x is a row vector endend if dir==1, % rotate left or up if col==0, % row vector, rotate left y = [x(2:n) x(1)]; elseif col==1, y = [x(2:n); x(1)]; % rotate up end elseif dir==0, % default rotate right or down if col==0, y = [x(n) x(1:n-1)]; elseif col==1 % column vector y = [x(n); x(1:n-1)]; end end %================================================== function [L1,L2]=crossgens(X1,X2) % Usage:[L1,L2]=crossgens(X1,X2) s=randomize([2:12]')'; n1=min(s(1),s(11));n2=max(s(1),s(11)); X3=X1;X4=X2; for i=n1:n2, for j=1:13, if X2(i)==X3(j), X3(j)=0; end if X1(i)==X4(j), X4(j)=0; end end end j=13;k=13; for i=12:-1:2, if X3(i)~=0, j=j-1; t=X3(j);X3(j)=X3(i);X3(i)=t; end if X4(i)~=0, k=k-1; t=X4(k);X4(k)=X4(i);X4(i)=t; end end for i=n1:n2 X3(2+i-n1)=X2(i); X4(2+i-n1)=X1(i); end L1=X3;L2=X4; %======================= 由于BP网络的权值优化是一个无约束优化问题,而且权值要采用实数编码,所以直接利用Matlab遗传算法工具箱。以下贴出的代码是为一个19输入变量,1个输出变量情况下的非线性回归而设计的,如果要应用于其它情况,只需改动编解码函数即可。 程序一:GA训练BP权值的主函数 function net=GABPNET(XX,YY) %-------------------------------------------------------------------------- % GABPNET.m % 使用遗传算法对BP网络权值阈值进行优化,再用BP算法训练网络 %-------------------------------------------------------------------------- %数据归一化预处理 nntwarn off XX=premnmx(XX); YY=premnmx(YY); %创建网络 net=newff(minmax(XX),[19,25,1],{'tansig','tansig','purelin'},'trainlm'); %下面使用遗传算法对网络进行优化 P=XX; T=YY; R=size(P,1); S2=size(T,1); S1=25;%隐含层节点数 S=R*S1+S1*S2+S1+S2;%遗传算法编码长度 aa=ones(S,1)*[-1,1]; popu=50;%种群规模 initPpp=initializega(popu,aa,'gabpEval');%初始化种群 gen=100;%遗传代数 %下面调用gaot工具箱,其中目标函数定义为gabpEval [x,endPop,bPop,trace]=ga(aa,'gabpEval',[],initPpp,[1e-6 1 1],'maxGenTerm',gen,... 'normGeomSelect',[0.09],['arithXover'],[2],'nonUnifMutation',[2 gen 3]); %绘收敛曲线图 figure(1) plot(trace(:,1),1./trace(:,3),'r-'); hold on plot(trace(:,1),1./trace(:,2),'b-'); xlabel('Generation'); ylabel('Sum-Squared Error'); figure(2) plot(trace(:,1),trace(:,3),'r-'); hold on plot(trace(:,1),trace(:,2),'b-'); xlabel('Generation'); ylabel('Fittness'); %下面将初步得到的权值矩阵赋给尚未开始训练的BP网络 [W1,B1,W2,B2,P,T,A1,A2,SE,val]=gadecod(x); net.LW{2,1}=W1; net.LW{3,2}=W2; net.b{2,1}=B1; net.b{3,1}=B2; XX=P; YY=T; %设置训练参数 net.trainParam.show=1; net.trainParam.lr=1; net.trainParam.epochs=50; net.trainParam.goal=0.001; %训练网络 net=train(net,XX,YY); 程序二:适应值函数 function [sol, val] = gabpEval(sol,options) % val - the fittness of this individual % sol - the individual, returned to allow for Lamarckian evolution % options - [current_generation] load data2 nntwarn off XX=premnmx(XX); YY=premnmx(YY); P=XX; T=YY; R=size(P,1); S2=size(T,1); S1=25;%隐含层节点数 S=R*S1+S1*S2+S1+S2;%遗传算法编码长度 for i=1:S, x(i)=sol(i); end; [W1, B1, W2, B2, P, T, A1, A2, SE, val]=gadecod(x); 程序三:编解码函数 function [W1, B1, W2, B2, P, T, A1, A2, SE, val]=gadecod(x) load data2 nntwarn off XX=premnmx(XX); YY=premnmx(YY); P=XX; T=YY; R=size(P,1); S2=size(T,1); S1=25;%隐含层节点数 S=R*S1+S1*S2+S1+S2;%遗传算法编码长度 % 前R*S1个编码为W1 for i=1:S1, for k=1:R, W1(i,k)=x(R*(i-1)+k); end end % 接着的S1*S2个编码(即第R*S1个后的编码)为W2 for i=1:S2, for k=1:S1, W2(i,k)=x(S1*(i-1)+k+R*S1); end end % 接着的S1个编码(即第R*S1+S1*S2个后的编码)为B1 for i=1:S1, B1(i,1)=x((R*S1+S1*S2)+i); end % 接着的S2个编码(即第R*S1+S1*S2+S1个后的编码)为B2 for i=1:S2, B2(i,1)=x((R*S1+S1*S2+S1)+i); end % 计算S1与S2层的输出 A1=tansig(W1*P,B1); A2=purelin(W2*A1,B2); % 计算误差平方和 SE=sumsqr(T-A2); val=1/SE; % 遗传算法的适应值 文章引用自: