03. Travelling Salesman Problem
β GFG solution to the Travelling Salesman Problem: find minimum cost to visit all cities exactly once and return to start using dynamic programming with bitmask optimization. π
The problem can be found at the following link: π Question Link
π§© Problem Description
You are given a 2D matrix cost[][] of size n where cost[i][j] denotes the cost of moving from city i to city j. Your task is to complete a tour from city 0 (0-based index) to all other cities such that you visit each city exactly once and then at the end come back to city 0 at minimum cost.
This is the classic Travelling Salesman Problem (TSP), where the goal is to find the shortest possible route that visits every city exactly once and returns to the starting city.
π Examples
Example 1
Input: cost[][] = [[0, 111],
[112, 0]]
Output: 223
Explanation: We can visit 0->1->0 and cost = 111 + 112 = 223.Example 2
Input: cost[][] = [[0, 1000, 5000],
[5000, 0, 1000],
[1000, 5000, 0]]
Output: 3000
Explanation: We can visit 0->1->2->0 and cost = 1000 + 1000 + 1000 = 3000.π Constraints
$1 \le \text{cost.size()} \le 15$
$0 \le \text{cost}[i][j] \le 10^4$
β
My Approach
The optimal approach uses Dynamic Programming with Bitmask (Held-Karp algorithm) to efficiently explore all possible tours:
Bitmask Dynamic Programming
State Representation:
Use
dp[mask][i]to represent the minimum cost to visit all cities represented by set bits inmask, ending at cityi.The bitmask
masktracks which cities have been visited (bitiis 1 if cityiis visited).
Base Case:
Start from city 0:
dp[1][0] = 0(only city 0 visited with cost 0).
State Transitions:
For each state
(mask, i), try moving to every unvisited cityj.Update
dp[mask | (1 << j)][j]with the minimum of current value anddp[mask][i] + cost[i][j].
Final Answer:
After visiting all cities (when
mask = 2^n - 1), add the cost to return to city 0.The answer is
min(dp[fullMask][i] + cost[i][0])for all citiesi.
Optimization:
Process states in order of increasing mask values to ensure all dependencies are resolved.
Skip invalid states where city
iis not in the mask or cost is infinity.
π Time and Auxiliary Space Complexity
Expected Time Complexity: O(nΒ² Γ 2βΏ), where n is the number of cities. We have 2βΏ possible subsets of cities and for each subset-city combination, we try to extend to n other cities.
Expected Auxiliary Space Complexity: O(n Γ 2βΏ), as we maintain a 2D DP table with dimensions (2βΏ Γ n) to store the minimum cost for each state.
π§βπ» Code (C++)
class Solution {
public:
int tsp(vector<vector<int>>& cost) {
int n = cost.size();
if (n <= 1) return n ? cost[0][0] : 0;
int FULL = (1 << n) - 1;
vector<vector<int>> dp(1 << n, vector<int>(n, INT_MAX));
dp[1][0] = 0;
for (int mask = 1; mask <= FULL; mask++) {
for (int i = 0; i < n; i++) {
if (!(mask & (1 << i)) || dp[mask][i] == INT_MAX) continue;
for (int j = 0; j < n; j++) {
if (mask & (1 << j)) continue;
int nxt = mask | (1 << j);
dp[nxt][j] = min(dp[nxt][j], dp[mask][i] + cost[i][j]);
}
}
}
int ans = INT_MAX;
for (int i = 0; i < n; i++)
if (dp[FULL][i] != INT_MAX)
ans = min(ans, dp[FULL][i] + cost[i][0]);
return ans;
}
};β Code (Java)
class Solution {
public int tsp(int[][] cost) {
int n = cost.length;
if (n <= 1) return n == 1 ? cost[0][0] : 0;
int FULL = (1 << n) - 1;
int[][] dp = new int[1 << n][n];
for (int[] row : dp) Arrays.fill(row, Integer.MAX_VALUE);
dp[1][0] = 0;
for (int mask = 1; mask <= FULL; mask++) {
for (int i = 0; i < n; i++) {
if ((mask & (1 << i)) == 0 || dp[mask][i] == Integer.MAX_VALUE) continue;
for (int j = 0; j < n; j++) {
if ((mask & (1 << j)) != 0) continue;
int nxt = mask | (1 << j);
dp[nxt][j] = Math.min(dp[nxt][j], dp[mask][i] + cost[i][j]);
}
}
}
int ans = Integer.MAX_VALUE;
for (int i = 0; i < n; i++)
if (dp[FULL][i] != Integer.MAX_VALUE)
ans = Math.min(ans, dp[FULL][i] + cost[i][0]);
return ans;
}
}π Code (Python)
class Solution:
def tsp(self, cost):
n = len(cost)
if n <= 1: return cost[0][0] if n else 0
FULL = (1 << n) - 1
dp = [[float('inf')] * n for _ in range(1 << n)]
dp[1][0] = 0
for mask in range(1, (1 << n)):
for i in range(n):
if not (mask & (1 << i)) or dp[mask][i] == float('inf'): continue
for j in range(n):
if mask & (1 << j): continue
nxt = mask | (1 << j)
dp[nxt][j] = min(dp[nxt][j], dp[mask][i] + cost[i][j])
ans = float('inf')
for i in range(n):
if dp[FULL][i] != float('inf'):
ans = min(ans, dp[FULL][i] + cost[i][0])
return ansπ§ Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: π¬ Any Questions?. Let's make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β
πVisitor Count
Last updated