我很抱歉,如果这个问题是错误的,但我试图使用z3(在python中使用语言绑定)来解决一些非线性方程式,但遗憾的是,qfnra-nlsat和一般求解器都无法解决以下系统除非a,b和c全部给出:
y == 0.001 * (a ** 2.07) * (b ** 0.9) * (c ** 0.7) + 0.002
y > 0.0
我尝试了以下策略:
t = z3.Then('simplify', 'qfnra-nlsat')
我还尝试用一些中间名替换非线性部分,然后使用push()
使用增量求解器将指数部分添加回来。但是在这两种情况下,z3基本上都被卡住了(就我试过的时间长了不到1小时)。
我是CSP的新手和所涉及的理论背景,对不起,如果这是一个愚蠢的问题,但我想知道这种非线性是否超出(经验)z3可解决或我不使用它正确吗?谢谢!
修改
这是我机器上失败的python代码:
import z3
a = z3.Real('a')
b = z3.Real('b')
c = z3.Real('c')
y = z3.Real('y')
eq = [
y == 0.001 * (a ** 2.07) * (b ** 0.9) * (c ** 0.7) + 0.002,
y >= 0.0
]
t = z3.Then('simplify', 'qfnra-nlsat')
s = t.solver()
s.add(eq)
r = s.check()
print r
m = s.model()
print m
这是输出:
unknown
[y = 1/500 ]
修改
似乎z3 git repo的最新代码有点破碎了。我尝试了4.4.1版本,一切都很顺利。
后续问题,如果我只是在下面再添加一个约束:
a == 16.0
并且z3卡住了,我无法理解......似乎上面的附加约束非常简单,b和c的初始猜测都是1s应解决系统,但我想这就是' s不是z3如何工作?关于如何使用这个新约束解决系统的任何想法?
答案 0 :(得分:1)
假设我没有做出一些翻译错误,我在纯SMT-LIB界面中尝试了这一点,它似乎工作正常。
如果您在查看此内容后仍然遇到一些问题,请对您失败的整个示例进行编码,因为您可能会遇到一些不会导致其失败的限制。或者,可能是重载的Python运算符(例如,**
)没有被正确解释(虽然这似乎是权力的正确用法),所以你可能想要使用Z3 Python API的函数各种表达方式。
我添加了x
这个额外的^
变量只是为了仔细检查我是否正确使用(declare-const x Real)
(declare-const y Real)
(declare-const a Real)
(declare-const b Real)
(declare-const c Real)
; y == 0.001 * (a ** 2.07) * (b ** 0.9) * (c ** 0.7) + 0.002
(assert (= y (+ (* 0.001 (^ a 2.07) (^ b 0.9) (^ c 0.7)) 0.002)))
(assert (> y 0.0))
(check-sat-using qfnra-nlsat)
(get-model)
(assert (> x 1.0))
(assert (= x (^ 5.0 2.5))) ; check ^ means pow
(check-sat-using qfnra-nlsat)
(get-model)
作为权力,看起来是正确的(rise4fun link:http://rise4fun.com/Z3/plLQJ):< / p>
sat
(model
(define-fun a () Real
(- 1.0))
(define-fun b () Real
(- 1.0))
(define-fun c () Real
(- 1.0))
(define-fun y () Real
(+ (/ 1.0 500.0)
(* (- (/ 69617318994479297159441705182250977318952641791835914067365099344218850343780027694073822279020999411953209540560859156221731465694293028234177768119402105034869871366755227547291324996387.0
4000.0))
(^ (/ 1.0 8.0) 207.0))))
)
sat
(model
(define-fun a () Real
(- 1.0))
(define-fun b () Real
(- 1.0))
(define-fun c () Real
(- 1.0))
(define-fun x () Real
(root-obj (+ (^ x 2) (- 3125)) 2))
(define-fun y () Real
(+ (/ 1.0 500.0)
(* (- (/ 69617318994479297159441705182250977318952641791835914067365099344218850343780027694073822279020999411953209540560859156221731465694293028234177768119402105034869871366755227547291324996387.0
4000.0))
(^ (/ 1.0 8.0) 207.0))))
)
这会产生:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>