2

I am looking for an efficient way to iterate over all n bit non-negative integers which have at most k bits set by flipping one bit at a time.

What is the minimum number of bit flips I need to do to iterate over all n bit non-negative integers with at most k bits set?

I know that if k = n, that is we want to iterate over all n bit non-negative integers then we can use a Gray code. This has the great property that you only ever change one bit to get a new number. However this will typically go via integers with more than k bits if k < n.

Simd
  • 19,447
  • 42
  • 136
  • 271

2 Answers2

0

To iterate over all values for bit 0: Start with any starting value, then flip bit 0.

To iterate over all values for bits 0, 1: Start with any starting value. Iterate over all values for bit 0. Flip bit 1. Iterate over all values for bit 0.

To iterate over all values for bits 0-2: Start with any starting value. Iterate over all values for bit 0, 1. Flip bit 2. Iterate over all values for bit 0, 1.

To iterate over all values for bits 0-3: Start with any starting value. Iterate over all values for bit 0-2. Flip bit 3. Iterate over all values for bit 0-2. I hope the system is clear now.

Start with i = any value, j = 0. Increase j by 1, determine the lowest bit that is set in j, flip that bit in i. Rinse and repeat.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
  • How does this restrict the number of bits set to k? – Simd Nov 30 '16 at 15:53
  • Ideally also I would only change one bit to get a new number as in a Gray code. – Simd Nov 30 '16 at 15:56
  • @Arthur: Iterating over values with fixed number of 1-bits will require changing at least 2 bits from one value to the next. You can't do it by changing only 1 bit each time. – AnT stands with Russia Nov 30 '16 at 16:14
  • @AnT Changing 2 at a time is also fine with me. It is possible to iterate over all n bit non-negative changing one bit at a time using a Gray code of course if we remove the restriction to having at most k bits set. – Simd Nov 30 '16 at 16:24
  • @Arthur: Well, that's a question of what you can/need to do at the *external* specification level. If the external behavior of your algorithm is supposed to look like you are iterating over values with exactly `k` 1-bits, then using Gray code under the hood will not look like you are flipping only 1 bit each time. – AnT stands with Russia Nov 30 '16 at 16:38
  • @AnT Yes that is true. I meant something different . But in any case we have a solution flipping 2 bits at a time now. I wonder if that is optimal over all. – Simd Nov 30 '16 at 16:53
0

A known bit-fiddling technique might be implemented as follows (using unsigned is the underlying n-bit integer type)

unsigned next_combination(unsigned x)
{
  unsigned u = x & -x;
  unsigned v = u + x;
  x = v  + (((v ^ x) / u) >> 2);
  return x;
}

It generates the "next" number in some sequence of integers with the same number of 1-bits. (1u << k) - 1u is the starting point. The iteration ends when the first overflow occurs. The latter means that the algorithm can be immediately used for n smaller than number of bits in unsigned.

(See https://en.wikipedia.org/wiki/Combinatorial_number_system for a more detailed description.)

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • That's very nice. However I really want to flip as few bits as possible in my case. – Simd Nov 30 '16 at 16:00