基于模拟退火算法的TSP算法

304 篇文章 184 订阅
13 篇文章 7 订阅

一,理论基础

模拟退火(simulated annealing,SA)算法的思想最早是由Metropolis等提出的。其出发点是基于物理中固体物质的退火过程与一般的组合优化问题之间的相似性。模拟退火法是一种通用的优化算法,其物理退火过程由以下三部分组成:
(1)加温过程。其目的是增强粒子的热运动,使其偏离平衡位置。当温度足够高时,固体将熔化为液体,从而消除系统原先存在的非均匀状态。
(2)等温过程。对于与周围环境交换热量而温度不变的封闭系统,系统状态的自发变化总是朝自由能减少的方向进行的,当自由能达到最小时,系统达到平衡状态。
(3)冷却过程。使粒子热运动减弱,系统能量下降,得到晶体结构。
SA算法实现过程如下(以最小化问题为例):
(1)初始化:取初始温度 T 0 T_0 T0足够大,令 T = T 0 T=T_0 T=T0,任取初始解 S 1 S_1 S1,确定每个 T T T时的迭代次数,即Metropolis链长 L L L
(2)对当前温度 T T T k = 1 , 2 , ⋯   , L k=1,2,\dotsm,L k=1,2,,L,重复步骤(3)~(6)。
(3)对当前解 S 1 S_1 S1随机扰动(比如交换 S 1 S_1 S1分量的数据)产生一个新解 S 2 S_2 S2
(4)计算S2的增量 d f = f ( S 2 ) − f ( S 1 ) df=f(S_2)-f(S_1) df=f(S2)f(S1),其中 f ( S 1 ) f(S_1) f(S1)为S1的代价函数。
(5)若 d f < 0 df<0 df<0,则接受S2作为新的当前解,即 S 1 = S 2 S_1=S_2 S1=S2;否则计算S2的接受概率 e x p ( − d f / T ) exp(-df/T) exp(df/T),即随机产生 ( 0 , 1 ) (0,1) (0,1)区间上均匀分布的随机数 r a n d rand rand,若 e x p ( − d f / T ) > r a n d exp(-df/T)>rand exp(df/T)>rand,也接受S2作为新的当前解, S 1 = S 2 S_1=S_2 S1=S2;否则保留当前解 S 1 S_1 S1
(6)如果满足终止条件 S t o p Stop Stop,则输出当前解 S 1 S_1 S1为最优解,结束程序。终止条件 S t o p Stop Stop通常为:在连续若干个Metropolis链中新解 S 2 S_2 S2都没有被接受时终止算法,或是设定结束温度。否则,则按衰减函数衰减 T T T后返回步骤(2)。
以上步骤称为Metropolis过程。逐渐降低控制温度,重复Metropolis过程,直至满足结束准则Stop,求出最优解。

二,TSP问题介绍

TSP(traveling salesman problem,旅行商问题)是典型的NP完全问题,即其最坏情况下的时间复杂度随着问题规模的增大按指数方式增长,到目前为止还未找到一个多项式时间的有效算法。
TSP问题可描述为:已知 n n n个城市相互之间的距离,某一旅行商从某个城市出发访问每个城市有且仅有一次,最后回到出发城市,如何安排才使其所走路线距离最短。简言之,就是寻找一条最短的遍历 n n n个城市的路径,或者说搜索自然子集 X = { 1 , 2 , ⋯   , n } X=\{1,2,\dotsm,n\} X={1,2,,n}( X X X的元素表示对 n n n个城市的编号)的一个排列 π ( X ) = { V 1 , V 2 , ⋯   , V n } π(X)=\{V_1,V_2,\dotsm,V_n\} π(X)={V1,V2,,Vn},使得 T d = ∑ i = 1 n + 1 d ( V i , V i + 1 ) + d ( V n , V 1 ) T_d=\sum_{i=1}^{n+1} {d(V_i,V_{i+1})}+d(V_n,V_1) Td=i=1n+1d(Vi,Vi+1)+d(Vn,V1)取得最小值,其中 d ( V i , V i + 1 ) d(V_i,V_{i+1}) d(Vi,Vi+1)表示城市 V i V_i Vi到城市 V i + 1 V_{i+1} Vi+1的距离。

三,思路和步骤

1.算法流程
模拟退火算法求解TSP问题的流程图如图1所示。

图1 模拟退火算法求解流程图

在这里插入图片描述
2.模拟退火算法实现

控制参数的设置

需要设置的主要控制参数有降温速率 q q q、初始温度 T 0 T_0 T0、结束温度 T e n d T_{end} Tend以及链长 L L L

初始解

对于 n n n个城市的TSP问题,得到的解就是对1~ n n n的一个排序,其中每个数字对应城市的编号。

解变换生成新解

通过对当前解 S 1 S_1 S1进行变换,产生新的路径数组即新解,这里采用的变换是产生随机数的方法来产生将要交换的两个城市,用二邻域变换法产生新的路径,即可行的新解 S 2 S_2 S2

Metropolis准则

若路径长度函数为 f ( S ) f(S) f(S),则当前解的路径为 f ( S 1 ) f(S_1) f(S1),新解的路径为 f ( S 2 ) f(S_2) f(S2),路径差为 d f = f ( S 2 ) − f ( S 1 ) df=f(S_2)-f(S_1) df=f(S2)f(S1),则Metropolis准则为 P = { 1 , d f <0 e x p ( − d f T ) , d f ≥0 P= \begin{cases}1, & \text{$df$<0} \\ exp(-\frac {df} {T}), & \text{$df$≥0} \\\end{cases} P={1,exp(Tdf),df<0df≥0如果 d f < 0 df<0 df<0,则以概率1接受新的路径;否则以概率 e x p ( − d f T ) exp(-\frac {df} {T}) exp(Tdf)接受新的路径。

降温

利用降温速率 q q q进行降温,即 T = q T T=qT T=qT,若 T T T小于结束温度,则停止迭代输出当前状态,否则继续迭代。

四,MATLAB程序实现

  • 计算距离矩阵
function D = Distance(citys)
%% 计算两两城市之间的距离
% 输入 citys  各城市的位置坐标
% 输出 D  两两城市之间的距离

n = size(citys,1);
D = zeros(n,n);
for i = 1:n
   for j = i+1:n
       D(i,j) = sqrt(sum((citys(i,:) - citys(j,:)).^2));
       D(j,i) = D(i,j);
   end
end
  • 初始解
S1=randperm(N);			% 随机产生一个初始路线
  • 生成新解
function S2 = NewAnswer(S1)
%% 输入
% S1:当前解
%% 输出
% S2:新解

N = length(S1);
S2 = S1;                
a = round(rand(1,2)*(N-1)+1); %产生两个随机位置 用来交换
W = S2(a(1));
S2(a(1)) = S2(a(2));
S2(a(2)) = W;         %得到一个新路线
  • Metropolis准则
function [S,R] = Metropolis(S1,S2,D,T)
%% 输入
% S1:  当前解
% S2:   新解
% D:    距离矩阵(两两城市的之间的距离)
% T:    当前温度
%% 输出
% S:   下一个当前解
% R:   下一个当前解的路线距离

R1 = PathLength(D,S1);  %计算路线长度
N = length(S1);         %得到城市的个数

R2 = PathLength(D,S2);  %计算路线长度
dC = R2 - R1;   %计算能力之差
if dC < 0       %如果能力降低 接受新路线
    S = S2;
    R = R2;
elseif exp(-dC/T) >= rand   %exp(-dC/T)概率接受新路线
    S = S2;
    R = R2;
else        %不接受新路线
    S = S1;
    R = R1;
end
  • 画路线轨迹图
function DrawPath(Route,citys)
%% 画路径函数
%输入
% Route  待画路径   
% citys  各城市坐标位置

figure
plot([citys(Route,1);citys(Route(1),1)],...
     [citys(Route,2);citys(Route(1),2)],'o-');
grid on

for i = 1:size(citys,1)
    text(citys(i,1),citys(i,2),['   ' num2str(i)]);
end

text(citys(Route(1),1),citys(Route(1),2),'       起点');
text(citys(Route(end),1),citys(Route(end),2),'       终点');

  • 输出路径函数
function p = OutputPath(R)
%% 输出路径函数
% 输入:R 路径
R = [R,R(1)];
N = length(R);
p = num2str(R(1));
for i = 2:N
    p = [p,'—>',num2str(R(i))];
end
disp(p)
  • 可行解路线长度函数
function Length = PathLength(D,Route)
%% 计算各个体的路径长度
% 输入:
% D     两两城市之间的距离
% Route 个体的轨迹

Length = 0;
n = size(Route,2);
for i = 1:(n - 1)
    Length = Length + D(Route(i),Route(i + 1));
end
Length = Length + D(Route(n),Route(1));
  • 模拟退火算法主函数
    模拟退火算法参数设置如下所列。

在这里插入图片描述
主函数代码如下:

 %% I. 清空环境变量
clear all
clc

%% II. 导入城市位置数据
X = [16.4700   96.1000
     16.4700   94.4400
     20.0900   92.5400
     22.3900   93.3700
     25.2300   97.2400
     22.0000   96.0500
     20.4700   97.0200
     17.2000   96.2900
     16.3000   97.3800
     14.0500   98.1200
     16.5300   97.3800
     21.5200   95.5900
     19.4100   97.1300
     20.0900   92.5500];

%% III. 计算距离矩阵
D = Distance(X);  %计算距离矩阵
N = size(D,1);    %城市的个数

%% IV. 初始化参数
T0 = 1e10;   % 初始温度
Tend = 1e-30;  % 终止温度
L = 2;    % 各温度下的迭代次数
q = 0.9;    %降温速率
syms x;
Time = ceil(double(solve(T0*(0.9)^x == Tend)));    % 计算迭代的次数
% Time = 132;
count = 0;        %迭代计数
Obj = zeros(Time,1);         %目标值矩阵初始化
track = zeros(Time,N);       %每代的最优路线矩阵初始化

%% V. 随机产生一个初始路线
S1 = randperm(N);
DrawPath(S1,X)
disp('初始种群中的一个随机值:')
OutputPath(S1);
Rlength = PathLength(D,S1);
disp(['总距离:',num2str(Rlength)]);

%% VI. 迭代优化
while T0 > Tend
    count = count + 1;     %更新迭代次数
    temp = zeros(L,N+1);
    %%
    for k = 1:L
        % 1. 产生新解
        S2 = NewAnswer(S1);
        % 2. Metropolis法则判断是否接受新解
        [S1 R] = Metropolis(S1, S2, D, T0);   % Metropolis抽样算法
        temp(k, :) = [S1 R];            % 记录下一路线及其长度
    end
    %% 3. 记录每次迭代过程的最优路线
    [d0, index] = min(temp(:, end));    % 找出当前温度下最优路线
    if count == 1 || d0 <= Obj(count-1)
        Obj(count) = d0;                    % 如果当前温度下最优路程小于上一路程则记录当前路程
    else
        Obj(count) = Obj(count-1);    % 如果当前温度下最优路程大于上一路程则记录上一路程
    end
    track(count, :) = temp(index, 1:end-1);  % 记录当前温度的最优路线
    %降温
    T0 = q * T0;
end

%% VII. 优化过程迭代图
figure
plot(1:count,Obj)
xlabel('迭代次数')
ylabel('距离')
title('优化过程')

%% VIII. 绘制最优路径图
DrawPath(track(end,:),X)

%% IX. 输出最优解的路线和总距离
disp('最优解:')
S = track(end,:);
p = OutputPath(S);
disp(['总距离:',num2str(PathLength(D,S))]);

五,结果分析

优化前的一个随机路线轨迹图如图2所示。

初始种群中的一个随机值:
11>1>14>12>7>13>2>9>10>4>8>5>3>6>11
总距离:62.0785

优化后的路线如图3所示。

最优解:
6>12>7>13>8>11>9>10>1>2>14>3>4>5>6
总距离:29.3405
图2 随机路线图

在这里插入图片描述

图3 最优解路线图

在这里插入图片描述

优化迭代过程如图4所示。

图4 模拟退火算法优化过程图

在这里插入图片描述

由图4可以看出,优化前后路径长度得到很大改进,由优化前的64.7606变为29.8332,变为原来的46.1%,600多代以后路径长度已经保持不变了,可以认为已经是最优解了。

六,算法的改进

(1)使用逆转操作,即选择两个城市后,逆转这两个城市之间的所有城市。
(2)选择3个城市,将两个城市之间的城市插入到第3个城市的后面(这两个城市之间不包括第3个城市)。

七,算法的局限性

问题规模 n n n比较小时,得到的一般都是最优解,但当规模比较大时,一般只能得到近似解。这时可以通过增大种群大小和增加最大迭代次数使优化值更接近最优解。

八,参考文献

[1] 张建航, 李国. 模拟退火算法及其在求解TSP中的应用[J]. 现代电子技术, 2006, 29(22): 157-158.
[2] 盛国华, 陈玉金. 改进模拟退火算法求解TSP问题[J]. 电脑知识与技术, 2008(15): 129-130+156.
[3] 郁磊, 史峰, 王辉, 等. MATLAB智能算法30个案例分析(第2版)[M]. 北京: 北京航空航天大学出版社, 2015.

  • 20
    点赞
  • 153
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
模拟退火算法是一种基于模拟金属冶炼过程的算法,它通过模拟固体物体加热冷却时的微观分子运动和有序结构的变化来优化问题。 TSP问题(Traveling Salesman Problem)是一个经典的组合优化问题,目标是找到最短路径,使得旅行商经过所有城市后回到出发点。而使用模拟退火算法解决TSP问题,可以在一定时间内找到一个比较优解。 首先,在MATLAB中实现TSP问题模拟退火算法,需要定义一个距离矩阵来表示城市之间的距离。然后,初始化一个路径,并计算该路径的总距离。 接下来,我们需要进行若干次的迭代过程。迭代过程中,通过随机交换两个城市的位置来生成新的路径,并计算新路径的总距离。如果新路径的总距离比当前路径更小,说明找到了一个更优的解,那么接受这个解。如果新路径的总距离比当前路径大,根据一定的概率(退火原理),也有可能接受这个解。通过不断地迭代,模拟退火算法可以逐渐逼近最优解。 在MATLAB中,可以使用随机函数来实现路径的随机交换。比如,可以使用randi函数来随机选择两个城市,并交换它们的位置。然后,用sum函数计算路径的总距离。 需要注意的是,模拟退火算法有很多参数需要调整。例如,初始温度、降温速度、停止温度和每个温度下的迭代次数等。这些参数的选择对算法的性能和结果都有影响,需要进行实验和调优。 综上所述,通过在MATLAB中实现模拟退火算法解决TSP问题,可以找到一个较优解。通过合理选择参数和调优算法,可以提高算法的性能和结果的质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心️升明月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值