我正在尝试使用z3py作为优化求解器,以最大化从一张纸上切出的长方体的体积。 python API提供了Optimize()对象,但使用它似乎不可靠,给我的解决方案显然不准确。
我尝试使用h = opt.maximise
后跟opt.upper(h)
,并简单地检查模型,以及在将长方体添加到模型v = w*b*l
中和之后定义长方体的体积,并将目标设置为w*b*l
而不是v
。他们都没有给我任何类似的好解决方案。
from z3 import *
l = Real("l")
w = Real("w")
b = Real("b")
v = Real("v")
opt = Optimize()
width = 63.6
height = 51
opt.add(b+l <= width)
opt.add(w+b+w+l+w <= height)
opt.add(w > 0)
opt.add(b > 0)
opt.add(l > 0)
opt.add(v == w*b*l)
opt.maximize(w * b * l)
# h = opt.maximize(v)
print(opt.check())
# print(opt.upper(h))
print(opt.model())
输出:
unknown
[w = 1, b = 1, l = 47, v = 47]
这绝对不是最大值。将所有值设置为10可以提供满足约束条件的更好解决方案。
答案 0 :(得分:3)
Z3的优化器无法处理非线性问题。确实,这就是为什么它会打印unknown
的原因。当您看到调用check
返回unknown
的呼叫时,其确切含义是:Z3不知道问题是否可以解决,更不用说找到最佳解决方案了。
如果添加:
print(opt.reason_unknown())
在致电check
之后,您会看到:
(incomplete (theory arithmetic))
在这些情况下,对model
的调用将返回在解决问题时获得的一些中间结果z3
,但绝不能保证它是最优的。
您的问题是非线性的,因为您要乘变量。 (w
,b
和l
。)Z3 可以解决实际问题上的非线性可满足性问题,但不能解决优化问题。参见,例如:z3Opt optimize non-linear function using qfnra-nlsat
(请注意,与纯粹的可满足性相比,非线性优化对于实物而言要困难得多。因此,这不仅仅是“尚未实现”的问题。)