我正在尝试解决一个问题,例如我有一个 4点,每两点之间有一个成本。现在我想找到一个节点序列,总成本小于一个边界。我写了一段代码,但似乎没有用。主要问题是我已经定义了一个python函数并尝试在约束中调用它。
以下是我的代码:我有一个函数def getVal(n1,n2):
,其中n1, n2
是Int Sort
。行Nodes = [ Int("n_%s" % (i)) for i in range(totalNodeNumber) ]
将4个点定义为Int排序,当我添加约束s.add(getVal(Nodes[0], Nodes[1]) + getVal(Nodes[1], Nodes[2]) < 100)
时,它立即调用getVal
函数。但我想要的是,当Z3决定节点[0],节点[1],节点[2],节点[3]的值时,应该调用该函数来获得点到点之间的成本。
from z3 import *
import random
totalNodeNumber = 4
Nodes = [ Int("n_%s" % (i)) for i in range(totalNodeNumber) ]
def getVal(n1,n2):
# I need n1 and n2 values those assigned by Z3
cost = random.randint(1,20)
print cost
return IntVal(cost)
s = Solver()
#constraint: Each Nodes value should be distinct
nodes_index_distinct_constraint = Distinct(Nodes)
s.add(nodes_index_distinct_constraint)
#constraint: Each Nodes value should be between 0 and totalNodeNumber
def get_node_index_value_constraint(i):
return And(Nodes[i] >= 0, Nodes[i] < totalNodeNumber)
nodes_index_constraint = [ get_node_index_value_constraint(i) for i in range(totalNodeNumber)]
s.add(nodes_index_constraint)
#constraint: Problem with this constraint
# Here is the problem it's just called python getVal function twice without assiging Nodes[0],Nodes[1],Nodes[2] values
# But I want to implement that - Z3 will call python function during his decission making of variables
s.add(getVal(Nodes[0], Nodes[1]) + getVal(Nodes[1], Nodes[2]) + getVal(Nodes[2], Nodes[3]) < 100)
if s.check() == sat:
print "SAT"
print "Model: "
m = s.model()
nodeIndex = [ m.evaluate(Nodes[i]) for i in range(totalNodeNumber) ]
print nodeIndex
else:
print "UNSAT"
print "No solution found !!"
如果这不是解决问题的正确方法,那么请您告诉我解决问题的其他替代方法。我可以使用Z3求解器对这类问题进行编码以找到最佳的航路点序列吗?
答案 0 :(得分:0)
我不明白你需要解决什么问题。毫无疑问,getVal的制定方式没有意义。它不使用参数n1,n2。如果要检查模型生成的值,则在Z3从调用check()返回后执行此操作。
答案 1 :(得分:0)
我认为您不能在SMT逻辑中使用python函数。你还可以将getVal定义为像这样的函数
getVal = Function('getVal',IntSort(),IntSort(),IntSort())
将边权限制为
s.add(And(getVal(0,1)==1,getVal(1,2)==2,getVal(0,2)==3))
getVal的前两个输入参数表示节点ID,最后一个整数表示权重。