如何改进Z3py中基于二进制搜索的优化
我试图用Z3py优化基于最小化的集合覆盖问题(SCP41)的一个实例 结果如下: 使用 (1) 我知道Z3支持优化()。很多时候,我在SCP41和其他实例中都达到了最佳状态,但有少数情况下没有达到 (2) 我明白,如果我在没有优化模块的情况下使用z3pyapi,我将不得不执行@leonardodemoura()中描述的典型顺序搜索。它从不给我结果 我的方法 (3) 我尝试通过实现一个二进制搜索来改进顺序搜索方法,类似于它在()中解释@Philippe的方式,当我运行算法时,它会等待,但没有得到任何结果 我知道二进制搜索应该更快,并且在这种情况下有效?我还知道实例SCP41是一个很大的东西,产生了许多限制,它变得非常组合,这是我的完整代码(),这是我的二进制搜索它:如何改进Z3py中基于二进制搜索的优化,z3,z3py,sat-solvers,Z3,Z3py,Sat Solvers,我试图用Z3py优化基于最小化的集合覆盖问题(SCP41)的一个实例 结果如下: 使用 (1) 我知道Z3支持优化()。很多时候,我在SCP41和其他实例中都达到了最佳状态,但有少数情况下没有达到 (2) 我明白,如果我在没有优化模块的情况下使用z3pyapi,我将不得不执行@leonardodemoura()中描述的典型顺序搜索。它从不给我结果 我的方法 (3) 我尝试通过实现一个二进制搜索来改进顺序搜索方法,类似于它在()中解释@Philippe的方式,当我运行算法时,它会等待,但没有得到任
def min(F, Z, M, LB, UB, C):
i = 0
s = Solver()
s.add(F[0])
s.add(F[1])
s.add(F[2])
s.add(F[3])
s.add(F[4])
s.add(F[5])
r = s.check()
if r == sat:
UB = s.model()[Z]
while int(str(LB)) <= int(str(UB)):
C = int(( int(str(LB)) + int(str(UB)) / 2))
s.push()
s.add( Z > LB, Z <= C)
r = s.check()
if r==sat:
UB = Z
return s.model()
elif r==unsat:
LB = C
s.pop()
i = i + 1
if (i > M):
raise Z3Exception("maximum not found, maximum number of iterations was reached")
return unsat
def最小值(F、Z、M、LB、UB、C):
i=0
s=解算器()
s、 添加(F[0])
s、 添加(F[1])
s、 加(F[2])
s、 加(F[3])
s、 加上(F[4])
s、 加(F[5])
r=s.检查()
如果r==sat:
UB=s.model()[Z]
而int(str(LB))LB,zm:
raise Z3Exception(“未找到最大值,已达到最大迭代次数”)
未售出的退货
这是我在初始测试中使用的另一个实例(),它在任何情况下都运行良好
什么是不正确的二进制搜索或Z3的某些概念没有正确应用
问候,,
亚历克斯我不认为你的问题与最小化本身有关。如果在程序中的
r=s.check()
之后放置一个print r
,您会看到z3很难返回结果。所以你的循环甚至不会执行一次
因为你的程序太大了,所以不可能通读它!但我看到了很多这样的东西:
Or(X250 == 0, X500 == 1)
这表明变量X250
X500
等(有很多)实际上是布尔值,而不是整数。如果这确实是真的,你应该绝对坚持使用布尔语。求解整数约束比求解纯布尔约束要困难得多,当您使用整数来像这样对布尔进行建模时,底层解算器只会探索无法到达的搜索空间
如果确实如此,即如果您使用Int
值来建模布尔值,我强烈建议您对问题进行建模,以摆脱Int
值,只使用布尔值。如果您提出问题的“小”实例,我们可以帮助您进行建模
如果您确实需要
Int
值(很可能是这样),那么我会说您的问题对于SMT解算器来说太难了,无法有效处理。您最好使用其他针对此类优化问题进行优化的系统。我知道,将Ints值更改为Bools值,消除了模型的大部分约束,并使Z3更容易求解,这是相当可观的。为了更好地理解,我在初始问题的末尾添加了一个带有小实例的代码;所以你应该让他们变成布尔人。看起来你有伪布尔约束;i、 例如,“这N个布尔值中最多有K个是真的”;可通过Pb
约束直接建模。看看这个答案:一旦你完全摆脱了整数,我认为z3将很好地解决这个问题。您甚至可能不需要“二进制搜索”;但这是需要明确检查的。