Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Bitmasking in dynamic programming [closed]

I am learning about TSP and i came across bit masking to represent all the combination of cities. I don't understand the logic behind it. Please help me in this.

#define size 10 //maximum 10 cities
#define min(a,b) a>b?b:a
#define sizePOW 1024 // 2^10

int n,npow,g[size][sizePOW],p[size][sizePOW],adj[size][size];

int compute(int start,int set)
{   
    int masked,mask,result=INT_MAX,temp,i;

    if(g[start][set]!=-1)
        return g[start][set];
    for(i=0;i<n;i++)
    {   
        mask=(npow-1)-(1<<i);
        masked=set&mask;
        if(masked!=set)
        {   
            temp=adj[start][i]+compute(i,masked);
            if(temp<result)
                result=temp,p[start][set]=i;
        }
    }
    return g[start][set]=result;
}

void getpath(int start,int set)
{
    if(p[start][set]==-1) return;
    int x=p[start][set];
    int mask=(npow-1)-(1<<x);  // What is the use of this line
    int masked=set&mask;
    printf("%d ",x);
    getpath(x,masked);
}
void TSP()
{   
    int i,j;
    //g(i,S) is length of shortest path starting at i visiting all vertices in S and ending at 1
    for(i=0;i<n;i++)
        for(j=0;j<npow;j++) 
            g[i][j]=p[i][j]=-1; 
    for(i=0;i<n;i++)
        g[i][0]=adj[i][0];
    int result=compute(0,npow-2);
    printf("Tour cost:%d\n",result);
    printf("Tour path:\n0 ");
    getpath(0,npow-2);
    printf("0\n");
}
int main(void) {
    int i,j;
    printf("Enter number of cities\n");
    scanf("%d",&n);
    npow=(int)pow(2,n);//bit number required to represent all possible sets
    printf("Enter the adjacency matrix\n");
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            scanf("%d",&adj[i][j]);
    TSP();
    return 0;
}

Please help me how the bit masking is used in this code ?

like image 747
Bad Coder Avatar asked Sep 05 '14 08:09

Bad Coder


People also ask

What is the use of Bitmasking?

Bitmasking is the act of applying a mask over a value to keep, change or modify a piece of given information. A mask determines which bits to take and which bits to clear off a binary number. Bitmasking can be used to mask a value to represent the subsets of a set using various bitwise operations.

What is DP Bitmasking?

Mask in Bitmask means hiding something. Bitmask is nothing but a binary number that represents something. Let's take an example. Consider the set A = { 1 , 2 , 3 , 4 , 5 } .

What is bit masking in Java?

Bitmasking allows us to store multiple values inside one numerical variable. Instead of thinking about this variable as a whole number, we treat its every bit as a separate value. Because a bit can equal either zero or one, we can also think of it as either false or true.

How do I make a bit mask in Python?

As an aside, an easy way to make proper bitmasks with nice readable code is to write them like value1 = 1 << 0 , value2 = 1 << 1 (etc). That is, take a single bit and just change the shift. Errors are more obvious than with hex or decimal literals.


3 Answers

Basically bitmask is just help you to represent the visited cities, instead of using an array of boolean.

For example, if we have 4 cities, so to represent that all 4 cities is visited, we can have the mask is 15, which is 1111b in binary (4 bits are 1).

If city 0 is not visited, the state is just 1110b or 14, you should notice that bit 0 is 0 in this case. (Similarly, if you used a boolean array, the value for the 0 position is false)

So all the technique using (shift bit, toggle bit) is just to modify a specific bit's location. Why this is useful? Because it helps you to pack an entire state into a 32-bit integer, which can be easily used for dynamic programming.

So how is the compute(int start, int set) function?

  • start : the current city.
  • set : all the visited cities.

So

 mask=(npow-1)-(1<<i);
 masked=set&mask;

npow - 1 means all cities are visited,(why? just write down 2^n - 1 in binary, and you will understand) and thus, when it minus (1<<i), it means this is the state when all cities are visited, except city i.

masked=set&mask as you know, for and operator, it is 1 if both bit are 1 and 0 otherwise, so if you set&mask , the result is All the visited cities in set will be 1, except if city i is already visited, it will be turned to 0.

So if(set == masked), which means, city i is 0 from the beginning (or unvisited).

Comment: This is not making a good use of bit manipulation technique, if I wrote this code, I will use ((set & (1<<i)) == 0)

like image 50
Pham Trung Avatar answered Oct 04 '22 09:10

Pham Trung


Dynamic programming with bitmasking is just a technique used to efficiently compute the mathematical traveling salesman problem recursion.

The recursion can be defined as f(u, s), where u is the node that you are currently considering and s is the set of available/visited cities. I'd suggest you to first read something about the recursion first before implementing it because the mathematics behind it can be very crucial to help you understand this code (and maybe the only way).

like image 30
Gary Ye Avatar answered Oct 04 '22 10:10

Gary Ye


To understand it, it is helpful to try it manually, OK let's assume:

n = 3 then nPow = 8 , right?

Now let's see int mask=(npow-1)-(1<<x);

x = 0;
mask = (8-1) - (1<<0);
     = 7 - (1 right-shifted 0 times)
     = 0111 - 1;  // in binary
     = 0110;  which means the bit number 0 was masked

x = 1;
mask = (8-1) - (1<<1);
     = 7 - (1 right-shifted 1 times)
     = 0111 - 10;  // in binary
     = 0101;  which means the bit number 1 was masked

and so on,

IMPORTANT

Not part of the answer to your problem but be careful with your macro #define min(a,b) a>b?b:a

try

int a = 10,b = 5,c;    
c = min(a, b)*4;

It drives you crazy when you get 5 as output instead of 20 !!!

c = min(a,b)*4
  = a>b? b:a*4
  = b // in this case 

to avoid it use extra parentheses #define min(a,b) (a>b?b:a)

like image 24
chouaib Avatar answered Oct 04 '22 08:10

chouaib