如何并行计算 k 个集合位的所有组合?
Posted
技术标签:
【中文标题】如何并行计算 k 个集合位的所有组合?【英文标题】:How to compute the all combinations of k set bits in parallel? 【发布时间】:2021-06-30 10:58:06 【问题描述】:我想有效地计算一个 n 位数(在我的例子中,n=36)的所有组合,其中设置了 k 位。
我在想像 Gosper's Hack 之类的东西,但可以并行化。
例如,如果我可以将一个索引传递给 Gosper's Hack,那就完美了,它会计算第 i 个组合。
unsigned long long permute(unsigned long long val, unsigned long long i)
int ffs = __builtin_ffsll(val);
val |= (val - 1);
// Do something here with `i` to produce the i'th combination, rather than the next one.
return (val + 1) | (((~val & -(~val)) - 1) >> ffs);
另外,就我而言,这些组合不一定需要按字典顺序排列。只要生成所有组合,就可以进行任何排序。
【问题讨论】:
一般而言,可并行化可能比可索引化更容易。不过,可索引会更普遍。 因为 Gosper 的 hack 从最低到最高迭代,您可以将空间划分为多个范围,然后问题是关于找到范围开始上方的最低 n 位设置值 - 如果范围的开始有 l位设置,您需要将 (k - l) 最低位设置为 1 并从那里开始。如果k < l
那么你有问题
【参考方案1】:
您可以按照以下方式实现它,遵循this example:
long to_combination(int k, int N)
if (N == 0)
return (1L<<k)-1;
int n;
for (n=k; C(n,k)<=N; n++)
;
n--;
return (1L<<n) | to_combination(k-1, N - C(n,k));
调用to_combination(5, 72)
返回331(101001011
二进制,代表8, 6, 3, 1, 0
),如示例所示。
【讨论】:
以上是关于如何并行计算 k 个集合位的所有组合?的主要内容,如果未能解决你的问题,请参考以下文章