题目:利用遗传算法求函数极大值;
clc;clear;
%初始参数
N=100;%初始的随机自变量个数
G=100;%总的迭代次数,
Pc=0.6;%确定交叉的可能性即确定每一组xy被交叉改变的可能性
Pm=0.015;%确定变异的可能性即确实每一组xy被变异改变的可能性
n=10;%二进制串的长度,自己设置,太短随机生成的自变量则被局限了
%f=x^3+(2*y-x)^4;%目标函数,f(x,y)调用
x_min=10;x_max=20;%题目对x与y的约束
y_min=10;y_max=20;
E=round(rand(N,2*n));%随机生成100组x,y自变量,一行为一组
%time(1,G)=0;F(1,N)=0;Best_Fit(1,G)=0;temp_E(N,2*n)=0;%内存预分配
for k =1:G
time(k)=k;
x=zeros(1,N);%前面随机生成了100组,那么就有100个x与100个y
y=zeros(1,N);%这两是内存预分配
%接下来计算每一组x与y的目标函数值
for i=1:N
x=x_min+(er(E(i,1:n))/(2^n-1))*(x_max-x_min);%限制x在其范围内
y=y_min+(er(E(i,n+1:end))/(2^n-1))*(y_max-y_min);%同上
F(i)=f(x,y);%计算每一组的目标函数值保存到F
end
Best_F=max(F);%找到其中最大的,题目要求是求目标函数极大值
[now_F,index_F]=sort(F);%升序排序,now_F为排序后的,index_F一一对应原位置
Best_xy=E(index_F(N),:);%升序排的,所以最后一个(100)为最大值,找到这个最大值是哪一组xy
Best_Fit(k)=Best_F;%记录这一次迭代的最大目标函数值
%复制,带遗传算法中复制规定的公式
F_sum=sum(F);
P_num=N*now_F/F_sum;%复制公式
copynum=floor(P_num);%取整,确定这100组中每一组是否复制,复制多少次,续下
%这里你会发现让目标函数值越大的xy组,被复制的次数越多(因为本题是求极大值)
k=1;
for i =1:N
for j=1:copynum(i)
temp_E(k,:)=E(index_F(i),:);%进行"复制"后的新的x,y自变量
k=k+1;
end
end
for i=k:N
temp_E(i,:)=Best_xy;%把E后面几组还没有被复制替换的这些,均替换成最优的那组xy
end
%复制过程完成,接下来是交叉
for i =1:N
rand_point=round((20-1)*rand+1);%随机选定一个开始交叉的位置,这里E一行有20列,可选的交叉位置有20个
rand_xy=round((N-1)*rand+1);%随机选定E的一行即随机选定一组xy作为交叉替换的数
temp_Pc=rand;
if Pc>temp_Pc
for j=rand_point:20
temp_E(i,j)=temp_E(rand_xy,j);%若rand_point为10,为第10开始到第20个数都交叉替换成rand_xy10到20对应的值
end
end
end
temp_E(N,:)=Best_xy;%把最后一行还是固定为之前的最优xy组
%交叉结果,变异开始
for i=1:N
for j=1:20
temp_Pm=rand;
if Pm>temp_Pm
if temp_E(i,j)==1
temp_E(i,j)=0;%变异每一组xy内部进行,按变异概率改变二进制xy的值
else
temp_E(i,j)=1;%原来是1就换0,原来是0就换1;因为有temp_Pm,所以不大可能20个二进制值均改变
end
end
end
end
E=temp_E;%把经历了一轮复制、交叉、变异的100组xy给E,以便继续对其进行新一轮复制、交叉、变异
end
plot(time,Best_Fit);%查看目标函数最大值收敛情况
x=x_min+(er(Best_xy(1:n))/(2^n-1))*(x_max-x_min)
y=y_min+(er(Best_xy(n+1:end))/(2^n-1))*(y_max-y_min)
改进后的遗传算法,Pc和Pm随着迭代而自行改变
%改进的遗传算法
clc;clear;
%初始参数
N=100;%初始的随机自变量个数
G=100;%总的迭代次数,
r=0.0000000000000000001;%防止pc,pm那里分母为0;
Pc1=0.9;Pc2=0.6;%确定交叉的可能性即确定每一组xy被交叉改变的可能性
Pm1=0.1;Pm2=0.01;%确定变异的可能性即确实每一组xy被变异改变的可能性
n=10;%二进制串的长度,自己设置,太短随机生成的自变量则被局限了
%f=x^3+(2*y-x)^4;%目标函数,f(x,y)调用
x_min=10;x_max=20;%题目对x与y的约束
y_min=10;y_max=20;
E=round(rand(N,2*n));%随机生成100组x,y自变量,一行为一组
time(1,G)=0;F(1,N)=0;Best_Fit(1,G)=0;temp_E(N,2*n)=0;%内存预分配
for k =1:G
time(k)=k;
x=zeros(1,N);%前面随机生成了100组,那么就有100个x与100个y
y=zeros(1,N);%这两是内存预分配
%接下来计算每一组x与y的目标函数值
for i=1:N
x=x_min+(er(E(i,1:n))/(2^n-1))*(x_max-x_min);%限制x在其范围内
y=y_min+(er(E(i,n+1:end))/(2^n-1))*(y_max-y_min);%同上
F(i)=f(x,y);%计算每一组的目标函数值保存到F
end
Best_F=max(F);%找到其中最大的,题目要求是求目标函数极大值
[now_F,index_F]=sort(F);%升序排序,now_F为排序后的,index_F一一对应原位置
Best_xy=E(index_F(N),:);%升序排的,所以最后一个(100)为最大值,找到这个最大值是哪一组xy
Best_Fit(k)=Best_F;%记录这一次迭代的最大目标函数值
%%复制,带遗传算法中复制规定的公式
F_sum=sum(F);
P_num=N*now_F/F_sum;%复制公式
copynum=floor(P_num);%取整,确定这100组中每一组是否复制,复制多少次,续下
%这里你会发现让目标函数值越大的xy组,被复制的次数越多(因为本题是求极大值)
k=1;
for i =1:N
for j=1:copynum(i)
temp_E(k,:)=E(index_F(i),:);%进行"复制"后的新的x,y自变量
k=k+1;
end
end
for i=k:N
temp_E(i,:)=Best_xy;%把E后面几组还没有被复制替换的这些,均替换成最优的那组xy
end
%%复制过程完成,接下来是交叉
for i =1:N
rand_point=round((20-1)*rand+1);%随机选定一个开始交叉的位置,这里E一行有20列,可选的交叉位置有20个
rand_xy=round((N-1)*rand+1);%随机选定E的一行即随机选定一组xy作为交叉替换的数
temp_Pc=rand;
%随着每代个体适应度值的变化而自行调整,即保护了群体中优质的个体,又令具有最大适应度的个体Pc和Pm不为0,
%使每代最优个体不会处于一种不发生变化的状态,有利于跳出局部最优解
x_pc1=x_min+(er(temp_E(i,1:n))/(2^n-1))*(x_max-x_min);%限制x在其范围内
y_pc1=y_min+(er(temp_E(i,n+1:end))/(2^n-1))*(y_max-y_min);
x_pc2=x_min+(er(temp_E(rand_xy,1:n))/(2^n-1))*(x_max-x_min);%限制x在其范围内
y_pc2=y_min+(er(temp_E(rand_xy,n+1:end))/(2^n-1))*(y_max-y_min);
f_pc=max(f(x_pc1,y_pc1),f(x_pc2,y_pc2));
if (max(F)-mean(F))/(mean(F)-min(F)+r)<1
Pc=0.8*(max(F)-mean(F))/(mean(F)-min(F)+r);
else
Pc=Pc1-(Pc1-Pc2)*(f_pc-min(F))/(max(F)-min(F));%改进的IAGA算法让Pc自行调整
end
if Pc>temp_Pc
for j=rand_point:20
temp_E(i,j)=temp_E(rand_xy,j);%若rand_point为10,为第10开始到第20个数都交叉替换成rand_xy10到20对应的值
end
end
end
temp_E(N,:)=Best_xy;%把最后一行还是固定为之前的最优xy组
%%交叉结果,变异开始
for i=1:N
for j=1:20
temp_Pm=rand;
x_pm=x_min+(er(temp_E(i,1:n))/(2^n-1))*(x_max-x_min);%限制x在其范围内
y_pm=y_min+(er(temp_E(i,n+1:end))/(2^n-1))*(y_max-y_min);
f_pie=f(x_pm,y_pm);
if (max(F)-mean(F))/(mean(F)-min(F)+r)<1
Pm=0.1*(max(F)-mean(F))/(mean(F)-min(F)+r);
else
Pm=Pm1-(Pm1-Pm2)*(f_pie-min(F))/(max(F)-min(F));%改进的IAGA算法让Pm自行调整
end
if Pm>temp_Pm
if temp_E(i,j)==1
temp_E(i,j)=0;%变异每一组xy内部进行,按变异概率改变二进制xy的值
else
temp_E(i,j)=1;%原来是1就换0,原来是0就换1;因为有temp_Pm,所以不大可能20个二进制值均改变
end
end
end
end
E=temp_E;%把经历了一轮复制、交叉、变异的100组xy给E,以便继续对其进行新一轮复制、交叉、变异
end
plot(time,Best_Fit);%查看目标函数最大值收敛情况
x=x_min+(er(Best_xy(1:n))/(2^n-1))*(x_max-x_min)
y=y_min+(er(Best_xy(n+1:end))/(2^n-1))*(y_max-y_min)
上面代码中对应的function函数
er.m
function x=er(m)
a=length(m);x=0;
for i=1:a
x=m(i)*2^(a-i)+x;%二进制转十进制
end
end
shi.m
function m=shi(x)
k=1;a=2;
while a>=1
a=floor(x/2);
b=mod(x,2);
x=a;
e(k)=b;
k=k+1;
end
m=e(length(e):-1:1);%十进制转二进制
f.m
function f=f(x,y)
f=x^3+(2*y-x)^4;%目标函数(适应度函数)
end
运行结果:
对应最优xy解为x=10;y=20;
需要了解遗传算法中复制、交叉、变异规定的公式(公式来源:http://t.csdn.cn/JlcJP)