如何在 ortools 中更改约束参数的类型

Posted

技术标签:

【中文标题】如何在 ortools 中更改约束参数的类型【英文标题】:how to change the type of constraint's arguments in ortools 【发布时间】:2018-06-01 13:22:09 【问题描述】:

我不知道我的问题是否可行。我正在使用 ortools 来解决优化问题,并且我知道在部分条件中,参数应该定义为 double 类型,如下所示:

constraints[i] = solver.Constraint(0.0 , 10,0)

但我的问题是,我不想在创造条件时使用这种类型的论据。例如我想要一个列表。

所以我在我的代码中写了这个:

constraints[i] = solver.Constraint([1,2,3,...])

我得到了这个错误:

return _pywraplp.Solver_Constraint(self, *args)
NotImplementedError: Wrong number or type of arguments for overloaded 
function 'Solver_Constraint'.
Possible C/C++ prototypes are:
operations_research::MPSolver::MakeRowConstraint(double,double)
operations_research::MPSolver::MakeRowConstraint()
operations_research::MPSolver::MakeRowConstraint(double,double,std::string 
const &)
operations_research::MPSolver::MakeRowConstraint(std::string const &)

有没有办法改变条件参数的类型?

【问题讨论】:

希望您能在此处澄清您的更高级别目标。我知道如果你写constraint = solver.Constraint(0.0 , 10.0),它的意思是,“我要创建一个名为constraint 的表达式,表达式的值应该限制在[0, 10] 的范围内”。如果你写constraint = solver.Constraint([1,2,3,...]),你想表达什么意思? @CrepeGoat,正如你所说的constraint = solver.Constraint(0.0 , 10.0) 意味着你有一个名为constraint 的表达式,表达式的值应该是0到10之间的界限。但我不想限制表达式的值绑定到整数,实际上因为我的表达式是一些列表的总和,所以我想将它限制为一个列表。而且也不是一个界限,完全是一个列表。 【参考方案1】:

我的假设

您的约束表达式是“一些列表的总和”,这意味着类似于 the NumPy library 所做的事情:例如,如果您有两个值列表,[1, 2, 3][4, 5, 6],它们的总和将是 元素方面,s.t. [1, 2, 3] + [4, 5, 6] = [1+4, 2+5, 3+6] = [5, 7, 9]。 您的“列表约束”也是元素方面的;例如,[x1, x2, x3] <= [1, 2, 3] 表示 x1 <= 1x2 <= 2x3 <= 3。 您使用的是GLOP Linear Solver。 (我在下面所说的一切都适用于 ILP/CP/CP-SAT 求解器,但某些特定的方法名称/其他细节是不同的。)

我的答案

问题是,ortools 只允许您将 标量 值(如数字)设置为变量;可以这么说,您不能制作“列表变量”。

因此,您必须创建一个标量变量列表,以有效地表示同一事物。

例如,假设您希望您的“列表变量”是一个值列表,每个值都受到您存储在列表中的特定约束。假设您有一个上限列表:

upper_bounds = [1, 2, 3, ..., n]

你有几个像这样的求解器变量列表:

vars1 = [
    # variable bounds here are chosen arbitrarily; set them to your purposes
    solver.NumVar(0, solver.infinity, 'x0'.format(i))
    for i in range(n)
]
vars2 = [...]  # you define any other variable lists in the same way

然后,您将创建一个约束对象列表,列表中的每个上限都有一个约束:

constraints = [
    solver.Constraint(0, ubound)
    for ubound in upper_bounds
]

然后您将变量插入到您的约束中,但是这取决于您的问题:

# Example expression: X1 - X2 + 0.5*X3 < UBOUND
for i in range(n):
    constraints[i].SetCoefficient(vars1[i], 1)
    constraints[i].SetCoefficient(vars2[i], -1)
    constraints[i].SetCoefficient(vars3[i], 0.5)

希望这会有所帮助!我建议(另一个,如果你已经有的话)看看你的特定求解器的例子。可以找到 GLOP 的here。

【讨论】:

以上是关于如何在 ortools 中更改约束参数的类型的主要内容,如果未能解决你的问题,请参考以下文章

使用ortools时如何获取cpsolver的变量和约束

ortools如何添加非线性约束

在 google ortools 中添加析取约束

Ortools 在求解时设置约束

Python中如何使用ortools求解二次规划?

在 ORTools 中为每辆卡车设置不同的约束