【问题标题】:Combinatoric Optimization - Enumerating all Subsets that Contain a Given Set组合优化 - 枚举包含给定集合的所有子集
【发布时间】:2013-07-13 04:23:37
【问题描述】:

给定一组集合 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 的每个可能元素进行分支,有没有更好的方法来做到这一点?

【问题讨论】:

  • 所以你本质上想要一些 P(S) 的子集,使得联合包含 X。
  • 是的,我想针对所有此类子集优化成本函数
  • 你的成本函数是什么?
  • 成本函数在这里不是那么重要,我只是想确保我枚举出所有符合我标准的可能子集

标签: algorithm


【解决方案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 unions(恒定时间)+ x 查询以查看 X 是否在集合中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-09
    • 1970-01-01
    • 2012-11-20
    • 1970-01-01
    • 2020-07-26
    • 2011-11-05
    • 1970-01-01
    • 2020-07-09
    相关资源
    最近更新 更多