从整数子集

时间:2015-06-25 03:12:13

标签: c algorithm random

假设int数组 a [i] = i,i = 0,1,2,...,N-1 。现在假设每个整数都与一个位相关联。我需要一个算法来统一随机选择整数子集中的整数,其整数的关联位是 0 。假设关联位为0的整数总数已在变量 T 中给出。

我有一个直接的解决方案是生成 r = rand()%T ,然后找到 r -th整数,其关联位为0(通过测试我= 0,1,...)。但是,我想知道有没有合适的算法呢?另外,如果说相关的位存储在一些长的int变量中(在我的情况下也是如此),找到相关位为0的 r -th整数将不是一件容易的事。 / p>

感谢您的投入。

3 个答案:

答案 0 :(得分:1)

如果关联的比特是不规则的,即不能通过一个简单的公式从i的值推导出来,那么除非预先处理,否则不能枚举r-th '0'比特而不枚举前面的比特是不可能的。是允许的。

一个好的解决方案是预先计算一个表,该表将连续存储'0'位条目的索引,并查找此表以查找r-th条目。 (您也可以使用子集中的元素填充另一个数组,而不是索引表。)

索引打包位数组并不是什么大问题。假设64位long ints,索引i的位由表达式

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

6因为64 == (1 << 6)。)

如果您确实想要按顺序找到r-th '0',可以通过预先计算每个long int中'0's的数量来加快搜索速度(x 64),以便您可以跳过一次性64个条目。

如果你真的不想预先计算任何东西,你仍然可以通过使用与每个字节值相关的静态表(256之间的位来处理8位8来加速搜索。 )到其中'0'位的数量。 (如果你能负担得起使用65536数字的表格,那么即使是16比16。)

答案 1 :(得分:0)

你可以通过交换记忆来提高速度。

T必须是一个数组,它在T [n]中存储[]中有位n清零的整数个数,这需要在某个时刻进行预计算。因此,在计算时,存储在另一个二维数组中清除了给定位的所有整数的索引,由位数和r索引。

以C为例:

#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;
            }
        }
    }
}

然后你可以找到这样的随机数:

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

你可以通过使用一个浪费较少的数据结构来提高内存效率,这种结构只为每个位存储尽可能多的索引,因为[]中的实际值会清除这些位。

答案 2 :(得分:0)

如果T足够大,最有效的解决方案是随机选择一个最大为N的整数并循环,直到满足条件。