如何并行计算 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 个集合位的所有组合?的主要内容,如果未能解决你的问题,请参考以下文章

对集合进行并行计算方法选择的建议:stream的并行流,CompletableFuture

并行化大型动态程序

如何实现C语言的多处理器并行计算

如何在 Azure ML 服务计算集群上并行工作?

R中的并行计算:如何使用内核

PayPal 如何计算和分配并行支付交易费用?