Gurobi 提供了线性项和二次项的直接表达方法,用户可以直接调用。但超过二次之后,有2种表达方式
(1)引入辅助变量,拆解为二次项表达。例如 x ^5 可以引入几个辅助变量 y=xz,z=w^2, w=x^2,这样每项都是二次项或者线性项。
eg1: w = s(0)×s(1)×s(2),此时变量w已经超过二次,需要建立中间变量v,使得
v = s(0)×s(1),最后变量可表示为: w = v×s(2)。
主要方案是通过model.addVar(name=“v”) 添加变量, model.addConstr(v==var_s[0]* var_s[1])添加约束来实现。
// w = s(0)*s(1)*s(2)
v = model.addVar(name="v") # 在model基础上添加变量,name="v"
model.addConstr(v==var_s[0]* var_s[1]) # 在model基础上添加约束
w = QuadExpr(v*var_s[2])
eg2: 建立表达式m = x * y * z + x * x * y,使得m最小 ,需要引入辅助变量,w, u, v, k
// 表达式: x * y * z + x * x * y
expr = QuadExpr()
w = expr.addTerms(1, x, y)
u = expr.addTerms(1, w, z)
v = expr.addTerms(1, x, w)
minimize u + v
QuadExpr.addTerms() 方法介绍(引用Gurobi说明书P580)
addTerms ( coeffs, vars, vars2=None )
Add new linear or quadratic terms into a quadratic expression.
Arguments:
coeffs: Coefficients for new terms; either a list of coefficients or a single coefficient. The
arguments must have the same size.
vars: Variables for new terms; either a list of variables or a single variable. The arguments
must have the same size.
vars2 (optional): Variables for new quadratic terms; either a list of variables or a single
variable. Only present when you are adding quadratic terms. The arguments must have
the same size.
Example usage:
expr.addTerms(1.0, x)
expr.addTerms([2.0, 3.0], [y, z])
expr.addTerms([2.0, 3.0], [x, y], [y, z])
(2)直接调用 Gurobi 的 addGenConstrPoly() 函数或者addGenConstrPow() 函数。那么 y = x^5 可以表达为:
// y = x^5
model.addGenConstrPoly(x, y, [1, 0, 0, 0, 0, 0])
model.addGenConstrPow(x,y,5)
如果所建模型是非凸的,可进行如下设置(9.0以上版本):
// # 建立模型
BFG = Model("BFG")
BFG.setParam('nonconvex', 2)