Почти всегда плохая идея представлять логические числа целыми числами в z3. Таким образом, вместо использования целочисленного вектора, когда вы говорите, что элементы находятся между 0-1, просто используйте логический вектор и конструкцию If
. Примерно так:
from z3 import *
def f(t):
return t ** 2 - t + 1
opt = z3.Optimize()
x = BoolVector('x', 30)
m = [If(x[i], f(i + 1), 0) for i in range(30)]
m_sum = z3.Sum(m)
opt.add(m_sum == 4285)
opt.minimize(z3.Sum([If(x[i], 1, 0) for i in range(30)]))
if z3.sat == opt.check():
model = opt.model()
print(model)
Когда я запускаю это, оно идет очень быстро и находит решение:
[x__0 = False,
x__1 = False,
x__2 = False,
x__3 = False,
x__4 = False,
x__5 = False,
x__6 = False,
x__7 = False,
x__8 = False,
x__9 = False,
x__10 = False,
x__11 = False,
x__12 = False,
x__13 = True,
x__14 = False,
x__15 = False,
x__16 = False,
x__17 = True,
x__18 = False,
x__19 = False,
x__20 = False,
x__21 = False,
x__22 = False,
x__23 = False,
x__24 = False,
x__25 = True,
x__26 = True,
x__27 = True,
x__28 = True,
x__29 = True]
Я не проверял, является ли это правильным решением, но в по крайней мере, вы должны начать!