最近还是对模拟退火算法爱不释手,想找到一些连续型的题目练练手,就比如谢菲尔德大学的gatbx遗传算法工具包,虽然早已过时了,但是其中一些题目却考验着自己的细心和调参能力,毕竟调节超参数是很费脑子的!!!
模拟退火算法自成一派,其优化效果可见一斑,正如下面这张图:优化多峰函数(二元正态分布密度函数)
yj1.m:
该题是最简单的一元连续函数最小值求解问题:
最小化问题:
发现其曲线是一个不断波动的曲线:
极小值点很多,但是最小值只有一个。
求解代码:
%% 参数设置
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
该题是一个稍微复杂点的二元优化问题,存在着一批极值点,并且这些极值点之间稍有不同:
题目:
最小化问题:
代码:
%% 参数设置
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)是一个一阶的离散方程,表达式为
这个问题有解析解:
在本例中取其决策变量数为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
题目:
该问题也是一个系统的最小化问题:
装载系统的最优问题,装载系统是一个二维系统,表达式如下:
求目标函数:
初始值与限制条件:
该问题存在理论最小值:
在本例中取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
剩下的八题有的缺乏准确答案,使得该优化没有了可比性,有的难度博主接受不了,读者自己去解吧!!!: