Loading [MathJax]/jax/output/HTML-CSS/jax.js

巡回セールスマン問題

N個のノード1,2,...,Nを持つ重み付き有向グラフG(V,E)について,ノード1から出発し,各ノードをちょうど1度ずつ通りノード1へ戻る閉路の中で最短の経路の距離を求めよ.

この問題はNP困難というクラスに属する有名な問題で,多項式時間で解くアルゴリズムが存在しないとされている.bitDPというアルゴリズムを使うと,O(|V|22|V|)で解くことができる.

具体的には以下の漸化式が成立する.

dp[S][v]=minu(S{v})(dp[S{v}][u]+dist[u][v])

自然言語でいうなら,「今まで訪れたノードの集合がSで最後に訪れたノードがvになるような最短経路は,今までノードの集合がS{v}で最後に訪れたノードがS{v}に含まれるいずれかのノードであるような最短経路にそのノードからvへの距離を足した値の最小値」.

この訪れたノードの集合をbitで持つ.この集合の状態数は2|V|となり,最後に訪れたノードの状態数は|V|である.各状態から,次に通る都市を|V|通り探索するので,全体の計算量はO(|V|22|V|)となる.

コード

i64 tsp(int n, vector<vector<int>> &dist) { vector<vector<i64>> dp(1<<n, vector(n, inf)); dp[0][0] = 0; rep (bit, 1<<n) { rep (u, n) { if (!((bit >> u)&1) and bit + u != 0) continue; rep (v, n) { if ((bit >> v)&1) continue; chmin(dp[bit|(1<<v)][v], dp[bit][u] + dist[u][v]); } } } return dp[(1<<n)-1][0]; }