我希望有关如何实现这一目标的建议:
定义: 无向图G由顶点集合V和边缘集合E定义,其中每个边缘是尺寸为2的V的子集,即无顶对的顶点{u,v}。 G中长度为k的循环是{v_1,v_2},{v_2,v_3},...,{v_k-1,v_k},{v_k,v_1的不同顶点的序列v_1,...,v_k G的哈密顿循环是长度为n = | V |的循环,即恰好一次穿过图的每个顶点的一个循环。如果它具有哈密顿循环,我们称之为G哈密顿量。
问题: 提供以下决策问题的命题逻辑表达式:给出一个 迭代图G,是G哈密顿量?配方将由Z3检查。
输入格式为:
4
0 1
1 2
2 3
3 0
1 3
其中第一个数字表示顶点数,其余对是G中的所有边。
输出应为:0 1 2 3
显然输出总是数字1,...,n-1的一些排列,其中n = | V |但我不知道如何使用命题逻辑来处理整数。
感谢任何建议。
问候。
这是一个适用于给定输入的解决方案。如果我可以写一个perl例程来产生组合(n选择k)的边缘,那么我可以将它推广到任意数量的输入:
(declare-const v0 Bool)
(declare-const v1 Bool)
(declare-const v2 Bool)
(declare-const v3 Bool)
(declare-const e1 Bool)
(declare-const e2 Bool)
(declare-const e3 Bool)
(declare-const e4 Bool)
(declare-const e5 Bool)
(assert (xor (and e1 e2 e3 e4) (and e1 e2 e3 e5) (and e1 e2 e4 e5) (and e1 e3 e4 e5) (and e2 e3 e4 e5)))
(assert (and v0 v1 v2 v3))
(assert (=> e1 (and v0 v1)))
(assert (=> e2 (and v1 v2)))
(assert (=> e3 (and v2 v3)))
(assert (=> e4 (and v3 v0)))
(assert (=> e5 (and v1 v3)))
(check-sat)
(get-model)
答案 0 :(得分:2)
我们的想法是让SMT求解器生成n个数字,例如a1..an,然后断言以下所有内容:
也就是说,你只是描述一个“哈密尔顿循环”是什么,如果SMT求解器确实存在,它将找到一个。
现在,困难在于如何在SMTLib2中表达所有这些,以便Z3可以解析它。当然可以做到,但我建议使用更高级别的语言来提供与SMT求解器的绑定。例如,Haskell和Scala是两种可以编写Z3脚本的语言。这样,您只关注问题,宿主语言将为您处理幕后翻译。这需要一些学习宿主语言和相关库的投资,但在我看来这是值得的。
例如,以下是使用Haskell和Z3解决此问题的方法:http://gist.github.com/1715097。解决方案只有7行Haskell,您可以使用它来查询您想要的任何大小的图形。该解决方案利用了Haskell的强大功能和Z3的SMT求解器功能,提供了一个干净的界面。
答案 1 :(得分:0)
您可以使用布尔变量对边缘关系进行编码,例如使用R-5-4来表示R中是否为(5,4)。
设E为输入边缘关系。
将关系R约束为E的子集,使每个顶点恰好连接到R中的两个边。
现在将关系T约束为R的传递闭包。
如果T完全连接(所有T-n1-n2都为真),则R是Hamilton循环,(V,E)是Hamilton图。