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...