与多个组合的组合

时间:2013-07-12 23:43:59

标签: math combinations counting

您如何以编程方式将一组数字的所有可能唯一组合枚举为多个组?

例如,如果我有集合{1,2,3,4,5,6,7,8,9,10}并且我想要3个大小为3,3,2的组,则一个可能的子集将是{ [1,2,3],[4,5,6],[7,8]}

这相当于{[3,2,1],[6,5,4],[7,8]}并且会被视为重复

而{[4,2,3],[1,5,6],[7,8]}将被视为不同的子集

显然,我正在寻找最有效和实用的方法。我将使用相当大的N,因此算法需要可扩展。

1 个答案:

答案 0 :(得分:1)

另一种思考这个问题的方法是作为多集的排列 {1, 1, 1, 2, 2, 2, 3, 3}。如果此类排列p在位置i中的值为j,则表示原始集合中的元素j应放在分区i中。

使用例如您可以按如下方式枚举这些排列的C ++模板next_permutation

int main() {
  int a[] = { 0, 0, 0, 1, 1, 1, 2, 2 };
  do {
    // Here a[j] == i means element j of your set goes in partition i.
    // Do whatever you want to do with the permutations generated this way.
  } while (std::next_permutation(a, a + 8));
}

结果将包含10!/(3!3!2!)= 560种不同的组合。此代码的演示运行(包括类似于问题陈述中使用的符号的输出)为available at ideone。如果您想知道如何为gcc实现next_permutation,可以查看the source code,但只有在目标项目的许可证允许复制该代码时才能这样做。