解題思路主要有兩部分:
第一部分:i為當前節點(城市),s為還沒有遍歷的節點(城市集合),
第二部分,回溯,找到最優的路徑,需要將s集合一一對應乙個數字(類似於編碼,一般用二進位制),不如
# tsp問題
class solution:
def __init__(self,x,start_node):
self.x = x #距離矩陣
self.start_node = start_node #開始的節點
self.array = [[0]*(2**len(self.x)) for i in range(len(self.x))] #記錄處於x節點,未經歷m個節點時,矩陣儲存x的下一步是m中哪個節點
def transfer(self,sets):
su = 0
for s in sets:
su = su + 2**s # 二進位制轉換
return su
# tsp總介面
def tsp(self):
s = self.start_node
num = len(self.x)
cities = range(num) #形成節點的集合
past_sets = [s] #已遍歷節點集合
cities.pop(cities.index(s)) #構建未經歷節點的集合
node = s #初始節點
return self.solve(node,cities) #求解函式
def solve(self,node,future_sets):
# 迭代終止條件,表示沒有了未遍歷節點,直接連線當前節點和起點即可
if len(future_sets) == 0:
return self.x[node][self.start_node]
d = 99999
# node如果經過future_sets中節點,最後回到原點的距離
distance =
# 遍歷未經歷的節點
for i in range(len(future_sets)):
s_i = future_sets[i]
copy = future_sets[:]
copy.pop(i) # 刪除第i個節點,認為已經完成對其的訪問
# 動態規劃遞推方程,利用遞迴
d = min(distance)
# node需要連線的下乙個節點
next_one = future_sets[distance.index(d)]
# 未遍歷節點集合
c = self.transfer(future_sets)
# 回溯矩陣,(當前節點,未遍歷節點集合)——>下乙個節點
self.array[node][c] = next_one
return d
d = [[-1,10,20,30,40,50],[12,-1,18,30,25,21],[23,19,-1,5,10,15],[34,32,4,-1,8,16],[45,27,11,10,-1,18],[56,22,16,20,12,-1]]
s = solution(d,0)
print s.tsp()
# 開始回溯
m = s.array
lists = range(len(s.x))
start = s.start_node
while len(lists) > 0:
lists.pop(lists.index(start))
m = s.transfer(lists)
next_node = s.array[start][m]
print start,"--->" ,next_node
start = next_node
動態規劃求解TSP圈
求解思路 動態規劃的方法的最大難點就在於初始變數的確定,選擇合適的初始變數才能更好的運用動態規劃的方式解決問題。我在這裡定義的變數就是d i,s 設s出發點,其中i是乙個點,而s是點的集合,這個變數的意思就是從i出發,經過s中的所有點一次且僅一次且回到出發點s的最小距離。當s為空時,就表示i到起始點...
TSP問題求解方法
原文 一名旅行商準備前往若干個城市推銷他的產品,他想要從駐地出發,經過每個城市恰好一次,最後返回駐地,求滿足條件的最短路徑。這便是旅行商問題。旅行商問題是乙個np問題,至今尚未有準確的解法,現有的演算法只能盡可能減小誤差。目前最優的演算法能在誤差1 範圍內估計上百萬個城市的問題。改良圈演算法的思想是...
動態規劃法求解TSP問題 C
此文章借鑑於博文在此基礎上重新進行了分析總結。1 怎麼求頂點子集,即這些怎麼記錄?答 例如4個頂點,依次為 十進位制數0 1 2 3 4 5 6 7的二進位制分別為000 001 010 011 100 101 110 111。上述集合中的元素即為二進位制中的位數,例如集合,可用二進位制110 十進...