【发布时间】:2019-07-12 15:51:59
【问题描述】:
模型目标的一部分由标量列表中的项目加权。
我通过使用 0-1 范围变量的列表来解决这个问题,然后使用 LinearExpr.ScalProd 对目标进行加权。
有没有办法只使用一个整数变量(目标变量除外),我可以使用 lambda 或其他机制在表中查找变量的值?
这里是一些我有的示例代码,虽然我试图确定它可以更简洁。
def argmax(
model: cp_model.CpModel, values: List[int]
) -> Tuple[List[cp_model.IntVar], cp_model.IntVar]:
objective_var = model.NewIntVar(0, 1000000, "objective_var")
ret_vars = [model.NewIntVar(0, 1, "x(%i)" % i) for i in range(len(values))]
model.Add(sum(ret_vars) == 1)
model.Add(objective_var == cp_model.LinearExpr.ScalProd(ret_vars, values))
return [ret_vars, objective_var]
【问题讨论】:
-
这并不是您真正想要的答案,但请注意,您的
model.NewIntVar(0, 1, "x(%i)" % i)也可能只是model.NewBoolVar(f'x{i}')。 -
另外,在你自己的初始解决方案中,如果你只是想从
ret_vars中提取索引,你可以完全摆脱objective_var,直接使用model.Maximize(cp_model.LinearExpr.ScalProd(ret_vars, values))。 -
相反,如果您只需要
objective_var,另一种(而且更快)的方法是使用约束model.AddMaxEquality(objective_var, values)。出于好奇,您将使用 or-tools 来解决此问题的用例是什么,而不仅仅是使用例如NumPy 的np.argmax(实际上速度要快几个数量级)? -
感谢 cmets。我使用 IntVar 因为我认为 ScalProd 需要它。关于 argmax:我使用 argmax 作为说明性示例来演示我在做什么,我想将其用作最大化更复杂目标的一部分。