大規模旅行商問題解決方案(基於分層規劃,整數規劃)

2021-09-19 19:44:15 字數 3348 閱讀 5133

/*上週在無意間跟室友討論到tsp問題時,我覺得應該把這個問題整合一下,並給出自己的解決方案,同時**公布在github,有人做成其他版本的與其他人**共同進步。

無特別說明情況下,聚類指的是kmeans聚類*/

本文採用分層規劃的思想,層層聚類,直至最底層單個城市群數量滿足一定閾值,然後利用整數規劃求最底層城市群的精確解,單層之間的城市群路徑規劃同樣採用整數規劃求精確解,這裡的城市群路徑規劃指的是城市群的聚類中心之間的路徑規劃,最高層為閉合路徑的tsp問題,以下單層包括底層都為確定起點終點的不閉合tsp問題,這裡的不閉合tsp問題的起點終點貪心的由上一級城市群聚類中心求出的路徑來確定哪兩個城市群相鄰,並由此計算此相鄰城市群的最近子城市群對。

求出近似路徑後再進行區域性的隨機優化。

/簡單的講,模擬在全球尋找一條可以走遍所有城市的最短路,每個城市只能訪問一次,我們先找大範圍的路徑,如亞洲->非洲->歐洲->北美洲->南美洲->大洋洲->亞洲,然後在往下分層,比如非洲,先計算非洲與它的前驅亞洲後繼歐洲之間最近的國家對,比如是埃及-伊朗,利比亞-義大利,這樣確定了進入非洲的起點埃及,終點利比亞,在非洲國家之間解決走完所有國家且僅訪問一次的路徑,再針對其中某個國家進行分析,直至到底層的城市為止。最後路徑規劃出來後再對求出的路徑進行區域性的優化,特別需要關注的是包含起點終點部分的路徑。/

對於大規模tsp問題,尚沒有太好的有效解決方案,現在智慧型演算法如蟻群演算法,遺傳演算法,人工神經網路更為流行與實用。這些在其他文章中可以找到相應的內容。遺傳演算法(ga)尋解空間好大,我超喜歡ga的。

給定城市與城市間的連線關係,在有解的前提下,從起點出發,尋找一條路徑回到起點,這條路徑需要滿足經過所有城市,並且每個城市僅能經過一次。

首先利用分層規劃,層層聚類,直至最底層單個城市群數量滿足一定閾值,然後利用整數規劃求最底層城市群的精確解。

最高層為閉合路徑的tsp問題,以下單層包括底層都為確定起點終點的不閉合tsp問題,這裡的不閉合tsp問題的起點終點貪心的由上一級城市群聚類中心求出的路徑來確定哪兩個城市群相鄰,並由此計算此相鄰城市群的最近子城市群對。

單層之間的城市群路徑規劃同樣採用整數規劃求精確解,這裡的城市群路徑規劃指的是城市群的聚類中心之間的路徑規劃。

對於top層如下圖所示求閉合路徑

對於非top層,實則為確定起點終點的聚類中心之間的路徑規劃,如下圖。

對於子層,如果滿足子層節點中城市數量不超過一定閾值(整數規劃求精確解時間允許的城市數量),則不進行**,直接將其進入下一層。

整體結構類似於樹的廣搜,先處理頂層,再處理後續子層。採取乙個佇列儲存當前層的城市資訊。分支定界也讓計算複雜度得以控制。

推薦這篇文章optimization by integer programming

這個地方很詭異,建立轉化為閉合路徑的tsp問題來計算,比如我們可以增加了這樣一條規則:

virtual_node = rand();//設定乙個虛擬節點,隨機生成座標

virtual_node->start_node = 0;//虛擬節點到起始點的距離為0

virtual_node->end_node = 0;//虛擬節點到終止點的距離為0

virtual_node->other_nodes = inf;//虛擬節點到除了起點終點的其他節點的距離為很大乙個數值

注意,這個是在計算出距離之上直接修改,這個設定在實際上肯定不存在,因為這樣會導致起點終點直聯的距離不等於由經過虛擬節點的距離,不過這並不影響計算。

有了這個設定,在這樣的乙個閉合tsp問題中,肯定會包含一條start_node-virtual_node-end_node的路徑,去掉虛擬節點以及其兩邊,則為確定起點終點的路徑,而且因為虛擬節點到起點終點的距離均為0,計算時候也不影響優化結果,解仍然是最優的。

因為聚類中心數量並不大,而且可控,直接暴搜走起。

logicimp()

%初始化一些資料

city;maxcitynum;...

%分層處理

while(true)

%如果全部滿足底層條件,退出死迴圈

if allcitygroupminenough(citycell,maxcitynum)

break;

end%否則處理單層問題

todo

for i=1:citycelllength

%子城市群預處理

todo

%如果子城市群滿足不**條件,該子城市群出隊再入隊,跳過當前子城市群

if cur_city_group_x < maxcitynum

todo

continue;

end%子城市群邊界的處理

todo

%聚類得到類中心座標向量與分組

todo

%得到起始點與終止點

todo

%如果起點終點一樣,即產生衝突,改變乙個

todo

%規劃路徑,分為頂層與非頂層

if topflag == 1

circletspsolver();

topflag = 0;

else

tspsolver();

end%檢索排序子城市群,**的子節點入隊。

todo

endcitycell = citycellnew;

end%處理最底層

for i =1:citycelllength

%城市群預處理

todo

%底層最近鄰的起點終點

todo

%如果起點終點一樣,即產生衝突,改變乙個

todo

% 呼叫整數規劃

tspsolver();

%處理結果

todo

endend

在tsplib資料集上的測試(我們只測試個大規模的),與精確解穩定在10%的損失,不遜於一般**的方法的測試結果!

資料集名字1

最優解本文得到的解

比例ja9847

此實驗的**的github

Jar Hell 問題解決方案

最近看到溫紹錦的jvm基礎,裡面看到這個jar hell問題的解決方法,之前遇到過一次,是乙個資源檔案,當時覺得挺麻煩,不知道還有這個方法,很棒,特地整理了下,記錄到這裡來,這個部落格開了好長時間了,一直以來也懶得寫東西,以後會堅持更新些。classloader classloader thread...

top K問題解決方案

1.使用最大最小堆。求最大的數用最小堆,求最小的數用最大堆。2.quick select演算法。使用類似快排的思路,根據pivot劃分陣列。3.使用排序方法,排序後再尋找top k元素。4.使用選擇排序的思想,對前k個元素部分排序。5.將1000 個數分成m組,每組尋找top k個數,得到m k個數...

Ajax post亂碼問題解決方案

今天測試乙個ajax元件的時候遇到亂碼問題,在網上找了很多解決方案都未能解決,原因可能我出現亂碼的問題不在傳輸過程,而且是在頁面上就已經出現亂碼了,現象很奇怪,我直接把引數賦值為中文後alert,發現是亂碼,所以不管我怎麼設定和在後台解碼都依然是亂碼。後來找到原因,共分兩點 第一 我的meta標籤設...