狀態壓縮動態規劃 旅行商問題

2021-09-08 12:42:57 字數 2330 閱讀 6847

旅行商問題:

n個點(n<16)的帶權有向圖d,求一條路徑,使得這條路經過每乙個點恰好一次。

而且路徑上邊的權值和最小(或者最大),

或者求一條具有這樣性質的迴路。

狀態壓縮:

將二進位制表示十進位制數n的點集,

比方:

10 = 0000000000001010 代表第1和3個點已經路過

18 = 0000000000010010 代表第1和4個點已經路過

乙個整數就是乙個點集。

dp_arr[binary][to_]代表經過點集 binary 中,當前終點為to_,

且路徑最短的值。若該狀態不存在就是inf

狀態轉移:

單點集合:狀態存在dp_arr[1<

非單點集合:

dp_arr[binary][to] = min( dp_arr[from_bin][from_] + graph[from_][to] )

from_為 from_ 與 to 右邊相連,且dp_arr[from_bin][from_] 狀態存在,

且 dp_arr[from_bin][from_] 中的 from_bin 尚未包括 to 點資訊的一系列點。狀態不存在就為inf

最後結果:

min( dp_arr[( 1<

python:

inf = 1 << 10

graph = [

[0, 2, inf, 3],

[inf, 0, 6, 1],

[inf, 2, 0, 4],

[5, 1, 3, 0]

]state_list =

citys = 4

dp_arr = [ [ inf for i in xrange( citys ) ] for j in xrange( 1 << citys ) ]

class state:

def __init__( self, binary = none, end = none ):

self.binary = binary

self.end = end

def dp():

for to_ in range( citys ):

binary = 1 << to_

end = to_

dp_arr[binary][end] = 0

while len( state_list ):

pre = state_list.pop()

from_bin = pre.binary

from_ = pre.end

for to_ in xrange( citys ):

binary = 1 << to_

if binary & from_bin or graph[from_][to_] is inf:

continue

binary |= from_bin

next_state = state( binary, to_ )

distance = dp_arr[from_bin][from_] + graph[from_][to_]

dp_arr[binary][to_] = min( dp_arr[binary][to_], distance )

if __name__ == '__main__':

dp()

ans = min( [ dp_arr[( 1 << citys ) - 1][to_] for to_ in xrange( citys ) ] )

print ans

旅行商問題 狀態壓縮

二進位制的很多應用離不開集合這個概念,我們都知道在計算機當中,所有資料都是以二進位制的形式儲存的。一般乙個int整形是4個位元組,也就是32位bit,我們通過這32位bit上0和1的組合可以表示多大21億個不同的數。如果我們把這32位bit看成是乙個集合,那麼每乙個數都應該對應集合的一種狀態,並且每...

狀態壓縮DP 旅行商問題

題目描述 給定乙個n個頂點組成的帶權有向圖的距離矩陣d i j inf表示沒有邊 要求從頂點0出發,經過每個頂點恰好一次後再回到頂點0.問所經過的邊的總權重的最小值是多少?限制條件 題目解析 這個問題就是著名的旅行商問題 tsp 所有可能的路線有 n 1 種。這是乙個非常大的值,即使題中n已經很小了...

從旅行商問題談狀態壓縮DP

乙個商品推銷員要去若干個城市推銷商品,該推銷員從乙個城市出發,需要經過所有城市後,回到出發地。應如何選擇行進路線,以使總的行程最短?請輸出最短行程。節點個數 n 滿足 2 leq n leq 20 路的長度小於 1000 例如這個旅行商問題,可能的路線一共有 n 1 種,如果純暴力試遍每一種方案,那...