此问题被称为MINIMUM ķ -union,并且它是NP-hard,如下所示:
因此,没有人知道任何算法来解决它在时间上运行的多项式大小的输入。
在你的情况,你可能会很乐意接受的近似解:即用成分的小工会食谱的集合,但不一定是最小的这样的集合。所以我建议你试试贪心算法:通过在每个阶段加入,该联盟的规模最小的配方反复建立食谱的集合。下面是Python中的天真实现:
def small_union(sets, k):
"""
Choose `k` elements from `sets` and return their union. Attempt
to return a fairly small union using a greedy approach.
>>> small_union([{1,2}, {2,3}, {1,2,3}, {1}, {2}], 3)
set([1, 2])
>>> small_union([{1,2}, {2,3}, {3,4}, {1,4}], 3)
set([1, 2, 3, 4])
"""
union = set()
for _ in xrange(k):
s = min(sets, key = lambda s: len(s | union))
sets.remove(s)
union |= s
return union
嗯也许Mathforum会更好;) –
跨张贴在这里:http://mathoverflow.net/questions/259485/inverse-set-cover-problem(2017) –
为O(n^{0.25+ \小量}) - 近似算法在这里(和SODA 2017年):https://arxiv.org/abs/1611.07866 –