你所问的有一个名字。它被称为电源组。
谷歌搜索“幂集算法”让我找到了这个递归解决方案。
红宝石算法
def powerset!(set)
return [set] if set.empty?
p = set.pop
subset = powerset!(set)
subset | subset.map { |x| x | [p] }
end
幂集直觉
如果 S = (a, b, c) 那么幂集 (S) 是所有子集的集合
powerset ( S) = {(), (a), (b), (c), (a,b), ( a,c), (b,c), (a,b,c)}
第一个“技巧”是尝试递归定义。
什么是停止状态?
S = () 有什么幂集(S)?
如何达到它?
将集合减少一个元素
考虑取出一个元素 - 在上面的例子中,取出 {c}
S = (a,b) 然后 幂集(S) = {(), (a), (b), (a,b)}
什么不见了?
幂集(S) = {(c), (a,c), (b,c), (a,b,c)}
嗯
注意到任何相似之处吗?再看...
幂集(S) = {(), (a), (b), (c), (a,b), (a,c), (b,c), (a,b,c)}
取出任何元素
幂集(S) = {(), (a), (b), (c), (a,b), (a,c), (b,c), (a,b,c)}是
powerset (S - {c}) = {(), (a), (b), (a,b)} 联合
{c} U幂集(S - {c}) = { (c), (a,c), (b,c), (a,b,c)}
幂集(S) =幂集(S - {e i }) U ({e i } U幂集(S - {e i }))
其中 e i是 S 的一个元素(单例)
伪算法
- 传递的集合是空的吗?完成(请注意,{} 的幂集为 {{}})
- 如果没有,取出一个元素
- 在集合的其余部分上递归调用方法
- 返回由 Union 组成的集合
- 没有元素的集合的幂集(来自递归调用)
- 相同的集合(即2.1),但其中的每个元素都与最初取出的元素联合