3

Suppose that int array a[i]=i, i=0, 1, 2, ..., N-1. Now given that each integer would associate with a bit. I need an algorithm to uniformly randomly select an integer from the subset of integers whose associated bit are 0. It is assumed that the total number of integers whose associated bit are 0 is already given in a variable T.

One straightforward solution I have is to generate r=rand() % T, and then find the r-th integer whose associated bit is 0 (by testing i=0,1,...). However, I wonder would there be any decent algorithms for doing this? Also, if say that the associated bits are stored in some long int variables (which is true in my case), finding the r-th integer whose associated bit is 0 would not be a easy task.

Thanks for your inputs.

4
  • 2
    Knuth shuffle or Fisher-Yates shuffle, guess there will be links for others. Commented Jun 25, 2015 at 3:20
  • 1
    what does "associated bit" mean? Commented Jun 25, 2015 at 3:43
  • What's the need to have a[] which has all items a[i]==i ? Whenever you access a[i] you can use i itself instead... Commented Jun 25, 2015 at 5:03
  • What is an 'associated bit'? Do you mean n-th bit of a[i] for some predefined n? Or is it n-th bit for some variable n? Or is it an 'i'-th item of some parallel array bool b[i] for i=0..(N-1)? Commented Jun 25, 2015 at 5:07

3 Answers 3

1

If the associated bits are irregular, i.e. cannot be deduced from the value of i by a simple formula, then it is just impossible to locate the r-th '0' bit without enumerating those that precede, unless preprocessing is allowed.

A good solution is to precompute a table that will store the indexes of the '0' bit entries contiguously, and lookup this table for the r-th entry. (Instead of an index table, you can as well fill another array with the elements from the subset only.)


Indexing a packed bit array is not such a big deal. Assuming 64 bits long ints, the bit at index i is found by the expression

(PackedBits[i >> 6] >> (i & 63)) & 1 

(The 6 because 64 == (1 << 6).)

In case you really want to find the r-th '0' sequentially, you can speed-up the search a little (x 64) by precomputing the number of '0's in every long int so that you can skip 64 entries in a single go.

And if you really really don't want to precompute anything, you can still speed-up the search by processing the bits 8 by 8, using a static table that relates every byte value (among 256) to the number of '0' bits in it. (Or even 16 by 16 if you can afford using a table of 65536 numbers.)

Sign up to request clarification or add additional context in comments.

Comments

0

You can speed this up by trading memory for speed.

T must be an array, that stores in T[n] the number of integers in a[] that have bit n cleared, and this needs to be precomputed at some point. So, while you are calculating that, store the indices of all the integers that have a given bit cleared in another 2 dimensional array, indexed by the bit number and r.

In C for example:

#define BITS (64) #define N (100) long int a[N]; int T[BITS]; int index[BITS][N]; void init() { int i, j; // clear T: for(j = 0; j < BITS; j++) T[j] = 0; // compute T and the indices for each: for(i = 0; i < N; i++) { for(j = 0; j < BITS; j++) { if((a[i] & (1 << j)) == 0) { // increment T and store the index index[j][T[j]++] = i; } } } } 

Then you can find your random number like this:

long number = N[index[bit][rand() % T[bit]]; 

You could make this more memory-efficient by using a less wasteful data structure that only stores as many indices for each bit as there are actual values in a[] that have the bit cleared.

Comments

0

If T is sufficiently large, the most efficient solution is going to be to randomly select an integer up to N and loop until the condition is met.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.