Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.thealgorithms.dynamicprogramming;

import java.util.Arrays;

/**
* An implementation of Dynamic Programming using Bitmasks.
* Bitmask DP represents a subset of elements as bits in an integer.
* If the i-th bit is 1, the i-th element is included in the subset.
* This is highly effective for problems where n is small (≤ 20).
* This class demonstrates Bitmask DP by solving the Traveling
* Salesperson Problem (TSP) - finding the minimum cost to visit all
* nodes exactly once and return to the starting node.
*/
public final class BitmaskDP {

private BitmaskDP() {
// Prevent instantiation
}

/**
* Solves the Traveling Salesperson Problem using Bitmask DP.
* @param distance A 2D array where distance[i][j] is the cost to travel from node i to node j.
* @return The minimum distance to visit all nodes and return to the start.
*/
public static int tsp(int[][] distance) {
int n = distance.length;
if (n == 0) {
return 0;
}

int totalSubsets = 1 << n;

// dp[mask][i] = min distance visiting the subset 'mask' and currently ending at node 'i'
int[][] dp = new int[totalSubsets][n];

// Initialize with Integer.MAX_VALUE
for (int[] row : dp) {
Arrays.fill(row, Integer.MAX_VALUE);
}

// Base case: Start at node 0.
dp[1][0] = 0;

for (int mask = 1; mask < totalSubsets; mask++) {
for (int u = 0; u < n; u++) {
// Skip if node 'u' is NOT in the current subset,
// OR if the current state is unreachable (INT_MAX)
if ((mask & (1 << u)) == 0 || dp[mask][u] == Integer.MAX_VALUE) {
continue;
}

for (int v = 0; v < n; v++) {
// If node 'v' IS already in the subset, skip
if ((mask & (1 << v)) != 0) {
continue;
}

int nextMask = mask | (1 << v);

// Safe to add since we already verified dp[mask][u] is not INT_MAX
dp[nextMask][v] = Math.min(dp[nextMask][v], dp[mask][u] + distance[u][v]);
}
}
}

// Find the minimum cost to return to the starting node (0) from the last visited node
int minCost = Integer.MAX_VALUE;
int allVisitedMask = totalSubsets - 1; // All n bits are 1

for (int i = 1; i < n; i++) {
minCost = Math.min(minCost, dp[allVisitedMask][i] + distance[i][0]);
}

return minCost;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
This document provides a detailed, line-by-line breakdown of the Traveling Salesperson Problem (TSP) implementation using Bitmask Dynamic Programming.

Class: BitmaskDP

A utility class containing the algorithm to solve the TSP. It is declared as final with a private constructor to prevent instantiation, adhering to standard Java utility class conventions.

Method: tsp(int[][] distance)

Calculates the minimum cost to visit every node exactly once and return to the starting node.

Parameters

distance (int[][]): An $N \times N$ adjacency matrix representing the graph. distance[u][v] holds the cost/distance to travel from node u to node v.

Returns

int: The minimum total distance required to complete the TSP tour.

Variable Breakdown

n: The total number of nodes (cities) in the graph.

totalSubsets: Calculated as 1 << n (which equals $2^n$). This represents the total number of possible combinations of visited nodes.

dp: A 2D array of size [totalSubsets][n].

mask (row): The current subset of visited nodes represented as an integer bitmask.

i (column): The node the path currently ends on.

dp[mask][i] stores the minimum cost to reach this state.

Step-by-Step Logic

1. Initialization

for (int[] row : dp) {
Arrays.fill(row, Integer.MAX_VALUE);
}


All states in the DP table are initialized to Integer.MAX_VALUE (infinity). This indicates that, initially, all paths are considered unreachable.

2. The Base Case

dp[1][0] = 0;


The algorithm assumes node 0 is the starting point.

The binary representation of 1 is ...0001, meaning only the 0-th bit is set (only node 0 has been visited).

The cost to be at node 0 having only visited node 0 is 0.

3. State Transitions (The Core Loop)

The algorithm iterates through every possible mask (from 1 to totalSubsets - 1).

for (int u = 0; u < n; u++) {
if ((mask & (1 << u)) == 0 || dp[mask][u] == Integer.MAX_VALUE) continue;


For each mask, it checks every node u to see if it acts as a valid "current end node". It skips the iteration if:

Node u is not in the current mask.

The state dp[mask][u] is unreachable (Integer.MAX_VALUE).

for (int v = 0; v < n; v++) {
if ((mask & (1 << v)) != 0) continue;


It then looks for an unvisited adjacent node v. If v is already included in the mask (meaning the bit is 1), it skips v because the TSP requires visiting nodes exactly once.

int nextMask = mask | (1 << v);
dp[nextMask][v] = Math.min(dp[nextMask][v], dp[mask][u] + distance[u][v]);


If v is unvisited, the algorithm calculates the nextMask by setting the $v$-th bit to 1. It then updates the DP table for nextMask ending at v with the minimum of:

Its current known cost.

The cost of the current state (dp[mask][u]) plus the travel cost from u to v.

4. Calculating the Final Tour Cost

int minCost = Integer.MAX_VALUE;
int allVisitedMask = totalSubsets - 1;

for (int i = 1; i < n; i++) {
minCost = Math.min(minCost, dp[allVisitedMask][i] + distance[i][0]);
}


After the DP table is fully populated, the algorithm looks at the state where all nodes have been visited (allVisitedMask, where all $N$ bits are 1).

It iterates through every possible ending node i, taking the cost of reaching that node and adding the distance to travel back to the starting node 0 (distance[i][0]). The smallest resulting sum is returned as the final minCost.
Loading