Matlab学习手记——旅行商TSP问题:模拟退火法

  • 原理

Matlab学习手记——旅行商TSP问题:模拟退火法_第1张图片

Matlab学习手记——旅行商TSP问题:模拟退火法_第2张图片

Matlab学习手记——旅行商TSP问题:模拟退火法_第3张图片

Matlab学习手记——旅行商TSP问题:模拟退火法_第4张图片

  • 结果 

Matlab学习手记——旅行商TSP问题:模拟退火法_第5张图片

  • 坐标文件
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

 

你可能感兴趣的:(算法系列,Matlab学习手记)