一、问题描述(给出所解决问题的简要描述)
用遗传算法求解如下函数优化问题:
max f(x1,x2)=21.5+x1*sin(4*pi*x1)+x2*sin(20*pi*x2),
-3.0<=x1<=12.1,4.1<=x2<=5.8
二、方法设计(给出方法的详细设计步骤)
图1 遗传算法流程图
1.个体的编码:问题的可能解为实数对(x1,x2)的形式,将问题的可能解编码为二进制位串。对于上面的优化问题,假定所要求的精度是小数点后4位,那么
由(12.1-(-3.0))*10000=151000, 2^17-1<151000<=2^18-1知表示变量x1的二进制位串的长度是L1=18。
由(5.8-4.1)*10000=17000,2^14-1<17000<=2^15-1知表示变量x2的二进制位串的长度是L2=15。
所以表示问题可能解(x1,x2)的二进制位串的长度L=L1+L2=18+15=33。
2.适应函数:该优化问题是一个极大化问题,直接取目标函数f(x1,x2)作为适应函数eval(x1,x2)。
3.父体选择策略:轮盘赌选择。
(1)计算种群中所有染色体适应值之和F=
(2)计算每个染色体的选择概率pk= (k=1,2,...,N)
(3)计算每个染色体的累计概率qk= (k=1,2,...N)
(4)转动轮盘N次,从中选出N个染色体。选择过程如下:
用[0,1]中的一个随机数r来模拟转动一次轮盘,轮盘停止 转动后指针指向的位置。若r<=q1,这说明指针指向第一个扇形,这时选择第一个染色体v1,一般若qk-1<r<=qk , 这说明指针指向第k个扇形,这时选择第k个染色体。
4.杂交算子:选择单点杂交。首先随机产生一个整数n作为杂交电的位置,然后对于N/2个父体(取奇数位置的父体),产生一个随机数temp,如果temp<pc,那么将相邻的奇偶项父体在该杂交点右边的子串进行交换,产生两个后代个体。
5.变异算子:对种群中的每一个染色体的每一基因,产生一个随机数r,如果r<pm,则该基因进行变异,否则不进行变异。
6.参数设置:种群规模N=80,最大代数G=300,杂交概率pc=0.6,变异概率pm=0.01。
7.初始化:随机产生初始种群。
8.终止条件:算法运行所指定的最大代数后终止。
9.解码:将染色体解码为表现型。
三、实验分析(给出实验结果,并进行分析)
图2 实验结果
图3 BEST F-times图
实验结果如上图2所示:x1=11.6241,x2=5.7274,max f(x1,x2)=38.7875。
实验结果分析:画出每一轮的最好个体的适应值图,如图3所示,可知曲线是在38.5附近上下震荡的,较早代种群中某些个体的适应值要比第300轮后种群中最好个体的适应值要大,这是由于采样的随机误差所产生的。
在本题实现遗传算法时,将到当代为止演化的最好个体单独保存起来,在遗传算法结束后,将演化过程中发现的最好个体作为问题的最优解。
附录:程序源代码(提供主要代码以及注释)
clc;
clear all;
close all;
G=300; %最大代数
N=80; %种群规模
pm=0.01; %变异概率
pc=0.6; %交叉概率
x1min=-3.0;x1max=12.1; %x1取值范围
x2min=4.1;x2max=5.8; %x2取值范围
L1=18;
L2=15;
L=L1+L2; %二进制位串长度
E=round(rand(N,L)); %初始化种群
maxh=-100;
for k=1:1:G %终止条件:算法运行所指定的最大代数
time(k)=k;
for s=1:1:N
m=E(s,:);
y1=0;y2=0;
m1=m(1:1:L1);
for i=1:1:L1
y1=y1+m1(i)*2^(i-1);
end
x1=(x1max-x1min)*y1/(2^L1-1)+x1min; %x1对应的十进制
m2=m(L1+1:1:L);
for i=1:1:L2
y2=y2+m2(i)*2^(i-1);
end
x2=(x2max-x2min)*y2/(2^L2-1)+x2min; %x2对应的十进制
eval(s)=21.5+x1*sin(4*pi*x1)+x2*sin(20*pi*x2);%适应函数
end
%%------------------------------父体选择-------------------------%%
[Order,Index]=sort(eval);
eval_best(k)=Order(N);
if eval_best(k)>maxh
maxh=eval_best(k);
answer_index=k;
r_string(k,:)=E(Index(N),:);
end
eval_sum=sum(eval);
g=eval/eval_sum;%计算选择概率
q(1)=g(1);%计算累积概率
for i=2:1:N
q(i)=q(i-1)+g(i);
end
for i=1:1:N %轮盘赌算法
r=rand(1);
for j=1:1:N
if r<=q(j)
NE(i,:)=E(j,:);
break;
end
end
end
%%--------------------------------------------------------------%%
%%------------------------------杂交----------------------------%%
n=ceil(L*rand);
for i=1:2:(N-1)
temp=rand;
if pc>temp
for j=n:1:L
t=NE(i,j);
NE(i,j)=NE(i+1,j);
NE(i+1,j)=t;
end
end
end
%%--------------------------------------------------------------%%
%%------------------------------变异----------------------------%%
for i=1:1:N
for j=1:1:L
temp=rand;
if temp<pm
NE(i,j)=1-NE(i,j);
end
end
end
%%--------------------------------------------------------------%%
E=NE;
end
%%----------------------------输出、画图------------------------%%
fprintf('MAXVALUE\n');
maxh
%answer_index
r_string(answer_index,:)
m=r_string(answer_index,:);
y1=0;y2=0;
m1=m(1:1:L1);
for i=1:1:L1
y1=y1+m1(i)*2^(i-1);
end
x1=(x1max-x1min)*y1/(2^L1-1)+x1min; %x1对应的十进制
fprintf('x1\n');
x1
m2=m(L1+1:1:L);
for i=1:1:L2
y2=y2+m2(i)*2^(i-1);
end
x2=(x2max-x2min)*y2/(2^L2-1)+x2min; %x2对应的十进制
fprintf('x2\n');
x2
figure(1);
plot(time,eval_best);
xlabel('times');ylabel('BEST F');
%%-------------------------------------------------------------%%