節約里程法求解TSP問題

2021-10-23 09:47:27 字數 3890 閱讀 4294

clc

clear all

close all

c=[35,41,35,55,55,15,25,20,10,55,30,20,50,30,15,30,10,5,20,15,45,45,45,55,65,65,45,35,41,64,40,31,35,53,65,63,2,20,5,60,40,42,24,23,11,6,2,8,13,6,47,49,27,37,57,63,53,32,36,21,17,12,24,27,15,62,49,67,56,37,37,57,47,44,46,49,49,53,61,57,56,55,15,14,11,16,4,28,26,26,31,15,22,18,26,25,22,25,19,20,18;35,49,17,45,20,30,30,50,43,60,60,65,35,25,10,5,20,30,40,60,65,20,10,5,35,20,30,40,37,42,60,52,69,52,55,65,60,20,5,12,25,7,12,3,14,38,48,56,52,68,47,58,43,31,29,23,12,12,26,24,34,24,58,69,77,77,73,5,39,47,56,68,16,17,13,11,42,43,52,48,37,54,47,37,31,22,18,18,52,35,67,19,22,24,27,24,27,21,21,26,18;0,10,7,13,19,26,3,5,9,16,16,12,19,23,20,8,19,2,12,17,9,11,18,29,3,6,17,16,16,9,21,27,23,11,14,8,5,8,16,31,9,5,5,7,18,16,1,27,36,30,13,10,9,14,18,2,6,7,18,28,3,13,19,10,9,20,25,25,36,6,5,15,25,9,8,18,13,14,3,23,6,26,16,11,7,41,35,26,9,15,3,1,2,22,27,20,11,12,10,9,17]; 

w=1000; 

n=size(c,2);%m=size(c,1)

d=zeros(n,n);%距離矩陣

for i=1:n

for j=1:n

if i~=j

d(i,j)=sqrt(sum((c(:,i)-c(:,j)).^2));%歐氏距離

else

d(i,j)=eps;  %i=j時不計算,應該為0,但後面的啟發因子要取倒數,用eps(浮點相對精度)表示

endd(j,i)=d(i,j);  %對稱矩陣

endend

p=zeros(n-1,n-1);%計算節約里程數

for j=2:(n-1) 

for i=(j+1):n

p(i-1,j-1)=d(i,1)+d(j,1)-d(i,j);

endend

s=p(:); 

[hs,wz]=sort(s,1,'descend');%按節約里程的大小排序

hs(find(hs==0))=; 

for i=1:size(hs)

[sub(i,1),sub(i,2)]=ind2sub(size(p),wz(i)); %將p矩陣各元素索引轉換成座標,並儲存到sub矩陣,wz(1)=2726,隊以ing的hs值是114,996,是從27到26的。

end;

svt=[hs,sub];

route=zeros(n-1,n-1);

sv=0;%記錄節約的里程

for j=1:n-1

for i=1:size(svt) %求從最大節約值開始,可一起配送的兩個客戶,作為初始解

if c(3,(svt(i,2)+1))+c(3,(svt(i,3)+1))<=w %計算兩個客戶是否超重,

solut=[svt(i,2),svt(i,3)];

sv=sv+svt(i,1);

load=c(3,(solut(1,1)+1))+c(3,(solut(1,2)+1));%裝等於城市65+30的重量

ii=i;

break

endend

for i=(ii+1):size(svt)

if (svt(i,2)==solut(1,1))&&(isempty(find(svt(i,3)==solut))==1)&&((c(3,(svt(i,3)+1))+load)<=w); %從最大的小於初始解對應的最大節約值對應的座標判斷(左座標等於最優解的左座標,並且右座標不等於最優解的右座標,並且容量不超) 

olut=[svt(i,3),solut]; %如滿足條件,將右座標加到路徑的左側

sv=sv+svt(i,1);

load=c(3,(svt(i,3)+1))+load;

elseif (svt(i,2)==solut(1,length(solut)))&&(isempty(find(svt(i,3)==solut))==1)&&((c(3,(svt(i,3)+1))+load)<=w);

solut=[solut,svt(i,3)];

sv=sv+svt(i,1);

load=c(3,(svt(i,3)+1))+load;

elseif (svt(i,3)==solut(1,1))&&(isempty(find(svt(i,2)==solut))==1)&&((c(3,(svt(i,2)+1))+load)<=w);

solut=[svt(i,2),solut];

sv=sv+svt(i,1);

load=c(3,(svt(i,2)+1))+load;

elseif (svt(i,3)==solut(1,length(solut)))&&(isempty(find(svt(i,2)==solut))==1)&&((c(3,(svt(i,2)+1))+load)<=w);

solut=[solut,svt(i,2)];

sv=sv+svt(i,1);

load=c(3,(svt(i,2)+1))+load;

else continue

endend

for i=size(svt):-1:1 %刪除已經選到路徑中的點

if ((isempty(find(svt(i,2)==solut))==0)||(isempty(find(svt(i,3)==solut))==0));

svt(i,:)=;

else continue

endend

route(j,(1:length(solut)))=solut%將確定好的某一條路徑存到route矩陣的一行中

if isempty(svt) %直到判斷svt無元素,退出

break

endend

for i=1:n-1 %判斷route中沒有的單一使用者,增加一行,加入到route中

if (isempty(find(route(:)==i))==1)

route(j+1,1)=i;

j=j+1;

endend

opt=2*sum(d(:,1))-sv;

plot(c(1,1),c(2,1),'s')

text(c(1,1),c(2,1),['(',num2str(c(1,1)),',',num2str(c(2,1)),')'])

hold on;

for i=2:n

plot (c(1,i),c(2,i),'o')

text(c(1,i),c(2,i),['(',num2str(c(1,i)),',',num2str(c(2,i)),')'])

hold on;

endfor i=1:n-1

line([c(1,1),c(1,route(i,1)+1)],[c(2,1),c(2,route(i,1)+1)])

for j=1:n-1

if route(i,j)~=0

line([c(1,route(i,j)+1),c(1,route(i,j+1)+1)],[c(2,route(i,j)+1),c(2,route(i,j+1)+1)]) 

endend

end

TSP問題求解方法

原文 一名旅行商準備前往若干個城市推銷他的產品,他想要從駐地出發,經過每個城市恰好一次,最後返回駐地,求滿足條件的最短路徑。這便是旅行商問題。旅行商問題是乙個np問題,至今尚未有準確的解法,現有的演算法只能盡可能減小誤差。目前最優的演算法能在誤差1 範圍內估計上百萬個城市的問題。改良圈演算法的思想是...

1044 用分枝定界法求解TSP問題

用分枝定界法求解tsp問題 time limit 1000ms memory limit 65536k total submit 15 accepted 7 description 已知n個城市之間的相互距離,現有一推銷員必須遍訪這n個城市,並且每個城市只能訪問一次,最後又必須返回出發城市。如何安排...

模擬退火求解TSP問題

1.尋找下乙個解 2.計算下乙個解的能量 3.決定是否接受這個解 4.降溫 double randfloat double t0 1000000 tk 1,t t0,d 0.9999 int x initx 當前解 初始解 int anse,nowe 全域性最優解的能量,當前解的能量 anse no...