巡回セールスマン問題
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];
}