我是SMT解决方案的新手。我想知道如何编码一个有4/6节点的简单TSP问题?我很困惑如何使用Z3pay Api设置我的约束。任何形式的提示或帮助都会非常感激。
由于
答案 0 :(得分:0)
有一个很好的示例可能对您有用: http://z3.codeplex.com/SourceControl/changeset/view/1235b3ea24d9#examples/python/hamiltonian/hamiltonian.py
答案 1 :(得分:0)
您可以将TSP问题表述为ILP问题。现在的问题是如何将TSP编码为ILP。有两个众所周知的答案:Miller–Tucker–Zemlin和Dantzig–Fulkerson–Johnson。
基本思想如下:假设我们有n个城市。让我们用d_ij表示城市i和j之间的距离,让我们用x_ {ij}表示布尔值(0或1),TSP是否包含从i到j的边。然后找到最小的游览手段
minimize sum_{i,j} x_{ij} d_{ij}
使得x_ {ij}描述一个循环。在这两个条件下,我们得到一个或多个周期:
sum_{j} x_{ij} = 1 for all i exactly one outgoing edge per city
sum_{i} x_{ij} = 1 for all j exactly one ingoing edge per city
现在我们必须排除解决方案包含多个周期的情况。我们可以添加Dantzig–Fulkerson–Johnson个条件的指数数量:
sum_{i in S} sum_{j in S} x_{ij} < |S| for all proper subsets S of {1, ..., n}
请注意,如果我们的解决方案包含两个周期,则对于S是周期之一的顶点集,则x_ {ij} -sum将为| S |。另一方面,如果只有一个周期,则x_ {ij} -sum将永远不会达到| S |,例如,如果从{1,...,n}中删除一个顶点,则剩余边数为n-2,但| S | = n-1。
当然,我们不需要的是指数级的约束,因此我们寻求一种更聪明的方式来排除子周期情况。这就是Miller–Tucker–Zemlin跳入的位置。
一种不同的方法是简单地忽略子循环问题,计算一个解,并检查该解是否包含子循环。如果是这样,请通过将其添加为延迟约束来排除该解决方案,然后重复进行直到获得单周期解决方案。此处的关键字为lazy constraint。