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

时间:2019-07-12 15:51:59

标签: python or-tools

模型目标的一部分由标量列表中的项目加权。

我正在通过使用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]

1 个答案:

答案 0 :(得分:2)

这可以使用model.AddElement完成。

def AddElement(self, index, variables, target)

我发现AddElement的文档有点晦涩难懂,因此我将尝试用我认为更简单的术语来整理它。

它指出:Adds the element constraint: variables[index] == target.

  • 索引->您要使用的变量。
  • 变量->查找值表。
  • 目标->您希望其等于的值。

如果有的话,阅读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]