例题一:一位旅行者从一出发点出发,要求经过31个城市(目标点的坐标已给出),并且每个点只能经过一次,最终经过所有点后回到起点。
要求:为旅行者制定一条最短路径。
%%%%%%%%%%%%%%%%%%%%%%模拟退火算法解决TSP问题%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%初始化%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
tic %用来记录程序运行时间的
clear all; %清除所有变量
close all; %清图
clc; %清屏
C=[1304 2312; % 城市坐标
3639 1315;
4177 2244;
3712 1399;
3488 1535;
3326 1556;
3238 1229;
4196 1044;
4312 790;
4386 570;
3007 1970;
2562 1756;
2788 1491;
2381 1676;
1332 695;
3715 1678;
3918 2179;
4061 2370;
3780 2212;
3676 2578;
4029 2838;
4263 2931;
3429 1980;
3507 2376;
3394 2643;
3439 3201;
2935 3240;
3140 3550;
2545 2357;
2778 2826;
2370 2975]; %31个城市坐标
n=size(C,1); %城市数目,即c的行数
T=1000; %初始温度
L=100; %迭代次数
K=0.99; %衰减参数
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%城市坐标结构体%%%%%%%%%%%%%%%%%%%%%%%%%%
city=struct([]); %结构体变量,类似python中的字典
for i=1:n %city(i)的值为第i座城市的坐标
city(i).x=C(i,1);
city(i).y=C(i,2);
end
l=1; %统计迭代次数
len(l)=func3(city,n); %每次迭代后的路线总长度
while T>0.001 %终止温度
%%%%%%%%%%%%%%%%多次迭代扰动,温度降低之前多次实验%%%%%%%%%%%%%%%
for i=1:L
%%%%%%%%%%%%%%%%%%%计算原路线总距离%%%%%%%%%%%%%%%%%%%%%%%%%
len1=func3(city,n);
%%%%%%%%%%%%%%%%%%%%%%%%%产生随机扰动%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%随机置换两个不同的城市的坐标%%%%%%%%%%%%%%%%%
p1=floor(1+n*rand()); %朝负无穷方向取整,如floor(-1.3)=-2,ceil相反
p2=floor(1+n*rand());
while p1==p2
p1=floor(1+n*rand());
p2=floor(1+n*rand());
end
%%%%%%%%%%%%%置换两地%%%%%%%%%%%%
tmp_city=city;
tmp=tmp_city(p1);
tmp_city(p1)=tmp_city(p2);
tmp_city(p2)=tmp;
%%%%%%%%%%%%%%%%%%%%%%%%计算新路线总距离%%%%%%%%%%%%%%%%%%%%
len2=func3(tmp_city,n);
%%%%%%%%%%%%%%%%%%新老距离的差值,相当于能量%%%%%%%%%%%%%%%%%
delta_e=len2-len1;
%%%%%%%%%%%%新路线好于旧路线,用新路线代替旧路线%%%%%%%%%%%%%%
if delta_e<0
city=tmp_city;
else
%%%%%%%%%%%%%%%%%%依概率选择是否接受新解%%%%%%%%%%%%%%%%%
if exp(-delta_e/T)>rand()
city=tmp_city;
end
end
end
l=l+1; %迭代次数
%%%%%%%%%%%%%%%%%%%%%%%%%计算新路线距离%%%%%%%%%%%%%%%%%%%%%%%%%%
len(l)=func3(city,n);
%%%%%%%%%%%%%%%%%%%%%%%%%%%温度不断下降%%%%%%%%%%%%%%%%%%%%%%%%%%
T=T*K;
% for i=1:n-1
% plot([city(i).x,city(i+1).x],[city(i).y,city(i+1).y],'bo-');
% hold on;
% end
% plot([city(n).x,city(1).x],[city(n).y,city(1).y],'ro-');
% title(['优化最短距离:',num2str(len(l))]);
% hold off;
% pause(0.005);
end
%%%%%%%%%%%%%%%%%%%%%%%%第一幅图%%%%%%%%%%%%%%%%%%
figure(1);
for i=1:n-1
plot([city(i).x,city(i+1).x],[city(i).y,city(i+1).y],'bo-');
hold on;
end
plot([city(n).x,city(1).x],[city(n).y,city(1).y],'ro-');
title(['优化最短距离:',num2str(len(l))])
hold off;
%%%%%%%%%%%%%%%%%%%%%%第二幅图%%%%%%%%%%%%%%%%%%%
figure(2);
plot(len)
% plot(C(:,1),C(:,2),'bo-')以C的第1列为横坐标,第二列为纵坐标
xlabel('迭代次数')
ylabel('目标函数值')
title('路径长变化曲线')
toc
例题二:求解一元函数y=sin(5*pi *x)/x的最小值,自变量x范围[1,2];
①用代码求解
②用工具箱求解
1.用代码求解
%% II. 一元函数优化
x = 1:0.01:2;
y = sin(5*pi*x) ./ x;
plot(x,y,'linewidth',1.5) %%%线宽设置1.5
ylim([-1.5, 1.5])
xlabel('x')
ylabel('y')
title('y = sin(5*pi*x) / x')
hold on
%%
% 1. 标记出最大值点
[maxVal,maxIndex] = max(y);
plot(x(maxIndex), maxVal, 'r*','linewidth',2)
text(x(maxIndex), maxVal, {[' X: ' num2str(x(maxIndex))];[' Y: ' num2str(maxVal)]})
hold on
%%
% 2. 标记出最小值点
[minVal,minIndex] = min(y);
plot(x(minIndex), minVal, 'ks','linewidth',2)
text(x(minIndex), minVal, {[' X: ' num2str(x(minIndex))];[' Y: ' num2str(minVal)]})
%%%%%%%%%%%%%%%%先构造一个cost函数%%%%%%%%%%%%%
function costVal = cost( x )
%一元函数优化:
costVal = sin(5*pi*x) / x; %求最小值
% costVal = -1 * sin(5*pi*x) / x; %用模拟退火求最大值,可以加个负号或者弄个倒数
end
% MarkoveLength 马尔科夫链长度
% DecayScale 温度衰减参数
clc
clear all
MarkoveLength=1000; %迭代次数
DecayScale=0.9; % 衰减参数α
Temperature=1000; % initial temperature
t = 1; % final temperature
% 指派矩阵,每个人做每件事所需要的时间
assingnMatrix=[17 14 2 10 1 20;
5 8 4 18 12 9;
1 12 2 10 1 20;
20 6 15 9 7 11;
17 15 13 10 10 20
12 7 20 12 9 10];
n=length(assingnMatrix);
%% 给出一个初始解
x=[1,2,3,4,5,6];
totalCost = 0;
for i=1:n
totalCost=totalCost+assingnMatrix(i,x(i));%计算初始解的时间
end
BestCost=totalCost;
BestAssign=x;
while (Temperature > t || abs(deltaCost)<2)
for i = 1:MarkoveLength
%%%%%%进行扰动%%%%%%%%%%
r = randperm(6,2); %产生两个随机数,用来交换x中的任务分配顺序
r1=r(1);
r2=r(2);
temp=x(r1);
x(r1)=x(r2);
x(r2)=temp;
%%%%%%%%扰动结束%%%%%%%%%
% 计算
totalCost=0;
for k=1:n
totalCost=totalCost+assingnMatrix(k,x(k));
end
% 判断时间是否优化
deltaCost=totalCost-BestCost;%f(x')-f(x)
if deltaCost <= 0
BestCost = totalCost; % 若时间减少则无条件接受
BestAssign=x;
else
if (rand()<exp(-deltaCost/Temperature))
BestCost = totalCost; %否则在一定概率下接受
BestAssign=x;
end
end
end
Temperature=Temperature*DecayScale;
end
disp(BestCost); %最少花费时间
disp(assingnMatrix); %指派矩阵
disp(BestAssign); %对应的指派方案
→
链接1 链接2