我意识到有很多关于组合学和枚举的问题,但我四处搜索并没有找到任何与我所追求的东西特别相关的东西。如果我错过了什么,请指出它,问题可以结束。
因此,假设我们有一组 N 个元素,并且我们有 x 个正整数 k1,...,kx,其中 Sum(k1,...,kx) <= N。我想列举我可以选择的所有方式(没有替换)给定大小的 x 个子集,来自原始 N 集合。
我希望我的措辞正确。如果我没有,一个简单的例子。
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 将使用标准组合枚举生成,或者从每个级别的源集中删除那些已选择的元素,或者仅从原始集中枚举并跳过之前已包含元素的情况.
我的问题,有没有更快/更优雅的解决方案?