是否可以仅使用一个整数变量使用 or-tools 来计算 argmax?

Posted

技术标签:

【中文标题】是否可以仅使用一个整数变量使用 or-tools 来计算 argmax?【英文标题】:Is it possible to compute argmax with or-tools with just one integer variable? 【发布时间】: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'xi') 另外,在你自己的初始解决方案中,如果你只是想从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 作为说明性示例来演示我在做什么,我想将其用作最大化更复杂目标的一部分。 【参考方案1】:

这可以使用 model.AddElement 来完成。

def AddElement(self, index, variables, target)

我发现 AddElement 的文档有点神秘,所以我会尝试用我认为更简单的术语来整理它。

上面写着:Adds the element constraint: variables[index] == target.

Index -> 要查找的变量。 变量 -> 查找值表。 目标 -> 您希望它等于的值。

如果有的话,阅读 C++ 代码会更容易理解。

Constraint CpModelBuilder::AddElement(IntVar index,
                                      absl::Span<const int64> values,
                                      IntVar target) 

将所有这些放在一起,我们得到:

def argmax(
    model: cp_model.CpModel, values: List[int]
) -> Tuple[cp_model.IntVar, cp_model.IntVar]:
    objective_var = model.NewIntVar(0, 1000000, "objective_var")
    ret_var = model.NewIntVar(0, len(values) - 1, "x")
    model.AddElement(ret_var, values, objective_var)

    return [ret_var, objective_var]

【讨论】:

以上是关于是否可以仅使用一个整数变量使用 or-tools 来计算 argmax?的主要内容,如果未能解决你的问题,请参考以下文章

or-tools,CP SAT:在目标函数中使用 AddDivisionEquality 的目标

自定义约束OR-Tools //约束编程

如何使用 or-tools 和 google-distance 矩阵创建车辆路线优化问题,同时仅取消结束位置?

如何在我们的 MIP 问题中使用 or-tools 设置像 y = max(x1,x2,x3) 这样的等式约束?

or-tools python中的变量除法

如何在 Or-tools 中对变量进行排序?