巡回セールスマン問題
1人の営業担当者が都市にいて、リストされている他のすべての都市を訪問する必要があります。ある都市から別の都市への移動費用も提供されます。すべての都市を一度訪れて、最初の都市に戻るためのコストが最小になるルートを見つけます。
この場合、グラフは完全である必要があります。これにより、営業担当者は任意の都市から任意の都市に直接移動できます。
ここで、最小加重ハミルトン閉路を見つける必要があります。
入力と出力
Input: Cost matrix of the matrix. 0 20 42 25 30 20 0 30 34 15 42 30 0 10 10 25 34 10 0 25 30 15 10 25 0 Output: Distance of Travelling Salesman: 80
アルゴリズム
travellingSalesman (mask, pos)
テーブルdpがあり、すべてのノードにアクセスしたことを示すVISIT_ALL値
入力- 一部の都市をマスクするためのマスク値、位置。
出力マイナス; すべての都市を訪れるための最短ルートを見つけてください。
Begin if mask = VISIT_ALL, then //when all cities are visited return cost[pos, 0] if dp[mask, pos] ≠ -1, then return dp[mask, pos] finalCost := ∞ for all cities i, do tempMask := (shift 1 left side i times) if mask AND tempMask = 0, then tempCpst := cost[pos, i] + travellingSalesman(mask OR tempMask, i) finalCost := minimum of finalCost and tempCost done dp[mask, pos] = finalCost return finalCost End
例
#include<iostream> #define CITY 5 #define INF 9999 using namespace std; int cost[CITY][CITY] = { {0, 20, 42, 25, 30}, {20, 0, 30, 34, 15}, {42, 30, 0, 10, 10}, {25, 34, 10, 0, 25}, {30, 15, 10, 25, 0} }; int VISIT_ALL = (1 << CITY) - 1; int dp[16][4]; //make array of size (2^n, n) int travellingSalesman(int mask, int pos) { if(mask == VISIT_ALL) //when all cities are marked as visited return cost[pos][0]; //from current city to origin if(dp[mask][pos] != -1) //when it is considered return dp[mask][pos]; int finalCost = INF; for(int i = 0; i<CITY; i++) { if((mask & (1 << i)) == 0) { //if the ith bit of the result is 0, then it is unvisited int tempCost = cost[pos][i] + travellingSalesman(mask | (1 << i), i); //as ith city is visited finalCost = min(finalCost, tempCost); } } return dp[mask][pos] = finalCost; } int main() { int row = (1 << CITY), col = CITY; for(int i = 0; i<row; i++) for(int j = 0; j<col; j++) dp[i][j] = -1; //initialize dp array to -1 cout << "Distance of Travelling Salesman: "; cout <<travellingSalesman(1, 0); //initially mask is 0001, as 0th city already visited }
出力
Distance of Travelling Salesman: 80
-
最大の独立集合問題
独立集合は、そのサブセット内の2つのノード間にエッジがない場合、すべての二分木ノードのサブセットです。 ここで、要素のセットから、最長の独立集合を見つけます。つまり、要素を使用してバイナリツリーを形成する場合、すべての最大のサブセットであり、そのサブセット内の要素は相互に接続されていません。 入力と出力 Input: A binary tree. Output: Size of the Largest Independent Set is: 5 アルゴリズム longSetSize(root) このアルゴリズムでは、バイナリツリーが形成され、そのツリーの各ノードがデータとsetSize
-
頂点被覆問題
無向グラフの場合、頂点被覆は頂点のサブセットであり、グラフのすべてのエッジ(u、v)について、uまたはvのいずれかがセットに含まれます。 二分木を使用すると、頂点被覆問題を簡単に解決できます。 この問題は、2つのサブ問題に分けることができます。ルートが頂点被覆の一部である場合。この場合、ルートはすべての子エッジをカバーします。左右のサブツリーの頂点被覆のサイズを簡単に見つけて、ルートに1を追加できます。 入力と出力 Input: A binary tree. Output: The vertex cover is 3. アルゴリズム vertexCover(root node