模拟退火算法-旅行商问题-matlab实现
Posted dawn-bin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模拟退火算法-旅行商问题-matlab实现相关的知识,希望对你有一定的参考价值。
整理一下数学建模会用到的算法,供比赛时候参考食用。
——————————————————————————————————————————
旅行商问题(TSP):
给定一系列城市和每对城市之间的距离,求解访问每一座城市一次并回到起始城市的最短回路。
它是组合优化中的一个NP困难问题,在运筹学和理论计算机科学中非常重要。
以下两个程序,在不同数据集合情况下表现有所差别,理论上第一个程序的解更为优化。
1 clear 2 clc 3 a = 0.99; %温度衰减函数的参数 4 t0 = 97; %初始温度 5 tf = 3; %终止温度 6 t = t0; 7 Markov_length = 10000; %Markov链长度 8 9 % load data.txt 10 % x = data(:, 1:2:8); x = x(:); 11 % y = data(:, 2:2:8); y = y(:); 12 % data = [70,40;x, y]; 13 % coordinates = data; 14 coordinates = [ 15 1 565.0 575.0; 2 25.0 185.0; 3 345.0 750.0; 16 4 945.0 685.0; 5 845.0 655.0; 6 880.0 660.0; 17 7 25.0 230.0; 8 525.0 1000.0; 9 580.0 1175.0; 18 10 650.0 1130.0; 11 1605.0 620.0; 12 1220.0 580.0; 19 13 1465.0 200.0; 14 1530.0 5.0; 15 845.0 680.0; 20 16 725.0 370.0; 17 145.0 665.0; 18 415.0 635.0; 21 19 510.0 875.0; 20 560.0 365.0; 21 300.0 465.0; 22 22 520.0 585.0; 23 480.0 415.0; 24 835.0 625.0; 23 25 975.0 580.0; 26 1215.0 245.0; 27 1320.0 315.0; 24 28 1250.0 400.0; 29 660.0 180.0; 30 410.0 250.0; 25 31 420.0 555.0; 32 575.0 665.0; 33 1150.0 1160.0; 26 34 700.0 580.0; 35 685.0 595.0; 36 685.0 610.0; 27 37 770.0 610.0; 38 795.0 645.0; 39 720.0 635.0; 28 40 760.0 650.0; 41 475.0 960.0; 42 95.0 260.0; 29 43 875.0 920.0; 44 700.0 500.0; 45 555.0 815.0; 30 46 830.0 485.0; 47 1170.0 65.0; 48 830.0 610.0; 31 49 605.0 625.0; 50 595.0 360.0; 51 1340.0 725.0; 32 52 1740.0 245.0; 33 ]; 34 coordinates(:,1) = []; 35 amount = size(coordinates,1); %城市的数目 36 %通过向量化的方法计算距离矩阵 37 dist_matrix = zeros(amount,amount); 38 coor_x_tmp1 = coordinates(:,1) * ones(1,amount); 39 coor_x_tmp2 = coor_x_tmp1‘; 40 coor_y_tmp1 = coordinates(:,2) * ones(1,amount); 41 coor_y_tmp2 = coor_y_tmp1‘; 42 dist_matrix = sqrt((coor_x_tmp1 - coor_x_tmp2).^2 + (coor_y_tmp1 - coor_y_tmp2).^2); 43 44 45 sol_new = 1:amount; %产生初始解,sol_new是每次产生的新解 46 sol_current = sol_new; %sol_current是当前解 47 sol_best = sol_new; %sol_best是冷却中的最好解 48 E_current = inf; %E_current是当前解对应的回路距离 49 E_best = inf; %E_best是最优解 50 p = 1; 51 52 53 rand(‘state‘, sum(clock)); 54 55 for j = 1:10000 56 sol_current = [randperm(amount)]; 57 E_current = 0; 58 for i=1:(amount-1) 59 E_current = E_current+dist_matrix(sol_current(i), sol_current(i+1)); 60 end 61 if E_current<E_best 62 sol_best = sol_current; 63 E_best = E_current; 64 end 65 end 66 67 68 69 70 while t >= tf 71 for r = 1:Markov_length %Markov链长度 72 %产生随机扰动 73 if(rand < 0.5) 74 %两交换 75 ind1 = 0; 76 ind2 = 0; 77 while(ind1 == ind2) 78 ind1 = ceil(rand * amount); 79 ind2 = ceil(rand * amount); 80 end 81 tmp1 = sol_new(ind1); 82 sol_new(ind1) = sol_new(ind2); 83 sol_new(ind2) = tmp1; 84 else 85 %三交换 86 ind1 = 0; 87 ind2 = 0; 88 ind3 = 0; 89 while( (ind1 == ind2) || (ind1 == ind3) || (ind2 == ind3) || (abs(ind1 -ind2) == 1) ) 90 ind1 = ceil(rand * amount); 91 ind2 = ceil(rand * amount); 92 ind3 = ceil(rand * amount); 93 end 94 tmp1 = ind1; 95 tmp2 = ind2; 96 tmp3 = ind3; 97 %确保 ind1 < ind2 < ind3 98 if(ind1 < ind2) && (ind2 < ind3); 99 elseif(ind1 < ind3) && (ind3 < ind2) 100 ind1 = tmp1; ind2 = tmp3; ind3 = tmp2; 101 elseif(ind2 < ind1) && (ind1 < ind3) 102 ind1 = tmp2; ind2 = tmp1; ind3 = tmp3; 103 elseif(ind2 < ind3) && (ind3 < ind1) 104 ind1 = tmp2; ind2 = tmp3; ind3 = tmp1; 105 elseif(ind3 < ind1) && (ind1 < ind2) 106 ind1 = tmp3; ind2 = tmp1; ind3 = tmp2; 107 elseif(ind3 < ind2) && (ind2 < ind1) 108 ind1 = tmp3; ind2 = tmp2; ind3 = tmp1; 109 end 110 111 tmplist1 = sol_new((ind1 + 1):(ind2 - 1)); 112 sol_new((ind1 + 1):(ind1 + (ind3 - ind2 + 1) )) = sol_new((ind2):(ind3)); 113 sol_new((ind1 + (ind3 - ind2 + 1) + 1):(ind3)) = tmplist1; 114 end 115 116 %检查是否满足约束 117 118 %计算目标函数值(即内能) 119 E_new = 0; 120 for i = 1:(amount - 1) 121 E_new = E_new + dist_matrix(sol_new(i),sol_new(i + 1)); 122 end 123 %再算上从最后一个城市到第一个城市的距离 124 E_new = E_new + dist_matrix(sol_new(amount),sol_new(1)); 125 126 if E_new < E_current 127 E_current = E_new; 128 sol_current = sol_new; 129 if E_new < E_best 130 E_best = E_new; 131 sol_best = sol_new; 132 end 133 else 134 %若新解的目标函数值大于当前解, 135 %则仅以一定概率接受新解 136 if rand < exp(-(E_new - E_current) / t) 137 E_current = E_new; 138 sol_current = sol_new; 139 else 140 sol_new = sol_current; 141 end 142 143 end 144 end 145 146 t = t * a; %控制参数t(温度)减少为原来的a倍 147 end 148 149 E_best = E_best+dist_matrix(sol_best(end), sol_best(1)); 150 151 disp(‘最优解为:‘); 152 disp(sol_best); 153 disp(‘最短距离:‘); 154 disp(E_best); 155 156 data1 = zeros(length(sol_best),2 ); 157 for i = 1:length(sol_best) 158 data1(i, :) = coordinates(sol_best(1,i), :); 159 end 160 161 data1 = [data1; coordinates(sol_best(1,1),:)]; 162 163 164 figure 165 plot(coordinates(:,1)‘, coordinates(:,2)‘, ‘*k‘, data1(:,1)‘, data1(:, 2)‘, ‘r‘); 166 title( [ ‘近似最短路径如下,路程为‘ , num2str( E_best ) ] ) ;
另一种根据《数学建模算法与应用—司守奎》中算法改编:
clc; clear; close all; coordinates = [ 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) = []; data = coordinates; % 读取数据 % load data.txt; % x = data(:, 1:2:8); x = x(:); % y = data(:, 2:2:8); y = y(:); x = data(:, 1); y = data(:, 2); start = [565.0 575.0]; data = [start; data;start]; % data = [start; x, y;start]; % data = data*pi/180; % 计算距离的邻接表 count = length(data(:, 1)); d = zeros(count); for i = 1:count-1 for j = i+1:count % temp = cos(data(i, 1)-data(j,1))*cos(data(i,2))*cos(data(j,2))... % +sin(data(i,2))*sin(data(j,2)); d(i,j)=( sum( ( data( i , : ) - data( j , : ) ) .^ 2 ) ) ^ 0.5 ; % d(i,j) = 6370*acos(temp); end end d =d + d‘; % 对称 i到j==j到i S0=[]; % 存储初值 Sum=inf; % 存储总距离 rand(‘state‘, sum(clock)); % 求一个较为优化的解,作为初值 for j = 1:10000 S = [1 1+randperm(count-2), count]; temp = 0; for i=1:count-1 temp = temp+d(S(i), S(i+1)); end if temp<Sum S0 = S; Sum = temp; end end e = 0.1^40; % 终止温度 L = 2000000; % 最大迭代次数 at = 0.999999; % 降温系数 T = 2; % 初温 % 退火过程 for k = 1:L % 产生新解 c =1+floor((count-1)*rand(1,2)); c = sort(c); c1 = c(1); c2 = c(2); if c1==1 c1 = c1+1; end if c2==1 c2 = c2+1; end % 计算代价函数值 df = d(S0(c1-1), S0(c2))+d(S0(c1), S0(c2+1))-... (d(S0(c1-1), S0(c1))+d(S0(c2), S0(c2+1))); % 接受准则 if df<0 S0 = [S0(1: c1-1), S0(c2:-1:c1), S0(c2+1:count)]; Sum = Sum+df; elseif exp(-df/T) > rand(1) S0 = [S0(1: c1-1), S0(c2:-1:c1), S0(c2+1:count)]; Sum = Sum+df; end T = T*at; if T<e break; end end data1 = zeros(2, count); % y1 = [start; x, y; start]; for i =1:count data1(:, i) = data(S0(1,i), :)‘; end figure plot(x, y, ‘o‘, data1(1, :), data1(2, :), ‘r‘); title( [ ‘近似最短路径如下,路程为‘ , num2str( Sum ) ] ) ; disp(Sum); S0
以上是关于模拟退火算法-旅行商问题-matlab实现的主要内容,如果未能解决你的问题,请参考以下文章
matlab解决TSP问题(货郎担问题,旅行商问题)的模拟退火算法
matlab解决TSP问题(货郎担问题,旅行商问题)的模拟退火算法
matlab最短路径问题(旅行商模型)—模拟退火算法禁忌搜索算法解决中国省会间最短路径问题