- 原理
- 结果
- 坐标文件
5.6500000e+02 5.7500000e+02
2.5000000e+01 1.8500000e+02
3.4500000e+02 7.5000000e+02
9.4500000e+02 6.8500000e+02
8.4500000e+02 6.5500000e+02
8.8000000e+02 6.6000000e+02
2.5000000e+01 2.3000000e+02
5.2500000e+02 1.0000000e+03
5.8000000e+02 1.1750000e+03
6.5000000e+02 1.1300000e+03
1.6050000e+03 6.2000000e+02
1.2200000e+03 5.8000000e+02
1.4650000e+03 2.0000000e+02
1.5300000e+03 5.0000000e+00
8.4500000e+02 6.8000000e+02
7.2500000e+02 3.7000000e+02
1.4500000e+02 6.6500000e+02
4.1500000e+02 6.3500000e+02
5.1000000e+02 8.7500000e+02
5.6000000e+02 3.6500000e+02
3.0000000e+02 4.6500000e+02
5.2000000e+02 5.8500000e+02
4.8000000e+02 4.1500000e+02
8.3500000e+02 6.2500000e+02
9.7500000e+02 5.8000000e+02
1.2150000e+03 2.4500000e+02
1.3200000e+03 3.1500000e+02
1.2500000e+03 4.0000000e+02
6.6000000e+02 1.8000000e+02
4.1000000e+02 2.5000000e+02
4.2000000e+02 5.5500000e+02
5.7500000e+02 6.6500000e+02
1.1500000e+03 1.1600000e+03
7.0000000e+02 5.8000000e+02
6.8500000e+02 5.9500000e+02
6.8500000e+02 6.1000000e+02
7.7000000e+02 6.1000000e+02
7.9500000e+02 6.4500000e+02
7.2000000e+02 6.3500000e+02
7.6000000e+02 6.5000000e+02
4.7500000e+02 9.6000000e+02
9.5000000e+01 2.6000000e+02
8.7500000e+02 9.2000000e+02
7.0000000e+02 5.0000000e+02
5.5500000e+02 8.1500000e+02
8.3000000e+02 4.8500000e+02
1.1700000e+03 6.5000000e+01
8.3000000e+02 6.1000000e+02
6.0500000e+02 6.2500000e+02
5.9500000e+02 3.6000000e+02
1.3400000e+03 7.2500000e+02
1.7400000e+03 2.4500000e+02
- 源码
function [sol_best, E_best] = SAA_TSP(coordinates, Markov_length, ratio, t_start, t_end)
%{
函数功能:模拟退火求解旅行商问题;
输入:
coordinates:城市坐标,两列;
Markov_length:Markov 链长度;
ratio:温度衰减系数;
t_start:初始温度;
t_end:结束温度;
输出:
sol_best:最优路线;
E_best:最短距离;
示例:
clear; clc;
ratio = 0.99;
t_start = 100;
t_end = 1;
Markov_length = 5000;
coordinates = load('CityCoordinates.txt');
[sol_best, E_best] = SAA_TSP(coordinates, Markov_length, ratio, t_start, t_end);
disp(['最优解为:', num2str(sol_best)]);
disp(['最短距离:', num2str(E_best)]);
x_path = [coordinates(sol_best, 1); coordinates(sol_best(1), 1)];
y_path = [coordinates(sol_best, 2); coordinates(sol_best(1), 2)];
plot(x_path, y_path, 'LineWidth', 2)
%}
% = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
if nargin < 5
t_end = 0.01 * t_start;
end
if nargin < 4
t_start = 100;
end
if nargin < 3
ratio = 0.99;
end
if nargin < 2
Markov_length = 5000;
end
if nargin < 1
error('输入参数不足!');
end
amount = size(coordinates,1); % 城市的数目
% 通过向量化的方法计算距离矩阵
coor_x_tmp1 = coordinates(:,1) * ones(1, amount);
coor_x_tmp2 = coor_x_tmp1';
coor_y_tmp1 = coordinates(:, 2) * ones(1, amount);
coor_y_tmp2 = coor_y_tmp1';
dist_matrix = sqrt((coor_x_tmp1 - coor_x_tmp2).^2 + (coor_y_tmp1 - coor_y_tmp2).^2);
sol_new = 1 : amount; % 产生初始解
% sol_new是每次产生的新解;sol_current是当前解;sol_best是冷却中的最好解;
% E_current是当前解对应的回路距离;E_new是新解的回路距离;E_best是最优解的
E_current = inf;
E_best = inf;
sol_current = sol_new;
sol_best = sol_new;
t = t_start;
while t >= t_end
% 当前温度下循环
for r = 1 : Markov_length
% 产生随机扰动
if (rand < 0.5) % 随机决定是进行两交换还是三交换
% 两交换
ind = randperm(amount, 2);
ind1 = ind(1);
ind2 = ind(2);
tmp1 = sol_new(ind1);
sol_new(ind1) = sol_new(ind2);
sol_new(ind2) = tmp1;
else
% 三交换
ind = randperm(amount, 3);
% 确保ind1 < ind2 < ind3
ind = sort(ind);
ind1 = ind(1);
ind2 = ind(2);
ind3 = ind(3);
tmplist1 = sol_new(ind1 + 1 : ind2 - 1);
sol_new(ind1 + 1 : ind1 + ind3 - ind2 + 1) = sol_new(ind2 : ind3);
sol_new(ind1 + ind3 - ind2 + 2 : ind3) = tmplist1;
end
% 计算目标函数值
E_new = 0;
for i = 1 : amount - 1
E_new = E_new + dist_matrix(sol_new(i), sol_new(i + 1));
end
% 再算上从最后一个城市到第一个城市的距离
E_new = E_new + dist_matrix(sol_new(amount), sol_new(1));
if E_new < E_current
E_current = E_new;
sol_current = sol_new;
if E_new < E_best
% 把冷却过程中最好的解保存下来
E_best = E_new;
sol_best = sol_new;
end
else
% 若新解的目标函数值大于当前解的,则仅以一定概率接受新解
if rand < exp(-(E_new - E_current)/t)
E_current = E_new;
sol_current = sol_new;
else
sol_new = sol_current;
end
end
end
t = t * ratio; % 降温
end