gurobipy.MNLExpr#
- class MNLExpr#
Gurobi 矩阵友好的非线性表达式对象。一个
MNLExpr存储了一个密集的NLExpr对象数组,并使得在 Python 中使用单个数学表达式来制定一组非线性约束成为可能。通常,您会从
MVar对象开始构建一个MNLExpr,并应用Python运算符、非线性函数或两者的组合。只有在矩阵表达式无法通过MLinExpr或MQuadExpr捕获时,才会创建MNLExpr。具体来说,如果矩阵的任何元素不是最多2次的多项式,则会导致生成MNLExpr。一个
MNLExpr对象有一个表示其维度的shape,一个计算元素总数的size,以及一个给出维数的ndim。这些属性依赖于NumPy的ndarray类中的对应属性。在使用
MLinExpr对象时,您需要确保操作数的形状是兼容的。对于矩阵乘法,我们遵循Python的矩阵乘法运算符的规则:两个操作数都需要至少有一个维度,并且它们的内维度必须一致。更多信息请参考Python的文档。如果两个操作数具有相同的形状,其他二元操作(如加法和乘法)则很容易理解:操作是按点应用于匹配的索引上。对于具有不同形状的操作数,算术遵循NumPy的广播规则。更多信息请参考NumPy的文档。以下示例列出了从
MVar对象构建的各种表达式的对象类型和形状:from gurobipy import nlfunc ... x = model.addMVar((3,), name="x") # MVar, shape (3,) y = model.addMVar((3, 3), name="y") # MVar, shape (3,3) z = model.addMVar((3, 3), name="z") # MVar, shape (3,3) expr1 = 2.0 * x # MLinExpr, shape (3,) expr2 = 2.0 * x * y # MQuadExpr, shape (3,3) expr3 = 2.0 * x * y * z # MNLExpr, shape (3,3) expr4 = x / y # MNLExpr, shape (3,3) expr5 = nlfunc.sin(x) # MNLExpr, shape (3,)
非线性矩阵表达式用于构建非线性矩阵的一般约束。它们通常是临时对象,立即传递给
Model.addConstr或Model.addGenConstrNL,以向模型添加一组约束。这些约束始终是等式约束,表达式的左侧有一个结果变量。在Python代码中,可以使用任一方法添加这些约束。使用上一个示例中的MVar对象:# Add the constraint z_ij = sqrt(x_j + y_ij) for each (i, j) model.addConstr(z == nlfunc.sqrt(x + y)) # Add the constraint z_ij = x_j / y_ij for each (i, j) model.addGenConstrNL(z, x / y)
非线性不等式约束
无法使用
<=或>=运算符通过NLExpr对象指定非线性不等式约束。但是,您可以通过创建一个有界结果变量来制定等效的约束。例如,以下代码约束了\(log(x_i) \le 1\)对于\(i \in {0, 1, 2, 3}\):x = model.addMVar((4,)) res = model.addMVar(x.shape, lb=-GRB.INFINITY, ub=1.0) model.addGenConstrNL(res, nlfunc.log(x))
更多控制表达式创建
如果你想对生成的表达式树有更多的控制,你可以显式地选择进入非线性世界,使用
nl属性,这是MVar对象的一个属性。这被认为是高级用法。在绝大多数情况下,你不需要考虑非线性表达式在内部是如何表示的。MVar.nl返回一个MNLExpr对象,该对象包含一个表达式树的矩阵,每个表达式树代表一个单独的变量。任何涉及该对象的算术操作也将产生一个MNLExpr:x = model.addMVar((2, 2)) # MVar, shape (2,2) expr1 = x + 1.0 # MLinExpr, shape (2,2) expr2 = x.nl # MNLExpr, shape (2,2) expr3 = x.nl + 1.0 # MNLExpr, shape (2,2)
影响是微妙的,但可能会影响求解器如何处理约束。例如,以下两个约束表示相同的表达式集 \((x_i + y_i)^2\),但在求解器中具有不同的内部表示:
x = model.addMVar((5,)) y = model.addMVar((5,)) z = model.addMVar((5,)) c1 = model.addGenConstrNL(z, (x - y) ** 2) c2 = model.addGenConstrNL(z, (x.nl - y.nl) ** 2)
具体来说,第一种情况捕捉了展开形式的二次表达式 \(x_i^2 - 2 x_i y_i + y_i^2\)。第二种情况捕捉了一个非线性 表达式,其中\(x_i - y_i\)作为表达式树中的一个节点,并且 被显式地平方。
操作符的域限制
某些算术运算符可能不适用于操作数可能具有的整个域(例如,除以零),这会产生一些微妙的问题。有关所有详细信息,请参阅除法运算符和幂运算符的附加信息。
- property shape#
此表达式的形状。
- Returns:
一个整数元组
- property size#
此表达式中的元素总数。
- Returns:
一个整数
- property ndim#
此表达式中的维度数量。
- Returns:
一个整数
- sum(axis=None)#
求这个
MNLExpr的元素之和;返回一个MNLExpr对象。- Parameters:
axis – 一个整数,或
None。沿指定轴求和。如果设置为None,则沿此MNLExpr的所有轴进行求和。- Returns:
一个表示总和的
MNLExpr。
- item()#
对于一个包含单个元素的
MNLExpr,返回该元素的副本作为一个NLExpr对象。在一个包含多个元素的MNLExpr上调用此方法将会引发一个ValueError。- Returns:
一个
NLExpr对象