遗传算法之求取函数极值
1、前言
在智能控制(刘金琨)这本里面讲了遗传算法求取函数极值的方法,这里给出一些个人理解时的注释,顺带 求解了第10章的课后习题第二题。
遗传算法流程图如下:
2、原书案例
利用遗传算法求Rosenbrock函数的极大值
该函数有两个局部极大点,分别是f(2.048,-2.048)=3897.7342和f(-2.048,-2.048)=3905.9262,其中后者为全局最大点。
1. 原书代码
%Generic Algorithm for function f(x1,x2) optimum
clear all;
close all;
%Parameters
Size=80;
G=100;
CodeL=10;
umax=2.048;
umin=-2.048;
%初始化 种群 采样rand+round 产生0和1
E=round(rand(Size,2*CodeL)); %Initial Code
%Main Program
for k=1:1:G
time(k)=k;
for s=1:1:Size
m=E(s,:);
y1=0;y2=0;
%Uncoding 解码操作
m1=m(1:1:CodeL);
for i=1:1:CodeL
y1=y1+m1(i)*2^(i-1);
end
x1=(umax-umin)*y1/1023+umin;
m2=m(CodeL+1:1:2*CodeL);
for i=1:1:CodeL
y2=y2+m2(i)*2^(i-1);
end
x2=(umax-umin)*y2/1023+umin;
%优化目标是求函数的最大值,故可将个体的适应度直接取为对应的目标函数值
F(s)=100*(x1^2-x2)^2+(1-x1)^2;
end
%选个体适应度的倒数作为目标函数
Ji=1./F; %(有一说一 这个真的没用)
%****** Step 1 : Evaluate BestJ ******
BestJ(k)=min(Ji);
fi=F; %适应度函数
%'ascend' 表示升序(默认值),'descend' 表示降序。
[Oderfi,Indexfi]=sort(fi,'ascend' ); %升序排列
Bestfi=Oderfi(Size); %Let Bestfi=max(fi )选出最优个体
BestS=E(Indexfi(Size),:); %Let BestS=E(m), m is the Indexfi belong to max(fi)
bfi(k)=Bestfi; %作图用的 寻优过程
%****** Step 2 : Select and Reproduct Operation******
fi_sum=sum(fi);
fi_Size=(Oderfi/fi_sum)*Size;%比例法进行 复制
fi_S=floor(fi_Size); %Selecting Bigger fi value
kk=1;
for i=1:1:Size
for j=1:1:fi_S(i) %Select and Reproduce
TempE(kk,:)=E(Indexfi(i),:); %%优秀的个体进行复制
kk=kk+1; %kk is used to reproduce
end
end
%************ Step 3 : Crossover Operation ************
pc=0.60; %%交叉的概率
n=ceil(20*rand); %%一点交叉 选择出一点交叉的位置
for i=1:2:(Size-1)
temp=rand;
if pc>temp %Crossover Condition
for j=n:1:20
TempE(i,j)=E(i+1,j);
TempE(i+1,j)=E(i,j);
end
end
end
TempE(Size,:)=BestS;
E=TempE;
%************ Step 4: Mutation Operation **************
%pm=0.001;
%pm=0.001-[1:1:Size]*(0.001)/Size; %Bigger fi, smaller Pm
%pm=0.0; %No mutation
pm=0.1; %Big mutation %%%变异
for i=1:1:Size
for j=1:1:2*CodeL
temp=rand;
if pm>temp %Mutation Condition
if TempE(i,j)==0
TempE(i,j)=1; %1变0 0变1
else
TempE(i,j)=0;
end
end
end
end
%Guarantee TempPop(30,:) is the code belong to the best individual(max(fi))
TempE(Size,:)=BestS; %保证最优个体不丢失(变异交叉等会改变最优个体的基因)
E=TempE; %形成新的一代种群的基因
end
Max_Value=Bestfi
BestS
x1
x2
figure(1);
plot(time,BestJ);
xlabel('Times');ylabel('Best J');
figure(2);
plot(time,bfi);
xlabel('times');ylabel('Best F');
2. 代码结果
Max_Value =
3.9059e+03
BestS =
列 1 至 16
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
列 17 至 20
0 0 0 0
x1 =
-2.0480
x2 =
-2.0480
3、 课后习题
1. 题目要求
2. 实验代码
%Generic Algorithm for function f(x1,x2) optimum
clear all;
close all;
%Parameters
Size=80;
G=100;
CodeL=40;%最主要的改动是这里 通过提高编码的长度,提高解的精度
umax=5.12;
umin=-5.12;
%初始化 种群 采样rand+round 产生0和1
E=round(rand(Size,3*CodeL)); %Initial Code
%Main Program
for k=1:1:G
time(k)=k;
for s=1:1:Size
m=E(s,:);
y1=0;y2=0;y3=0;
%Uncoding 解码操作
m1=m(1:1:CodeL);
for i=1:1:CodeL
y1=y1+m1(i)*2^(i-1);
end
x1=(umax-umin)*y1/( 2^CodeL-1)+umin;
m2=m(CodeL+1:1:2*CodeL);
for i=1:1:CodeL
y2=y2+m2(i)*2^(i-1);
end
x2=(umax-umin)*y2/( 2^CodeL-1)+umin;
m3=m(2*CodeL+1:1:3*CodeL);
for i=1:1:CodeL
y3=y3+m3(i)*2^(i-1);
end
x3=(umax-umin)*y3/( 2^CodeL-1)+umin;
F(s)=x1*x1+x2*x2+x3*x3;
end
Ji=F;
%****** Step 1 : Evaluate BestJ ******
BestJ(k)=min(Ji);
%要求最小值 所以适应度函数可以设为目标函数的倒数,这样好选出最优个体(值小的适应度高)
fi=1./F; %Fitness Function
%'ascend' 表示升序(默认值),'descend' 表示降序。
[Oderfi,Indexfi]=sort(fi,'ascend' ); %Arranging fi small to bigger
Bestfi=Oderfi(Size); %Let Bestfi=max(fi)
BestS=E(Indexfi(Size),:); %Let BestS=E(m), m is the Indexfi belong to max(fi)
bfi(k)=Bestfi;%作图用的 寻优过程
%****** Step 2 : Select and Reproduct Operation******
fi_sum=sum(fi);
fi_Size=(Oderfi/fi_sum)*Size;%比例法进行 复制
fi_S=floor(fi_Size); %Selecting Bigger fi value
kk=1;
for i=1:1:Size
for j=1:1:fi_S(i) %Select and Reproduce
TempE(kk,:)=E(Indexfi(i),:); %%优秀的个体进行复制
kk=kk+1; %kk is used to reproduce
end
end
%************ Step 3 : Crossover Operation ************
pc=0.60; %%交叉的概率
n=ceil(30*rand); %%一点交叉 概率大于0.6
for i=1:2:(Size-1)
temp=rand;
if pc>temp %Crossover Condition
for j=n:1:30
TempE(i,j)=E(i+1,j);
TempE(i+1,j)=E(i,j);
end
end
end
TempE(Size,:)=BestS;
E=TempE;
%************ Step 4: Mutation Operation **************
%pm=0.001;
%pm=0.001-[1:1:Size]*(0.001)/Size; %Bigger fi, smaller Pm
%pm=0.0; %No mutation
pm=0.1; %Big mutation %%%变异
for i=1:1:Size
for j=1:1:3*CodeL
temp=rand;
if pm>temp %Mutation Condition
if TempE(i,j)==0
TempE(i,j)=1;
else
TempE(i,j)=0;
end
end
end
end
%Guarantee TempPop(30,:) is the code belong to the best individual(max(fi))
TempE(Size,:)=BestS;
E=TempE;
end
BestS
x1
x2
x3
figure(1);
plot(time,BestJ);
xlabel('Times');ylabel('Best J');
figure(2);
plot(time,bfi);
xlabel('times');ylabel('Best F');
3. 实验结果
BestS =
列 1 至 18
1 1 1 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1
列 19 至 36
0 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
列 37 至 54
1 1 1 0 0 1 0 1 1 1 1 0 0 0 1 0 0 1
列 55 至 72
0 0 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0
列 73 至 90
0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 0
列 91 至 108
0 1 1 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1
列 109 至 120
1 1 1 1 1 1 1 1 1 1 1 0
x1 =
-1.2489e-04
x2 =
6.4789e-05
x3 =
-3.2121e-06
PS:适应度函数不一定要选成目标函数值的倒数,也可以是相反数,这样最小值问题就转换成最大值问题了。有兴趣的可以自己做一下。