遗传算法基本原理
借鉴物种进化的思想,将欲求解问题编码,把可行解转化为字符串形式。初始化随机产生一个种群,用合理的评价函数对种群进行评估,在此基础上进行选择、交叉、变异的操作。选择算子根据父代中个体适值大小进行选择或淘汰,保证了算法的最优搜索方向。
交叉算子模拟基因重组及随机信息交换,产生更好的1个体,使其在可行域中有效搜索。
变异算子模拟基因突变,保证了算法的全局搜索能力,避免陷入局部最优。
遗传算法基本过程
1.编码
有多种编码方式,一般采用二进制编码
2.解码
目的是为了将不直观的二进制数据串还原成十进制
3.初始种群
利用随机函数产生k位(假设二进制数的最大长度为k)的0、1排列,将该排列数表示一个染色体,每个染色体代表一个初始值
4.选择
根据个体适应值的比例来确定个体的选择概率,是一个随机采用的过程,一般再用轮盘赌算法来进行选择。
这里来举个??栗子来解释轮盘赌算法
个体序号 1 2 3 4 5 6 7 8 9 10
适应度 8 2 17 2 12 11 7 3 7
适应度累计值 8 10 27 34 36 48 59 66
随机数 23 49 76 13 1 27 57
被选中的个体号 3 7 10 3 1 3 7
设个体序号为i ,适应度累计值 为 个体序号1~i的适应度的累加和;
被选中的个体号为 比随机数大的最小的适应度累计值的索引
5.交叉
随机产生一个1到k-1的数(假设二进制数的最大长度为k),个体A、B在该位后的染色体进行交换
6.变异
为了避免在算法迭代后期出现种群过早收敛,随机选取1~k中的某位若其为0将其变为1,若其为1将其变为0
7.个体适应度评估
在设计适应度函数时要考虑:
1.适应度函数能否反映解的优劣
2.该函数是否时单值的和非负的
对于函数优化问题,适应度可取为函数值
8.复制
将子代复制为父代
无约束目标函数的最大值的求解
%target.m % 案例一:无约束目标函数的最大值 % 求解maxf(x)=200*e(−0.05x)*sinx; x∈[−2,2] %主程序:用遗传算法求解y=200*exp(-0.05*x).*sin(x)在[-2 2]区间上的最大值 clc; global BitLength %全局变量,计算如果满足求解精度至少需要编码的长度 global boundsbegin %全局变量,自变量的起始点 global boundsend %全局变量,自变量的终止点 bounds=[-2 2];%一维自变量的取值范围 precision=0.0001;%运算精度 boundsbegin=bounds(:,1); boundsend=bounds(:,2); %计算满足求解精度至少需要多长的染色体 BitLength=ceil(log2((boundsend-boundsbegin)‘./precision)); popsize=50;%初始种群大小 Generationnmax=20;%最大代数 pcrossover=0.9;%交配概率 pmutation=0.09;%变异概率 %产生初始种群 %Round函数返回一个数值,该数值是按照指定的小数位数进行四舍五入运算的结果。可是当保留位跟着的即使是5,有可能进位,也有可能舍去,机会各50%。 population=round(rand(popsize,BitLength));%随机产生初始种群,行为种群大小,列为二进制长度 %计算适应度,返回适应度Fitvalue和累计概率cumsump [Fitvalue,cumsump]=fitnessfun(population);%输入population返回适应度和累计概率 Generation=1; while Generation<Generationnmax+1 for j=1:2:popsize %1对1对的群体进行交叉、变异 %选择操作 seln=selection(population,cumsump);%选择两个个体,返回个体的序号 %交叉操作 scro=crossover(population,seln,pcrossover); scnew(j,:)=scro(1,:);%先两个个体交叉,再分别对两个个体进行变异 scnew(j+1,:)=scro(2,:); %变异操作 在交叉基础上变异 smnew(j,:)=mutation(scnew(j,:),pmutation); smnew(j+1,:)=mutation(scnew(j+1,:),pmutation); end population=smnew;%产生了新的种群 %计算新种群的适应度 [Fitvalue,cumsump]=fitnessfun(population); %记录当前代最好的适应度和平均适应度 [fmax,nmax]=max(Fitvalue);%最好的适应度为fmax(函数值最大),其对应个体为nmax fmean=mean(Fitvalue);%平均适应度 ymax(Generation)=fmax;%每代中最好的适应度 ymean(Generation)=fmean;%每代中的平均适应度 %记录当前代的最佳染色体个体 x=transform2to10(population(nmax,:));%population(nmax,:)为最佳染色体个体,x返回的时其对应的十进制数 %自变量取值范围[-2,2],需要把经过遗传运算的最佳染色体整合到[-2,2]区间 xx=boundsbegin+x*(boundsend-boundsbegin)/(power(2,BitLength)-1); xmax(Generation)=xx; Generation=Generation+1; end Generation=Generation-1; targetfunvalue=targetfun(xmax); [Besttargetfunvalue,nmax]=max(targetfunvalue); Bestpopulation=xmax(nmax); figure(1); hand1=plot(1:Generation,ymax); set(hand1,‘linestyle‘,‘-‘,‘linewidth‘,1.8,‘marker‘,‘*‘,‘markersize‘,6); hold on; hand2=plot(1:Generation,ymean); set(hand2,‘color‘,‘r‘,‘linestyle‘,‘-‘,‘linewidth‘,1.8,‘marker‘,‘h‘,‘markersize‘,6); xlabel(‘进化代数‘);ylabel(‘最大/平均适应度‘); xlim([1 Generationnmax]); legend(‘最大适应度‘,‘平均适应度‘); hold off;
%fitnessfun.m %计算适应度函数 返回适应度 累计概率 function [Fitvalue,cumsump]=fitnessfun(population) global BitLength; global boundsbegin; global boundsend; popsize=size(population,1);%计算个体个数,有popsize个个体 for i=1:popsize x=transform2to10(population(i,:));%将二进制转换为十进制 %译码过程 转化为[-2,2]区间的实数 xx=boundsbegin+x*(boundsend-boundsbegin)/(power(boundsend,BitLength)-1); Fitvalue(i)=targetfun(xx);%计算函数值即适应度,保存在行向量中 end %给适应度函数加上一个大小合理的数以便保证种群适应值为正数 Fitvalue=Fitvalue‘+230;%转化为列向量 %计算选择概率 fsum=sum(Fitvalue); Pperpopulation=Fitvalue/fsum;%适应度归一化,及被复制的概率 %计算累计概率 cumsump(1)=Pperpopulation(1); for i=2:popsize cumsump(i)=cumsump(i-1)+Pperpopulation(i);%求累计概率 end cumsump=cumsump‘;%累计概率 转化为行向量 end
%selection.m %新种群选择操作 选择两个个体,返回个体序号,可能两个序号相同 function seln=selection(population,cumsump)%参数 种群 个体累积概率 %从种群中选择两个个体 所以下面的过程循环两次 for i=1:2 r=rand;%产生一个随机数 %模拟轮盘赌算法 prand=cumsump-r; j=1; while prand(j)<0 j=j+1; end seln(i)=j;%选中个体的序号 end end
%IfCroIfMut.m %判断遗传运算是否需要进行交叉或变异 %mutORcro为动作(交叉、变异)发生的概率 %根据概率mutORcro决定是否进行操作,产生1的概率是mutORcro,产生0的概率为1-mutORcro function pcc=IfCroIfMut(mutORCro) test(1:100)=0;%1*100的行向量 l=round(100*mutORCro); test(1:l)=1; n=round(rand*99)+1; pcc=test(n); end
%crossover.m %新种群交叉操作 function scro=crossover(population,seln,pc)%参数 种群 选择的两个个体 交配的概率 BitLength=size(population,2);%二进制的个数 pcc=IfCroIfMut(pc);%根据交叉概率决定是否进行交叉操作,1则是,0则否 if pcc==1 %进行交叉操作 %获取交换位前面一位的index chb=round(rand*(BitLength-2))+1;%在[1,BitLength-1]范围内随机产生一个交叉位 scro(1,:)=[population(seln(1),1:chb) population(seln(2),chb+1:BitLength)]; scro(2,:)=[population(seln(2),1:chb) population(seln(1),chb+1:BitLength)]; else scro(1,:)=population(seln(1),:); scro(2,:)=population(seln(2),:); end end
%mutation.m %新种群变异操作 %snew为一个个体 function snnew=mutation(snew,pmutation) BitLength=size(snew,2);%获取个体的二进制长度 snnew=snew; pmm=IfCroIfMut(pmutation);%根据变异概率决定是否进行变异操作,1则是,0则否 if pmm==1 chb=round(rand*(BitLength-1))+1;%在[1,BitLength]范围内随机产生一个变异位 snnew(chb)=abs(snew(chb)-1);%0变成1,1变成0 end end
%transform2to10.m将二进制转换为十进制 function x=transform2to10(population) BitLength=size(population,2);%Population的列,即二进制的长度 x=population(BitLength);%x=末位 for i=1:BitLength-1 x=x+population(BitLength-i)*power(2,i); end end
%targetfun.m %对于优化最大值或极大值函数问题,目标函数可以作为适应度函数 function y=targetfun(x) y=200*exp(-0.05*x).*sin(x); end
原文:https://www.cnblogs.com/zuiaimiusi/p/11300604.html