【问题标题】:Exact cover problem but with constraint on exact number of subsets in the solution精确覆盖问题,但对解决方案中子集的精确数量有限制
【发布时间】:2020-06-21 13:38:10
【问题描述】:

我对精确覆盖和类似问题比较陌生,所以请多多包涵。假设我有一个典型的精确覆盖问题,即。给定一个集合 X 和一个 X 的子集 S 的集合,我想找到 S* (a S) 的子集,完全覆盖 X。但是,我希望解决方案 S* 恰好包含 k 元素。而且,一个解决方案就足够了。

我知道 Knuth 的算法 X 旨在返回所有可能的解决方案。我应该只运行 Knuth 的算法并遍历解决方案,直到找到具有 k 元素的解决方案,还是(我怀疑)有更好的方法?顺便说一句,我正在使用 Python。

对于上下文,X 的大小是 S 的大小可以是 10^6。 k

【问题讨论】:

    标签: python algorithm performance np-complete knuth


    【解决方案1】:

    如果k 很小,您可以简单地尝试添加k 额外元素,并复制每个子集k 次,每次重复都包含k 额外元素之一。

    另一种方法是将精确覆盖问题作为整数线性程序求解,并使用 ILP 求解器求解。然后,您将有 0-1 个变量 x_i 来说明 ith 子集是否包含在解决方案中,并具有防止重叠集包含在解决方案中的约束。在这个公式中,要提供一个完全包含 k 子集的覆盖,您只需拥有 sum(x_i) = k 的附加约束。

    也可以修改算法 X 以直接处理约束。只需计算到目前为止您选择了多少行,如果您已经选择了k,则无需进一步搜索即可失败。同样,忽略行数少于k 的解决方案。

    【讨论】:

    • 感谢您的回复。您的第一个建议可能不可行,因为任何算法都可能在子集的数量上呈指数增长,复制每个子集 k 次可能需要太长时间。你有没有感觉剩下的两种方法中的哪一种会运行得更快一些?
    • 第一个和第三个解决方案都应该很容易编码(假设您已经实现了算法 X),所以我会先尝试它们,看看它们的性能如何。很难说第二种解决方案 - 通用 ILP 求解器(而不是算法 X 的更严格实现)的开销可能会也可能不会超过它在您的特定问题上使用的更高级算法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    相关资源
    最近更新 更多