下面代码里的“x.sum(i+1,'*') /20”就是上面举例中的x
from gurobipy import *
M=3
N=100
m=Model('dis')
n=[20,10,1]
x=m.addVars(M,N,vtype=GRB.BINARY,name='x')
m.addConstrs( (math.ceil(x.sum(i+1,'*') /n[i])-x.sum(i+1,'*') /n[i]>=0.05 for i in range(M))," C1 ")
运行结果及详细报错内容
File D:\xlsdata.py:40 in
m.addConstrs( (math.ceil(x.sum(i+1,'') /n[i])-x.sum(i+1,'') /n[i]>=0.05 for i in range(M))," C2 ")
TypeError: must be real number, not gurobipy.LinExpr
我的解答思路和尝试过的方法
我之前在matlab中用的就是ceil(x)-x>=0.05,但是在gurobi里行不通,我知道ceil不能用,但是也不知道能用什么。搜了MODEL.addGenConstrIndicator(binvar, binval, expression, name=""),也用不好
到底怎么写这个约束才能实现0.95Z
加两个约束条件限制x.sum(i+1,'') / n[i]的范围试试:
from gurobipy import *
import math
M = 3
N = 100
Z = 20 # 你可以设置Z的值
m = Model('dis')
n = [20,10,1]
x = m.addVars(M, N, vtype=GRB.BINARY, name='x')
# 约束条件1: 0.95Z < x.sum(i+1,'*') / n[i]
m.addConstrs((x.sum(i+1,'*') / n[i] >= 0.95 * Z for i in range(M)), "C1")
# 约束条件2: x.sum(i+1,'*') / n[i] <= Z
m.addConstrs((x.sum(i+1,'*') / n[i] <= Z for i in range(M)), "C2")
Gurobi在Python里面并没有提供ceil函数来约束变量,但是可以通过其他方法来实现类似的效果。
一种方法是使用线性不等式来表示变量x的上限。如果要求x≥ceil(y),可以表示为x-y+1≥0。
另一种方法是使用Gurobi的整数变量和分段线性函数(piecewise linear function)来实现类似的效果。可以通过在变量x上限设置为整数,并在目标函数中添加一个分段线性函数来模拟ceil函数的效果。
如果你要求x必须是整数,可以这样设置
x = m.addVar(vtype=GRB.INTEGER)
如果你需要分段线性函数可以这样添加
m.setPWLObj(x, [y], [1])
这样就能在Gurobi里面实现类似ceil函数的效果了。
可以改为:
from gurobipy import *
M=3
N=100
m=Model('dis')
n=[20,10,1]
x=m.addVars(M,N,vtype=GRB.BINARY,name='x')
m.addConstrs( (x.sum(i+1,'*') /n[i] - math.floor(x.sum(i+1,'*') /n[i])<=0.95 for i in range(M))," C1 ")
m.update()
m.optimize()