在计划问题中。我想根据工作日的比例分配假期。现在,我有一个使用多个布尔标志的有效解决方案,但是扩展性不是很好。
from ortools.sat.python import cp_model
from math import ceil
model = cp_model.CpModel()
solver = cp_model.CpSolver()
days = model.NewIntVar(0, 365, 'days')
vacations = model.NewIntVar(0, 30, 'vacations')
for i in range(365 + 1):
flag_bool = model.NewBoolVar(f'days == {i}')
model.Add(days == i).OnlyEnforceIf(flag_bool)
model.Add(days != i).OnlyEnforceIf(flag_bool.Not())
model.Add(vacations == ceil(i * 30 / 365)).OnlyEnforceIf(flag_bool)
# test
model.Add(days == 300)
status = solver.Solve(model)
print(solver.Value(days), solver.Value(vacations))
有什么建议吗?
编辑:一个更笼统的问题是,是否存在更好的方法来实现一个从变量到另一变量的预先计算的任意映射。
答案 0 :(得分:0)
遵循洛朗的建议的解决方案:
ceil(days * 30 / 365) == (days * 30 + 364) // 365
因此
from ortools.sat.python import cp_model
model = cp_model.CpModel()
solver = cp_model.CpSolver()
days = model.NewIntVar(0, 365, 'days')
vacations = model.NewIntVar(0, 30, 'vacations')
tmp = model.NewIntVar(364, 365 * 30 + 364, 'days*30+364')
model.Add(tmp == days * 30 + 364)
model.AddDivisionEquality(vacations, tmp, 365)
# test
model.Add(days == 300)
status = solver.Solve(model)
print(solver.Value(days), solver.Value(vacations))