用python來編寫TSP問題
阿新 • • 發佈:2018-12-16
import math from os import path import numpy as np import matplotlib.pyplot as plt class TSPInstance: ''' 設計一個類,實現從檔案讀入一個旅行商問題的例項 檔案格式為: city number best known tour length list of city position (index x y) best known tour (city index starts from 1) 以檔案01eil51.txt為例: 第一行51為城市數 第二行426為最優解的路徑長度 第三行開始的51行為各個城市的序號、x座標和y座標 最後是最優解的訪問城市系列(注意裡面城市序號從1開始,而python的sequence是從0開始) Eil51Tour.png是最優解的城市訪問順序圖 ''' def __init__(self, file_name): ''' 從檔案file_name讀入旅行商問題的資料 ''' self.file_name=file_name a= open(file_name) # 城市數量 self.city_num = a.readline() # 返回座標 51行,3列 self.city = np.zeros((int(self.city_num), 3)) # x座標 self.x = np.zeros(int(self.city_num)) # y座標 self.y = np.zeros(int(self.city_num)) # 城市ID self.id = np.zeros(int(self.city_num)) b = a.readlines() for i, content in enumerate(b): if i in range(1, 52 ): # 單行賦值 self.city[i-1] = content.strip('\n').split(' ') self.x[i-1] = self.city[i-1][1] self.y[i-1] = self.city[i-1][2] for i, content in enumerate(b): if i in range(53, 104): self.id[i - 53] = content.strip('\n') @property def citynum(self): ''' 返回城市數 ''' return self.city_num @property def optimalval(self): ''' 返回最優路徑長度 ''' c = 0 i = 1 s = open(self.file_name) str = s.readlines() for content in str: if i == 2: c = content i = i + 1 return c @property def optimaltour(self): ''' 返回最優路徑 ''' tour = np.array(self.id) return tour def __getitem__(self, n): ''' 返回城市n的座標,由x和y構成的tuple:(x,y) ''' (x, y) = (self.x[n-1], self.y[n-1]) return (x, y) def get_distance(self, n, m): ''' 返回城市n、m間的整數距離(四捨五入) ''' u=int(self.x[n-1] - self.x[m-1]) v=int(self.y[n-1] - self.y[m-1]) dis = math.sqrt(pow(u,2) + pow(v,2)) return int(dis+0.5) def evaluate(self, tour): ''' 返回訪問系列tour所對應的路徑程度 ''' dis = 0 for i in range(50): dis += self.get_distance(int(tour[i]), int(tour[i + 1])) dis += self.get_distance(int(tour[50]), int(tour[0])) return dis def plot_tour(self, tour): ''' 畫出訪問系列tour所對應的路徑路 ''' for i in range(51): x0,y0 = self.__getitem__(i) plt.scatter(int(x0),int(y0),s=10,c='c') #記住座標點的畫法 for i in range(len(tour)-1): x1,y1 = self.__getitem__(int(tour[i])) x,y = self.__getitem__(int(tour[i+1])) plt.plot([x1,x],[y1,y],c='b') x2,y2 = self.__getitem__(int(tour[0])) x3,y3 = self.__getitem__(int(tour[len(tour)-1])) plt.plot([x2,x3],[y2,y3],c='b') plt.xlabel('x label') plt.ylabel('y label') plt.title("City access sequence diagram") plt.plot() plt.show() if __name__ == "__main__": file_name = path.dirname(__file__) + "/1.txt" instance = TSPInstance(file_name) print(instance.citynum) print(instance.evaluate(instance.optimaltour)) print(instance.optimaltour) print(instance.__getitem__(2)) print(instance.get_distance(0, 1)) instance.plot_tour(instance.optimaltour) ''' output: 51 426 [ 1. 22. 8. 26. 31. 28. 3. 36. 35. 20. 2. 29. 21. 16. 50. 34. 30. 9. 49. 10. 39. 33. 45. 15. 44. 42. 40. 19. 41. 13. 25. 14. 24. 43. 7. 23. 48. 6. 27. 51. 46. 12. 47. 18. 4. 17. 37. 5. 38. 11. 32.] (49.0, 49.0) 14 '''
其實解決TSP問題有很多方法,比如模擬退火演算法,貪心演算法,回溯演算法等等。希望各位博友可以把你們的解決方法出現在評論區。