📄 tsp.m
字号:
function out = tsp(loc)
% TSP Traveling salesman problem (TSP) using SA (simulated annealing).
% TSP by itself will generate 20 cities within a unit cube and
% then use SA to slove this problem.
%
% TSP(LOC) solve the traveling salesman problem with cities'
% coordinates given by LOC, which is an M by 2 matrix and M is
% the number of cities.
%
% For example:
%
% loc = rand(50, 2);
% tsp(loc);
if nargin == 0,
% The following data is from the post by Jennifer Myers (jmyers@nwu.edu)
% to comp.ai.neural-nets. It's obtained from the figure in
% Hopfield & Tank's 1985 paper in Biological Cybernetics
% (Vol 52, pp. 141-152).
loc = [3.64,2.68 %beijing
4.18,1.76 %shanghai
3.71,2.60 %tianjin
2.77,1.50 %chongqing
1.33,3.30 %wulumuqi
4.20,2.96 %shenyang
4.39,3.43 %haerbing
3.92,1.82 %nanjing
4.26,1.07 %taibei
2.55,1.64 %chengdu
2.37,1.02 %kunming
3.43,2.09 %zhengzhou
3.54,0.70 %xianggang
3.51,1.62 %wuhan
3.44,0.80 %guangzhou
3.24,2.77 %huhehaote
2.38,2.32 %xiling
2.56,2.24 %lanzhou
3.01,2.03 %xian
2.79,2.51 %yinchuan
3.33,2.44 %taiyuan
2.94,0.76 %nanling
3.39,1.36 %changsha
3.49,2.46 %shijiazhuang
2.78,1.17 %guiyang
3.14,0.45 %haikou
4.31,3.21 %changcun
3.72,2.32 %jinan
4.06,1.63 %hangzhou
3.78,1.79 %hefei
3.68,1.42 %nancang
4.03,1.16 %fuzhou
3.47,0.70 %aomen
1.30,1.69]; %lasha
end
NumCity = length(loc); % Number of cities
distance = zeros(NumCity); % Initialize a distance matrix
% Fill the distance matrix
for i = 1:NumCity,
for j = 1:NumCity,
distance(i, j) = norm(loc(i, :) - loc(j, :));
end
end
% To generate energy (objective function) from path
%path = randperm(NumCity);
%energy = sum(distance((path-1)*NumCity + [path(2:NumCity) path(1)]));
% Find typical values of dE
count = 20;
all_dE = zeros(count, 1);
for i = 1:count
path = randperm(NumCity);
energy = sum(distance((path-1)*NumCity + [path(2:NumCity) path(1)]));
new_path = path;
index = round(rand(2,1)*NumCity+.5); %四舍五入
inversion_index = (min(index):max(index));
new_path(inversion_index) = fliplr(path(inversion_index));
all_dE(i) = abs(energy - ...
sum(sum(diff(loc([new_path new_path(1)],:))'.^2)));
end
dE = max(all_dE);
temp = 10*dE; % Choose the temperature to be large enough
fprintf('Initial energy = %f\n\n',energy);
% Initial plots
out = [path path(1)];
plot(loc(out(:), 1), loc(out(:), 2),'r.', 'Markersize', 20);
axis square; hold on
h = plot(loc(out(:), 1), loc(out(:), 2)); hold off
MaxTrialN = NumCity*100; % Max. # of trials at a temperature
MaxAcceptN = NumCity*10; % Max. # of acceptances at a temperature
StopTolerance = 0.005; % Stopping tolerance
TempRatio = 0.5; % Temperature decrease ratio
minE = inf; % Initial value for min. energy
maxE = -1; % Initial value for max. energy
% Major annealing loop
while (maxE - minE)/maxE > StopTolerance,
minE = inf;
maxE = 0;
TrialN = 0; % Number of trial moves
AcceptN = 0; % Number of actual moves
while TrialN < MaxTrialN & AcceptN < MaxAcceptN,
new_path = path;
index = round(rand(2,1)*NumCity+.5);
inversion_index = (min(index):max(index));
new_path(inversion_index) = fliplr(path(inversion_index));
new_energy = sum(distance( ...
(new_path-1)*NumCity+[new_path(2:NumCity) new_path(1)]));
if rand < exp((energy - new_energy)/temp), % accept it!
energy = new_energy;
path = new_path;
minE = min(minE, energy);
maxE = max(maxE, energy);
AcceptN = AcceptN + 1;
end
TrialN = TrialN + 1;
end
% Update plot
out = [path path(1)];
set(h, 'xdata', loc(out(:), 1), 'ydata', loc(out(:), 2));
drawnow;
% Print information in command window
fprintf('temp. = %f\n', temp);
tmp = sprintf('%d ',path);
fprintf('path = %s\n', tmp);
fprintf('energy = %f\n', energy);
fprintf('[minE maxE] = [%f %f]\n', minE, maxE);
fprintf('[AcceptN TrialN] = [%d %d]\n\n', AcceptN, TrialN);
% Lower the temperature
temp = temp*TempRatio;
end
% Print sequential numbers in the graphic window
for i = 1:NumCity,
text(loc(path(i),1)+0.01, loc(path(i),2)+0.01, int2str(i), ...
'fontsize', 8);
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -