首页 > 编程语言 > 详细

遗传算法

时间:2019-08-05 00:33:44      阅读:221      评论:0      收藏:0      [点我收藏+]

遗传算法基本原理

借鉴物种进化的思想,将欲求解问题编码,把可行解转化为字符串形式。初始化随机产生一个种群,用合理的评价函数对种群进行评估,在此基础上进行选择、交叉、变异的操作。选择算子根据父代中个体适值大小进行选择或淘汰,保证了算法的最优搜索方向。

交叉算子模拟基因重组及随机信息交换,产生更好的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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!