【TSP】基于matlab模拟退火算法求解旅行商问题【含Matlab源码 1129期】
## 一、简介
**1 模拟退火算法原理**
模拟退火算法来源于固体退火原理,是一种基于概率的算法,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。退火是指将固体加热到足够高的温度,使分子呈随机排列状态,然后逐步降温使之冷却,最后分子以低能状态排列,固体达到某种稳定状态。
**2 物理退火过程**
加温过程——增强粒子的热运动,消除系统原先可能存在的非均匀态;
等温过程——对于与环境换热而温度不变的封闭系统,系统状态的自发变化总是朝*能减少的方向进行,当*能达到最小时,系统达到平衡态;
冷却过程——使粒子热运动减弱并渐趋有序,系统能量逐渐下降,从而得到低能的晶体结构。
热力学中的退火现象指物体逐渐降温时发生的物理现象:温度越低,物体的能量状态越低,到达足够的低点时,液体开始冷凝与结晶,在结晶状态时,系统的能量状态最低。缓慢降温时,可达到最低能量状态;但如果快速降温,会导致不是最低能态的非晶形。
模仿自然界退火现象而得,利用了物理中固体物质的退火过程与一般优化问题的相似性从某一初始温度开始,伴随温度的不断下降,结合概率突跳特性在解空间中随机寻找全局最优解 。
**3 模拟退火算法的模拟要求**
1 初始温度足够高
2 降温过程足够慢
3 终止温度足够低
**4 模拟退火算法的计算步骤**
![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20210711075608660.png)
![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20210711075613188.png)
![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20210711075617221.png)
![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20210711075621539.png)
![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20210711075625933.png)
## 二、源代码
```c
clc;
clear;
close all;
%%
tic
T0=1000; % 初始温度
Tend=1e-3; % 终止温度
L=500; % 各温度下的迭代次数(链长)
q=0.9; %降温速率
%% 加载数据
load CityPosition1;
%%
D=Distanse(X); %计算距离矩阵
N=size(D,1); %城市的个数
%% 初始解
S1=randperm(N); %随机产生一个初始路线
%% 画出随机解的路径图
DrawPath(S1,X)
pause(0.0001)
%% 输出随机解的路径和总距离
disp('初始种群中的一个随机值:')
OutputPath(S1);
Rlength=PathLength(D,S1);
disp(['总距离:',num2str(Rlength)]);
%% 计算迭代的次数Time
Time=ceil(double(solve(['1000*(0.9)^x=',num2str(Tend)])));
count=0; %迭代计数
Obj=zeros(Time,1); %目标值矩阵初始化
track=zeros(Time,N); %每代的最优路线矩阵初始化
%% 迭代
while T0>Tend
count=count+1; %更新迭代次数
temp=zeros(L,N+1);
for k=1:L
%% 产生新解
S2=NewAnswer(S1);
%% Metropolis法则判断是否接受新解
[S1,R]=Metropolis(S1,S2,D,T0); %Metropolis 抽样算法
temp(k,:)=[S1 R]; %记录下一路线的及其路程
end
%% 优化过程迭代图
figure
plot(1:count,Obj)
xlabel('迭代次数')
ylabel('距离')
title('优化过程')
%% 最优解的路径图
DrawPath(track(end,:),X)
%% 输出最优解的路线和总距离
disp('最优解:')
S=track(end,:);
p=OutputPath(S);
disp(['总距离:',num2str(PathLength(D,S))]);
disp('-------------------------------------------------------------')
toc
function D=Distanse(a)
%% 计算两两城市之间的距离
%输入 a 各城市的位置坐标
%输出 D 两两城市之间的距离
row=size(a,1);
D=zeros(row,row);
for i=1:row
for j=i+1:row
D(i,j)=((a(i,1)-a(j,1))^2+(a(i,2)-a(j,2))^2)^0.5;
D(j,i)=D(i,j);
end
end
function varargout = dsxy2figxy(varargin)
if length(varargin{1}) == 1 && ishandle(varargin{1}) ...
&& strcmp(get(varargin{1},'type'),'axes')
hAx = varargin{1};
varargin = varargin(2:end);
else
hAx = gca;
end;
if length(varargin) == 1
pos = varargin{1};
else
[x,y] = deal(varargin{:});
end
axun = get(hAx,'Units');
set(hAx,'Units','normalized');
axpos = get(hAx,'Position');
axlim = axis(hAx);
axwidth = diff(axlim(1:2));
axheight = diff(axlim(3:4));
if exist('x','var')
varargout{1} = (x - axlim(1)) * axpos(3) / axwidth + axpos(1);
varargout{2} = (y - axlim(3)) * axpos(4) / axheight + axpos(2);
else
pos(1) = (pos(1) - axlim(1)) / axwidth * axpos(3) + axpos(1);
pos(2) = (pos(2) - axlim(3)) / axheight * axpos(4) + axpos(2);
pos(3) = pos(3) * axpos(3) / axwidth;
pos(4) = pos(4) * axpos(4 )/ axheight;
varargout{1} = pos;
end
set(hAx,'Units',axun)
```
## 三、运行结果
![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20210711075752475.jpg?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01hdGxhYl9UYW5nTWVu,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20210711075752483.JPG?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01hdGxhYl9UYW5nTWVu,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20210711075752471.jpg?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01hdGxhYl9UYW5nTWVu,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20210711075752472.jpg?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01hdGxhYl9UYW5nTWVu,size_16,color_FFFFFF,t_70#pic_center)
## 四、备注
版本:2014a