我有一个对象数组(n)。 我想通过一次选择(r)元素来输出一组唯一对象。
例如: n = 600, r = 10
我们如何获得所有可能的独特解决方案?
我意识到这是二项式系数公式(并且解决方案集也是巨大的),但我无法找到实现它的方法,不会超出内存约束。
可能有助于实现细节的内容(来自内存问题)是对于每种可能的组合,我可以应用某些规则来确认它是否与我有任何关系(在很多情况下组合将会没用)。
答案 0 :(得分:1)
这是一个简单的算法,如果你足够多次调用,它可以让你产生从0到n-1的整数的所有r组合。该算法所做的是采用表示组合的r向量,并将其就地推进到下一个组合(按字典顺序)。您可以使用这样的矢量来索引对象的矢量。
给出一个向量v0...vr-1
:
j < r
vj < n - r + j
j
。k
j < k
和k < r
,请将vk
设置为vj + k - j
这是一个简单而合理有效的C解决方案(虽然不是每个人都会欣赏这种风格)。如果当前组合是最后一个组合,则函数返回false
。应该将向量初始化为序列0...r-1
,以便迭代整个可能性集。
bool next_combination(int *comb, int n, int r) {
for (int j = r - 1, v = n - 1; j >= 0; --j, --v) {
if (comb[j] < v) {
for (v = comb[j] + 1; j < r; ++j, ++v)
comb[j] = v;
return true;
}
}
return false;
}
但是,我真的不认为生成所有可能的 600 C 10 值是切实可行的,即使你不尝试将它们全部存储在一个数组中。 600 C 10 是1,545,269,050,621,668,869,640。如果你可以在一秒内处理10个 9 组合(即每纳秒一个),那么通过整个列表仍然需要大约48,965年。
因此,您可能想要考虑如何只生成您感兴趣的组合。