TSP模拟退火算法的MATLAB实现

TSPLIB是一组各类TSP问题的实例集合。这里以TSPLIB中的berlin52为例进行求解。berlin52有52座城市。

% TSP模拟退火算法

clear
    clc
    a = 0.99;       %温度衰减函数的参数
    t0 = 97;        %初始温度
    tf = 3;         %终止温度
    t = t0;
    Markov_length = 10000;  %Markov链长度
    
coordinates = [
1	 565.0	 575.0;	2	  25.0	 185.0;	3	 345.0	 750.0;	
4	 945.0	 685.0;	5	 845.0	 655.0;	6	 880.0	 660.0;	
7	  25.0	 230.0;	8	 525.0	1000.0;	9	 580.0	1175.0;	
10	 650.0	1130.0;	11	1605.0	 620.0;	12	1220.0	 580.0;	
13	1465.0	 200.0;	14	1530.0	   5.0;	15	 845.0	 680.0;	
16	 725.0	 370.0;	17	 145.0	 665.0;	18	 415.0	 635.0;	
19	 510.0	 875.0;	20	 560.0	 365.0;	21	 300.0	 465.0;	
22	 520.0	 585.0;	23	 480.0	 415.0;	24	 835.0	 625.0;	
25	 975.0	 580.0;	26	1215.0	 245.0;	27	1320.0	 315.0;	
28	1250.0	 400.0;	29	 660.0	 180.0;	30	 410.0	 250.0;	
31	 420.0	 555.0;	32	 575.0	 665.0;	33	1150.0	1160.0;	
34	 700.0	 580.0;	35	 685.0	 595.0;	36	 685.0	 610.0;	
37	 770.0	 610.0;	38	 795.0	 645.0;	39	 720.0	 635.0;	
40	 760.0	 650.0;	41	 475.0	 960.0;	42	  95.0	 260.0;	
43	 875.0	 920.0;	44	 700.0	 500.0;	45	 555.0	 815.0;	
46	 830.0	 485.0;	47	1170.0	  65.0;	48	 830.0	 610.0;	
49	 605.0	 625.0;	50	 595.0	 360.0;	51	1340.0	 725.0;	
52	1740.0	 245.0;	
];

coordinates(:,1) = [];
amount = size(coordinates,1);        %城市的数目
%通过向量化的方法计算距离矩阵
dist_matrix = zeros(amount,amount);
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_new;      %sol_current是当前解
sol_best = sol_new;         %sol_best是冷却中的最好解
E_current = inf;            %E_current是当前解对应的回路距离
E_best = inf;               %E_best是最优解
p = 1;

while t >= tf
   for r = 1:Markov_length      %Markov链长度
    %产生随机扰动
    if(rand < 0.5)
        %两交换
        ind1 = 0;
        ind2 = 0;
        while(ind1 == ind2)
           ind1 = ceil(rand * amount);
           ind2 = ceil(rand * amount);
        end
        tmp1 = sol_new(ind1);
        sol_new(ind1) = sol_new(ind2);
        sol_new(ind2) = tmp1;
    else
        %三交换
        ind1 = 0;
        ind2 = 0;
        ind3 = 0;
        while( (ind1 == ind2) || (ind1 == ind3) || (ind2 == ind3) || (abs(ind1 -ind2) == 1) )
            ind1 = ceil(rand * amount);
            ind2 = ceil(rand * amount);
            ind3 = ceil(rand * amount);
        end
        tmp1 = ind1;
        tmp2 = ind2;
        tmp3 = ind3;
        %确保 ind1 < ind2 < ind3
        if(ind1 < ind2) && (ind2 < ind3);
        elseif(ind1 < ind3) && (ind3 < ind2)
            ind1 = tmp1; ind2 = tmp3; ind3 = tmp2;
        elseif(ind2 < ind1) && (ind1 < ind3)
            ind1 = tmp2; ind2 = tmp1; ind3 = tmp3;
        elseif(ind2 < ind3) && (ind3 < ind1)
            ind1 = tmp2; ind2 = tmp3; ind3 = tmp1;
        elseif(ind3 < ind1) && (ind1 < ind2)
            ind1 = tmp3; ind2 = tmp1; ind3 = tmp2;
        elseif(ind3 < ind2) && (ind2 < ind1)
            ind1 = tmp3; ind2 = tmp2; ind3 = tmp1;
        end
        
        tmplist1 = sol_new((ind1 + 1):(ind2 - 1));
        sol_new((ind1 + 1):(ind1 + (ind3 - ind2 + 1) )) = sol_new((ind2):(ind3));
        sol_new((ind1 + (ind3 - ind2 + 1) + 1):(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 * a;      %控制参数t(温度)减少为原来的a倍
end

disp('最优解为:');
disp(sol_best);
disp('最短距离:');
disp(E_best);

对于berlin52,已用分支裁剪或分支定界法证明最优解为7542。

你可能感兴趣的:(Matlab)