【问题标题】:How to compute the all combinations of k set bits in parallel?如何并行计算 k 个集合位的所有组合?
【发布时间】: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那么你有问题

标签: c bit-manipulation combinations combinatorics


【解决方案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}),如示例所示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 2016-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多