1. 程式人生 > >TSP 模擬退火

TSP 模擬退火

none use 問題 prev splay element post desktop sym

TSP——模擬退火解法

都知道TSP是經典的NP問題,從一個點開始遍歷所有點,不重復,求最短路徑。

可以用枚舉終點,跑流量為2的最小費用,圖論來做,時間復雜度為 ? 費用流已經用到堆優化了。顯然點,邊較多將無法承受。

如果不要求精確解,使用模擬退火也是一個不錯的選擇。模型簡單,轉移很暴力。

先隨機生成一些解,然後隨機挑兩個點,開始試探轉移。

技術分享圖片

技術分享圖片

這裏,幾乎是按照退火算法模板寫的了,有初始化,有狀態轉移,有接受準則。

clc, clear
sj0=load(sj.txt);
x=sj0(:,[1:2:8]);x=x(:);
y=sj0(:,[2
:2:8]);y=y(:); sj=[x y]; d1=[70,40]; sj=[d1;sj;d1]; sj=sj*pi/180; d=zeros(102); for i=1:101 for j=i+1:102 d(i,j)=6370*acos(cos(sj(i,1)-sj(j,1))*cos(sj(i,2))*cos(sj(j,2))+sin(sj(i,2))*sin(sj(j,2))); end end d=d+d; path=[];long=inf; ? rand(state,sum(clock)); %初始化隨機數發生器 ? for j=1:1000
%求較好的初始解 path0=[1 1+randperm(100),102]; temp=0; for i=1:101 temp=temp+d(path0(i),path0(i+1)); end if temp<long path=path0; long=temp; end end ? e = 0.1^30; L = 20000; at = 0.999; T = 1; ? for k = 1:L c = 2+floor(100*rand(1,2)); c = sort(c); c1 = c(1
); c2 = c(2); df=d(path(c1-1),path(c2))+d(path(c1),path(c2+1))-d(path(c1-1),path(c1))-d(path(c2),path(c2+1)); if df < 0 path=[path(1:c1-1),path(c2:-1:c1),path(c2+1:102)]; long = long+df; elseif exp(-df/T)>rand path=[path(1:c1-1),path(c2:-1:c1),path(c2+1:102)]; long=long+df; end T = T*at; if T < e break; end end ? xx = sj(path,1); yy = sj(path,2); plot(xx,yy,-*);

TSP 模擬退火