【发布时间】:2020-03-25 03:35:59
【问题描述】:
所以现在我正在使用 SAT 来解决最小顶点覆盖问题,这是我对图 G = {V,E} 有 k 个顶点覆盖的编码,下面是子句:
Let n = sizeof(V);
首先,顶点覆盖中至少有一个顶点:
For i in {1..k}
Add clause (x<1,i> ∨ x<2,i> ∨ ··· ∨ x<n,i>);
那么,没有一个顶点可以在顶点覆盖中出现两次:
For j in {1..n}
For l and m in {1..k} with l < m
Add clause (¬x<j,l> ∨ ¬x<j,m>)
之后,顶点覆盖的特定位置只能出现一个顶点:
For j in {1..k}
For l and m in {1..n} with l < m
Add clause (¬x<l,j> ∨ ¬x<m,j>)
最后,顶点覆盖中至少有一个顶点应该来自边:
For i and j in each edge e from E
Add clause (x<i,1> ∨ x<i,2> ∨ ... ∨ x<i,k> ∨ x<j,1> ∨ ... ∨ x<j,k>)
现在我可以通过使用这种编码获得最小的顶点覆盖,但效率很差。我只能得到小于 20 个顶点的任何图的结果,否则只需要几分钟和几小时就能得到结果。我现在正在考虑将其从 SAT 进一步降低,也许是 3SAT。但看起来我不能简单地将所有子句从 nCNF 更改为 3CNF 以获得相同的结果。谁能帮我弄清楚下一步该怎么做?我需要全新的编码吗?
非常感谢。
顺便说一句,我正在使用 MiniSAT 作为求解器。
【问题讨论】:
-
我没有在问题中看到任何 优化 组件,因为它与伪代码一起呈现,所以我猜模型的某些部分丢失了。您可以编辑您的问题并包括缺失的部分吗?如果有任何优化,优化程序是属于minisat的还是你自己写的?在后一种情况下,您介意详细说明它是如何工作的吗?
标签: c++ algorithm optimization sat optimathsat