当前位置: 代码迷 >> 综合 >> 遗传算法(GA)_学习笔记(1.2) (第一式完结)
  详细解决方案

遗传算法(GA)_学习笔记(1.2) (第一式完结)

热度:19   发布时间:2023-12-03 01:04:18.0

今天来写1.1没写完的step3及后续~~~

Step3:这里执行的是交叉操作

交叉操作很简单,依据设定的交叉概率,判断是否进行交叉

遗传步骤就是将两条染色体上同一位置处的基因进行交换,如下图所示:

1

0

1

1

0

1

0

1

0

0

A

1

1

0

1

0

1

1

0

1

1

B

1

1

0

1

0

1

1

0

1

1

A*

1

0

1

1

0

1

0

1

0

0

B*

这里我们将A、B两条染色体上的10个基因全部进行交叉得到A*、B*两条新染色体

显然就是0-1对调,这里也体现了二进制编码基因的简便优越性

咱们直接上代码看看怎么弄!

%%%%%%%%基于概率的交叉操作%%%%%%%%%%%%%%for i=1:2:Npp=rand; %p为0-1之间的一个随机数if p<Pc   %如果随机概率小于于设定的交叉概率,进行交叉q=randi([0,1],1,L);  %令q为由0/1随机生成的1*20的矩阵for j=1:L   if q(j)==1%下面这是很简单的复制转换语句temp=newf(i+1,j);newf(i+1,j)=newf(i,j);newf(i,j)=temp;endend	endend

这里值得一提的是“ q=randi([0,1],1,L);  %令q为由0/1随机生成的1*20的矩阵”这条语句的存在,这里是新随机生成了一个染色体为1*20的矩阵(上篇博客说了,L=20,是二进制编码长度)

这个新随机的单独的染色体是起到了一个参考作用,原本的50(Np=50)条染色体被分成了两两一组,交叉在组内进行,那么哪些位置上进行交叉操作,就是这个新随机生成的染色体要起的作用

其实完全可以用生成一个1-20的随机数,在20个位置上进行随机选择,就是这个意思

这里交叉操作就结束了

Step4:这里进行变异操作

这个变异咱们简单理解,就是染色体某个位置上的基因突变成了另一种等位基因

如图所示:A染色体上2号位置基因突变就是由0换成了等位的1,其余保持不变

1

0

1

1

0

1

0

1

0

0

A

1

1

1

1

0

1

0

1

0

0

A*

可见变异的概率非常小,通常取0.001-0.1

这里我们因为有强大的语言,只需要随机确定某一个染色体和某一个基因位置对其数值使用not非逻辑,那么就可以实现0-1对调,这也是二进制编码的好处,因为只有0-1两个量。

这里变异是小操作,所以执行的次数还是少的,有相当的限制

代码如下:

%%%%%%%%%%%%基于概率的变异操作%%%%%%%%%i =1;while i <= round(Np*Pm)      %四舍五入NP*Pm的值即i<=5h = randi(Np);            %随机生成一个1-50的整数,即随机选择一个要变异的染色体for j = 1:round(L*Pm)  g = randi(L); %随机生成一个1-20的整数,即随机选择一个要变异的基因位置数newf(h,g) = ~newf(h,g);  %help ~not - 计算逻辑 not  此 MATLAB 函数 返回与 A 大小相同的逻辑数组。如果 A 中元素为零值,则数组中对应元素为逻 辑值 1 (true) 值;如果 A 中元素为非零值,则数组中对应元素为逻辑值 0 (false)。endi = i+1;endf = newf;f(1,:) =fbest;      %将第i代最优的染色体保存在新种群中value(generation) = Fitvaluemax;       %历代最优适应度
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end

这里变异操作就结束了

Step5:最后进行绘图,展示结果

这里就会很明显的感受到目标函数和适应度函数的映射关系,其实就是拿过来用的,具体绘图用的不是原来的描点法,而是用遗传进化代替。

%%%%%%%%%%%%%%%%%绘图%%%%%%%%%%%
xbest;
figure
plot(value)
xlabel('迭代次数');
ylabel('目标函数值');
title('适应度进化曲线');
%%%%%%%%%%%%适应度函数的调用%%%%%%%%%%%%%%
function result = func(x)
Fitvalue = x+10*sin(5*x)+7*cos(4*x);
result = Fitvalue;
end

结果图对比,一个是遗传进化图,一个是计算机描点法通用作图

 最后生成的具体极大值大约都是24.86,可能第二个图看起来像是贴近25了,其实不是,matlab用鼠标放上去会显示具体数值的确实是24.8左右

这里就可以看出遗传算法还是有非常强的求解能力的

下面是完整代码和详细注释,Ctrl+C\V可以直接运行出结果:(试了很多遍,嘻嘻~~)

%%%%%%%%%初始化参数%%%%%%%%
Np=50;%种群数量
L=20;%二进制编码长度
Pc=0.8;%交叉概率
Pm=0.1;%变异概率
G=100;%最大进化代数
Xmax=10;%自变量取值上限
Xmin=0;%自变量取值下限
f=randi([0,1],Np,L);  %随机生成初始化种群,Np*L的矩阵%%%%%%%%%%遗传循环%%%%%%%%%%%
for generation=1:G
%%%%%将二进制解码成十进制%%%%%for i=1:NpA=f(i,:);   %A为f矩阵的第i行m=0;for j=1:Lm=A(j)*2^(j-1)+m;endX(i)=Xmin+(Xmax-Xmin)*m/(2^L-1);  %第i个染色体的表现型数值Fitvalue(i)=func(X(i));  %由目标函数映射的初始适应度数值大小endFitvaluemax=max(Fitvalue);  %找出第i代中初始适应度函数最大值Fitvaluemin=min(Fitvalue);   %找出第i代中初始适应度函数最小值location=find(Fitvalue==Fitvaluemax);   %找到染色体适应度函数最大值所在的位置是第几行并返回给locationfbest=f(location(1,1),:);  %location是个行向量,表示在f矩阵中适应度最大值所在行的整个染色体,记为第i代最优个体xbest=X(location(1,1));   %这个第i代中最优个体的表现型数值大小Fitvalue=(Fitvalue-Fitvaluemin)/(Fitvaluemax-Fitvaluemin);  %将初始适应度函数值进行归一化操作
%%%%%%%%%%%%%基于轮盘赌的选择操作%%%%%%%%%%%%%%%%%%sum_Fitvalue=sum(Fitvalue);Fitvaluepercentage=Fitvalue./sum_Fitvalue;%计算出各个染色体被选择的概率Fitvaluepercentage=cumsum(Fitvaluepercentage);%cumsum和sum有所区别,是累加到所到之处,而不是直接全部累加sortuniform=sort(rand(Np,1));%生成50*1的[0,1]内的随机矩阵,就是50行个小于1,大于0的随机数fiti=1;newi=1;while newi<=Npif(sortuniform(newi))<Fitvaluepercentage(fiti)%随机概率和轮盘上的概率进行比较,若为真,则说明轮盘概率大newf(newi,:)=f(fiti,:); %被选择,则加入到新一代的种群矩阵中去 newi=newi+1;elsefiti=fiti+1;%没被选择,则保持不变endend
%%%%%%%%基于概率的交叉操作%%%%%%%%%%%%%%for i=1:2:Npp=rand; %p为0-1之间的一个随机数if p<Pc   %如果随机概率小于于设定的交叉概率,进行交叉q=randi([0,1],1,L);  %令q为由0/1随机生成的1*20的矩阵for j=1:L   if q(j)==1%下面这是很简单的复制转换语句temp=newf(i+1,j);newf(i+1,j)=newf(i,j);newf(i,j)=temp;endend	endend%%%%%%%%%%%%基于概率的变异操作%%%%%%%%%i =1;while i <= round(Np*Pm)      %四舍五入NP*Pm的值即i<=5h = randi(Np);            %随机生成一个1-50的整数,即随机选择一个要变异的染色体for j = 1:round(L*Pm)  g = randi(L); %随机生成一个1-20的整数,即随机选择一个要变异的基因位置数newf(h,g) = ~newf(h,g);  %help ~not - 计算逻辑 not  此 MATLAB 函数 返回与 A 大小相同的逻辑数组。如果 A 中元素为零值,则数组中对应元素为逻 辑值 1 (true) 值;如果 A 中元素为非零值,则数组中对应元素为逻辑值 0 (false)。endi = i+1;endf = newf;f(1,:) =fbest;      %将第i代最优的染色体保存在新种群中value(generation) = Fitvaluemax;       %历代最优适应度
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end%%%%%%%%%%%%%%%%%绘图%%%%%%%%%%%
x=0:0.01:10;
y=x+10*sin(5*x)+7*cos(4*x);
figure
plot(x,y)
xbest;
figure
plot(value)
xlabel('迭代次数');
ylabel('目标函数值');
title('适应度进化曲线');
%%%%%%%%%%%%适应度函数的调用%%%%%%%%%%%%%%
function result = func(x)
Fitvalue = x+10*sin(5*x)+7*cos(4*x);
result = Fitvalue;
end

制作不易,权当学习~~~~请批评指正