C 从整数子集中均匀随机选择一个数的算法
假设int数组a[i]=i,i=0,1,2,…,N-1。现在假设每个整数都与一个位相关联。我需要一个算法,从相关位为0的整数子集中统一随机选择一个整数。假设变量T中已经给出了关联位为0的整数总数 我有一个简单的解决方案,就是生成r=rand()%T,然后找到关联位为0的第r个整数(通过测试I=0,1,…)。然而,我想知道有什么合适的算法可以做到这一点?另外,如果说相关位存储在一些长int变量中(在我的例子中是这样),那么查找相关位为0的第r个整数将不是一件容易的任务C 从整数子集中均匀随机选择一个数的算法,c,algorithm,random,C,Algorithm,Random,假设int数组a[i]=i,i=0,1,2,…,N-1。现在假设每个整数都与一个位相关联。我需要一个算法,从相关位为0的整数子集中统一随机选择一个整数。假设变量T中已经给出了关联位为0的整数总数 我有一个简单的解决方案,就是生成r=rand()%T,然后找到关联位为0的第r个整数(通过测试I=0,1,…)。然而,我想知道有什么合适的算法可以做到这一点?另外,如果说相关位存储在一些长int变量中(在我的例子中是这样),那么查找相关位为0的第r个整数将不是一件容易的任务 感谢您的投入。您可以通过以内
感谢您的投入。您可以通过以内存换取速度来加快速度 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;
}
}
}
}
您可以通过使用一种不太浪费的数据结构来提高内存效率,该结构只为每个位存储与[]中清除位的实际值相同数量的索引。如果相关位是不规则的,即不能通过简单的公式从
i
的值推导出来,然后,除非允许预处理,否则如果不枚举前面的位,就不可能找到r-th“0”
位
一个好的解决方案是预计算一个表,该表将连续存储'0'
位条目的索引,并在该表中查找r-th
条目。(除了索引表,您还可以仅使用子集中的元素填充另一个数组。)
为压缩位数组编制索引并不是什么大事。假设64位
长整数
,则通过表达式找到索引i
处的位
(PackedBits[i >> 6] >> (i & 63)) & 1
(因为
64==(1如果T
足够大,最有效的解决方案是随机选择一个最大为N
的整数并循环直到满足条件。Knuth shuffle或Fisher-Yates shuffle,猜测会有其他的链接。“关联位”是什么意思是什么?需要一个包含所有项目的a[i]==i
的a[]
吗?每当你访问a[i]
时,你可以使用i
本身……什么是“关联位”?你的意思是n
-a[i]的第位吗
对于某些预定义的n
?或者对于某些变量n
,它是n
的第位?或者对于i=0.(n-1),它是某个并行数组bool b[i]
的第i项?
(PackedBits[i >> 6] >> (i & 63)) & 1