给定一组S = {s1,s2,s3 ..}和一组元素X = {x1,x2,x3 ..}我怎样才能枚举所有集合Y,其中绘制集合Y的元素从S替换,X是集合Y的集合的子集。对,这是我到目前为止所拥有的(python):
def enumerate_containing_subsets(S, X):
if not set(X).issubset(set().union(*S)): return
previous_generation = [[]]
for element in X:
current_generation = []
for subset in S:
if element in subset:
for node in previous_generation:
current_generation.append( node + [subset] )
previous_generation = current_generation
return previous_generation
S = [ frozenset([1,2]), frozenset([3]), frozenset([4,1])]
X = [ 1, 2 ]
enumerate_containing_subsets(S, X)
>> [[frozenset([1, 2]), frozenset([1, 2])],
[frozenset([1, 4]), frozenset([1, 2])]]
这种天真的方法是 O (n ^ n)我认为,我实际上是在这里构建一个树,并在每一代分支包含下一个X值的S的每个可能元素,有没有更好的方法呢?
答案 0 :(得分:1)
这个怎么样
# Ruby
require 'set'
s = Set[Set[1, 2, 3, 4], Set[3, 4, 5], Set[1, 2, 3, 7, 8, 9]]
x = Set[1, 3, 4]
class Set
def powerset
inject(Set[Set[]]) do |ps, item|
ps.union ps.map {|e| e.union (Set.new [item])}
end
end
end
pow = s.powerset
pow.select! { |sub|x <= sub.flatten }
p pow
这是O(n * x * 2^n)
,因为我们必须遍历powerset 2^n
并执行n
联合(常量时间)+ x查询以查看X是否在集合中。