【问题标题】:How to enumerate combinations of combinations from a single set如何从单个集合中枚举组合的组合
【发布时间】:2012-10-22 13:47:13
【问题描述】:

我意识到有很多关于组合学和枚举的问题,但我四处搜索并没有找到任何与我所追求的东西特别相关的东西。如果我错过了什么,请指出它,问题可以结束。

所以,假设我们有一组 N 个元素,并且我们有 x 个正整数 k1,...,kx,其中 Sum(k1,...,kx)

我希望我的措辞正确。如果我没有,一个简单的例子。
N = 4,x = 2,k1 = 2,k2 = 1。

我们应该枚举

  • {1, 2} {3}
  • {1, 2} {4}
  • {1, 3} {2}
  • {1, 3} {4}
  • {1, 4} {2}
  • {1, 4} {3}
  • {2, 3} {1}
  • {2, 3} {4}
  • {2, 4} {1}
  • {2, 4} {3}
  • {3, 4} {1}
  • {3, 4} {2}

在一般情况下,我认为总数是:

C(N, k1) * C(N - k1, k2) * ... * C(N - Sum(k1,...,kn-1), kn)。

我最初的猜测是,这可以使用堆栈相当容易地完成。在每个堆栈级别 i 子集 ki 将使用标准组合枚举生成,或者从每个级别的源集中删除那些已选择的元素,或者仅从原始集中枚举并跳过之前已包含元素的情况.

我的问题,有没有更快/更优雅的解决方案?

【问题讨论】:

  • SOs 格式检查器是荒谬的,我刚刚花了 45 分钟的时间让它接受我的问题,因为它告诉我我的代码格式不正确。没有代码,我最初在预览中的格式很好。我非常几乎要放弃了。
  • 我认为你应该使用递归函数来构建第一个子集,然后是第二个......

标签: algorithm math recursion combinations combinatorics


【解决方案1】:

您的问题正是枚举多集排列的问题。 (假设你的 ki 是有序的)。

首先,请注意,该问题完全等价于 Σk 等于; N,因为如果 Σk x+1,其值为 N - Σk。

现在,将原始集合 S 的元素按任意固定顺序放置,并生成由 k1 1's, k2 2's, k 组成的多重集的每个排列3 3 个,... kx 个 x。这个多重集具有与 S 相同的大小 (N),因为 ki 的总和为 N。我们通过将 S 中的每个元素分配给其索引为对应的子集来创建 S 的分区多重集排列中的值。

例如,S = {apple,banana,chirimoya,date} (N = 4)。我们取 k1 = 2 和 k2 = 1 并加上 k3 = 1 使总和为 4。(我们只需忽略分配给子集 3) 的元素。现在我们枚举多重集1 1 2 3 的排列(它有两个1,一个2,一个3,对应于k):

1 1 2 3    1 2 3 1    2 1 1 3    3 1 1 2
1 1 3 2    1 3 1 2    2 1 3 1    3 1 2 1
1 2 1 3    1 3 1 1    2 3 1 1    3 2 1 1

我们将这些转换回 S 的分区。例如,取1 3 1 2

apple     1 -> subset 1
banana    3 -> unused
chirimoya 1 -> subset 1
date      2 -> subset 2

所以我们有{{apple, chirimoya}, {date}}

用于查找集合排列的standard algorithm 在多集合上也同样有效,尽管如果多集合有很多重复项,它就不是最佳的了。

【讨论】:

  • 谢谢,看起来是一个非常干净的解决方案。
猜你喜欢
  • 2011-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
  • 1970-01-01
  • 2018-02-14
  • 1970-01-01
相关资源
最近更新 更多