gatbx遗传算法工具包部分题目的模拟退火求解

 

  最近还是对模拟退火算法爱不释手,想找到一些连续型的题目练练手,就比如谢菲尔德大学的gatbx遗传算法工具包,虽然早已过时了,但是其中一些题目却考验着自己的细心和调参能力,毕竟调节超参数是很费脑子的!!!

模拟退火算法自成一派,其优化效果可见一斑,正如下面这张图:优化多峰函数(二元正态分布密度函数)

yj1.m:

该题是最简单的一元连续函数最小值求解问题:

 f\left ( x \right )=xsin\left ( 10 \pi x \right )+2.0,x\in\left [ -1,2 \right ]

最小化问题:

发现其曲线是一个不断波动的曲线:

极小值点很多,但是最小值只有一个。

求解代码:

%% 参数设置
alpha=0.99;
T0=1;
T=T0;
max_iter=2000;%最大迭代次数
r=0.5;%随机变动半径
max_jump=30;%最大随机跳跃次数
simu=1;%并行程序数目
candidate=rand(1,simu);%随机生成并行程序
T_terminal=1.0e-30;%终止温度
now_grade=zeros(1,simu);
gradelist=zeros(1,max_iter);
%% 随机模拟
candidate=rand(1,10)*3-1;
for i=1:10
grade(1,i)=fitness(candidate(:,i));
end
[~,I]=sort(grade);
candidate(:,I(simu+1:end))=[];
%% 迭代
for i=1:max_iter
for j=1:simu
now_grade(1,j)=fitness(candidate(:,j));
for k=1:max_jump
new_point=candidate(:,j)+r*rand(1,1)-r./2;
new_point(find(new_point>10))=10;
new_point(find(new_point<0))=0;
new_grade=fitness(new_point);
if(new_grade<now_grade(1,j)||rand(1)<exp((now_grade(1,j)-new_grade)./T))
candidate(:,j)=new_point;
end
end
end
T=T*alpha;
if T<T_terminal
    break;
end
gradelist(1,i)=min(now_grade);
end
%% 展示最终运行效果
 showlist=1:1:max_iter;
 figure(1),
 plot(gradelist(showlist));
  figure(2),
 fplot(@(x)(x.*sin(10*pi.*x)+2.0),[-1,2]);
 hold on;
 scatter(candidate,now_grade,'filled','r');
 hold off;
fprintf('x=%f,fmin(x)=%f\n',candidate(1),now_grade(1));
%% 辅助函数
function y=fitness(x)
y=(x.*sin(10*pi.*x)+2.0)*(x>-1&x<2)+100*(x>=2|x<=-1);
end

yj3.m

该题是一个稍微复杂点的二元优化问题,存在着一批极值点,并且这些极值点之间稍有不同:

题目:

 f\left ( x_{1},x_{2} \right )=\sum_{i=1}^{5}icos[\left ( i+1 \right )x_{1}+i]*\sum_{i=1}^{5}icos[\left ( i+1 \right )x_{2}+i]     

最小化问题:                                                 

 代码:

%% 参数设置
alpha=0.99;
T0=1;
T=T0;
max_iter=2000;%最大迭代次数
r=0.5;%随机变动半径
max_jump=20;%最大随机跳跃次数
simu=5;%并行程序数目
candidate=rand(2,simu);%随机生成并行程序
T_terminal=1.0e-30;%终止温度
now_grade=zeros(1,simu);
gradelist=zeros(1,max_iter);
%% 随机模拟
candidate=rand(2,1000)*10;
for i=1:1000
grade(1,i)=fitness(candidate(:,i));
end
[~,I]=sort(grade);
candidate(:,I(simu+1:end))=[];
%% 迭代
for i=1:max_iter
for j=1:simu
now_grade(1,j)=fitness(candidate(:,j));
for k=1:max_jump
new_point=candidate(:,j)+r*rand(length(candidate(:,j)),1)-r./2;
new_point(find(new_point>10))=10;
new_point(find(new_point<0))=0;
new_grade=fitness(new_point);
if(new_grade<now_grade(1,j)||rand(1)<exp((now_grade(1,j)-new_grade)./T))
candidate(:,j)=new_point;
end
end
end
T=T*alpha;
if T<T_terminal
    break;
end
gradelist(1,i)=min(now_grade);
end
%% 展示最终运行效果
showlist=1:1:max_iter;
figure(1),
plot(gradelist(showlist));
figure(2),
[x,y]=meshgrid(-10:0.04:10,-10:0.04:10);
p=0;q=0;
for i=1:5
p=p+i*cos((i+1).*x+i);
q=q+i*cos((i+1).*y+i);
end
z=p.*q;
mesh(x,y,z);
%% 辅助函数
function y=fitness(x)
p=0;q=0;
for i=1:5
p=p+i*cos((i+1).*x(1)+i);
q=q+i*cos((i+1).*x(2)+i);
end
y=p*q;
end

yj4.m

该题叙述的是一个控制系统的最大化问题:

题目:

收获系统最优控制,收获系统(Harvest)是一个一阶的离散方程,表达式为

x\left ( k+1 \right )=\alpha*x\left ( k \right )-u\left ( k \right ),k=1,2,\hdots,N

x\left ( 0 \right )=100,u\left ( k \right )\in[0,200],max=\sum_{k=1}^{N}\sqrt{(u\left ( k \right ))}-\frac{0.4}{20^{0.6}}|x\left ( N \right )-x\left ( 0 \right )|

这个问题有解析解:

max=\sqrt{\frac{x\left ( 0 \right )\left ( a^{N}-1 \right )^{2}}{a^{N-1}\left ( a-1 \right )}}

在本例中取其决策变量数为20,则精确解为:

10*(1.1^20-1)*sqrt(10)./sqrt(1.1.^19)=73.2377;即在matlab中可以验证:

代码:

%% 参数设置
alpha=0.99;
T0=1;
T=T0;
max_iter=5000;%最大迭代次数
r=1;%随机变动半径
max_jump=50;%最大随机跳跃次数
simu=1;%并行程序数目
candidate=rand(20,simu);%随机生成并行程序
T_terminal=1.0e-30;%终止温度
now_grade=zeros(1,simu);
gradelist=zeros(1,max_iter);
global Rx a;
Rx=zeros(1,21);
a=1.1;
Rx(1)=100;
%% 随机模拟
candidate=rand(20,100)*200;
for i=1:100
grade(1,i)=fitness(candidate(:,i));
end
[~,I]=sort(grade);
candidate(:,I(simu+1:end))=[];
%% 迭代
for i=1:max_iter
for j=1:simu
now_grade(1,j)=fitness(candidate(:,j));
for k=1:max_jump
new_point=candidate(:,j)+r*rand(20,1)-r./2;
new_point(find(new_point>200))=200;
new_point(find(new_point<0))=0;
new_grade=fitness(new_point);
if(new_grade<now_grade(1,j)||rand(1)<exp((now_grade(1,j)-new_grade)./T))
candidate(:,j)=new_point;
end
end
end
T=T*alpha;
if T<T_terminal
    break;
end
gradelist(1,i)=min(now_grade);
end
%% 展示最终运行效果
showlist=1:100:max_iter;
stem(gradelist(showlist),'filled');
%% 辅助函数
function y=fitness(x)
global Rx a;
for i=1:20
Rx(i+1)=a.*Rx(i)-x(i);
end
y=-sum(sqrt(x))+0.4./20.^0.6.*abs((Rx(end)-Rx(1)));
end

yj5.m

题目:

该问题也是一个系统的最小化问题:

装载系统的最优问题,装载系统是一个二维系统,表达式如下:

$$\left\{ \begin{aligned} x_{1}\left ( k+1 \right ) & = & x_{2}\left ( k \right ) \\ x_{2}\left ( k +1\right ) & = & 2*x_{2}\left ( k \right )-x_{1}\left ( k \right )+\frac{u\left ( k \right )}{N^{2}} \\ \end{aligned} \right. $$ \forall k=1,2,\hdots N

求目标函数:

f\left ( x,u \right )=-x_{1}\left ( N+1 \right )+\frac{1}{2N}\sum_{k=1}^{N}u^{2}\left ( k \right )

初始值与限制条件:

x_{1}\left ( 0 \right )=x_{2}\left ( 0 \right )=0;\forall k=1,2,\hdots N:u\left ( k \right )\in[0,10]

该问题存在理论最小值:

min=-\frac{1}{3}+\frac{3N-1}{6N^{2}}+\frac{1}{2N^{3}}\sum_{k=1}^{N-1}k^{2}

在本例中取N=20,则全局最小值为-0.1544:

优化效果:

代码:

%% 参数设置
alpha=0.99;
T0=1;
T=T0;
max_iter=5000;%最大迭代次数
r=0.01;%随机变动半径
max_jump=20;%最大随机跳跃次数
simu=1;%并行程序数目
candidate=rand(20,simu);%随机生成并行程序
T_terminal=1.0e-30;%终止温度
now_grade=zeros(1,simu);
gradelist=zeros(1,max_iter);
%% 随机模拟
candidate=rand(20,1000)*10;
for i=1:1000
grade(1,i)=fitness(candidate(:,i));
end
[~,I]=sort(grade);
candidate(:,I(simu+1:end))=[];
%% 迭代
for i=1:max_iter
for j=1:simu
now_grade(1,j)=fitness(candidate(:,j));
for k=1:max_jump
new_point=candidate(:,j)+r*rand(20,1)-r./2;
new_point(find(new_point>10))=10;
new_point(find(new_point<0))=0;
new_grade=fitness(new_point);
if(new_grade<now_grade(1,j)||rand(1)<exp((now_grade(1,j)-new_grade)./T))
candidate(:,j)=new_point;
end
end
end
T=T*alpha;
if T<T_terminal
    break;
end
gradelist(1,i)=min(now_grade);
end
%% 展示最终运行效果
showlist=1:100:max_iter;
stem(gradelist(showlist),'filled');
%% 辅助函数
function y=fitness(x)
t=[0,0];
for i=1:20
t(i+1,1)=t(i,2);
t(i+1,2)=2*t(i,2)-t(i,1)+x(i)./20./20;
end
y=-t(21,1)+sum(x.^2)/40;
end

剩下的八题有的缺乏准确答案,使得该优化没有了可比性,有的难度博主接受不了,读者自己去解吧!!!:

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值