用Python解決TSP問題(2)——動態規劃演算法
阿新 • • 發佈:2019-01-08
本介紹用python解決TSP問題的第二個方法——動態規劃法
演算法介紹
動態規劃演算法根據的原理是,可以將原問題細分為規模更小的子問題,並且原問題的最優解中包含了子問題的最優解。也就是說,動態規劃是一種將問題例項分解為更小的、相似的子問題,並存儲子問題的解而避免計算重複的子問題,以解決最優化問題的演算法策略。
我使用DP求解TSP問題的主要分為三個主要部分:
1) 假定我們從城市0出發,經過了所有城市,並返回到城市0。那麼我們需要記錄的資訊有:當前所在城市location,當前未遍歷的城市集合s。
2) 狀態轉移方程,狀態轉移方程是DP演算法的核心部分,它代表了子問題和原問題的關係,通過狀態轉移方程可以將原問題不斷細分為各個子問題。我們狀態轉移方程的定義如下所示:
T(s,init)代表的意思是從init點出發經過s中全部的點回到init的距離。
3) 構建T表記錄T的值,如果不去記錄每次遞迴的T值,那麼以後每次搜尋都要重新計算,就成了暴力搜尋。所以我們構建一個T表dp[s][init],記錄每次求出來的T函式值,即將T(s,init)的值記錄在dp[s][init]位置。
程式
輸入:
1 2066 2333
2 935 1304
3 1270 200
4 1389 700
5 984 2810
6 2253 478
7 949 3025
8 87 2483
9 3094 1883
10 2706 3130
程式碼:
""" 動態規劃法 name:xxx date:6.8 """ import pandas as pd import numpy as np import math import time dataframe = pd.read_csv("./data/TSP10cities.tsp",sep=" ",header=None) v = dataframe.iloc[:,1:3] train_v= np.array(v) train_d=train_v dist = np.zeros((train_v.shape[0],train_d.shape[0])) #計算距離矩陣 for i in range(train_v.shape[0]): for j in range(train_d.shape[0]): dist[i,j] = math.sqrt(np.sum((train_v[i,:]-train_d[j,:])**2)) """ N:城市數 s:二進位制表示,遍歷過得城市對應位為1,未遍歷為0 dp:動態規劃的距離陣列 dist:城市間距離矩陣 sumpath:目前的最小路徑總長度 Dtemp:當前最小距離 path:記錄下一個應該到達的城市 """ N=train_v.shape[0] path = np.ones((2**(N+1),N)) dp = np.ones((2**(train_v.shape[0]+1),train_d.shape[0]))*-1 def TSP(s,init,num): if dp[s][init] !=-1 : return dp[s][init] if s==(1<<(N)): return dist[0][init] sumpath=1000000000 for i in range(N): if s&(1<<i): m=TSP(s&(~(1<<i)),i,num+1)+dist[i][init] if m<sumpath: sumpath=m path[s][init]=i dp[s][init]=sumpath return dp[s][init] if __name__ == "__main__": init_point=0 s=0 for i in range(1,N+1): s=s|(1<<i) start = time.clock() distance=TSP(s,init_point,0) end = time.clock() s=0b11111111110 init=0 num=0 print(distance) while True: print(path[s][init]) init=int(path[s][init]) s=s&(~(1<<init)) num+=1 if num>9: break print("程式的執行時間是:%s"%(end-start))
結果: