我对Gurobi
很陌生。我正在尝试解决以下ILP
最小化\ sum_i c_i y_i + \ sum_i \ sum_j D_ {ij} x_ {ij}
此处D
被存储为2D numpy array
。
我的约束如下
x_ {ij} <= y_i y_i + \ sum_j x_ {ij} = 1
这是代数的图像:
到目前为止,我的代码如下,
from gurobipy import *
def gurobi(D,c):
n = D.shape[0]
m = Model()
X = m.addVars(n,n,vtype=GRB.BINARY)
y = m.addVars(n,vtype=GRB.BINARY)
m.update()
for j in range(D.shape[0]):
for i in range(D.shape[0]):
m.addConstr(X[i,j] <= y[i])
我不确定如何实现第二个约束并指定目标函数,因为目标术语包括一个numpy数组。有帮助吗?
答案 0 :(得分:1)
这是一个非常简单的情况。您可以用这种方式编写第一个约束。命名约束是个好习惯。
m.addConstrs((x[i,j] <= y[j] for i in range(D.shape[0]) for j in range(D.shape[0])), name='something')
如果要添加第二个约束,则可以这样编写
m.addConstrs((y[i] + x.sum(i, '*') <= 1 for i in range(n)), name='something')
您可以使用digEmAll建议的quicksum编写第二个等式。
使用quicksum
的好处是您可以添加if
条件,这样就不会对j
的所有值求和。这是你怎么做
m.addConstrs((y[i] + quicksum(x[i, j] for j in range(n)) <= 1 for i in range(n)), name='something')
如果只需要一些j值来求和,则可以:
m.addConstrs((y[i] + quicksum(x[i, j] for j in range(n) if j condition) <= 1 for i in range(n)), name='something')
我希望这对您有帮助
答案 1 :(得分:0)
不幸的是,我没有GUROBI,因为它真的很贵...
但是,根据this tutorial,第二个约束应该这样实现:
for i in range(n):
m.addConstr(y[i] + quicksum(X[i,j] for j in range(n), i) == 1)
目标函数可以定义为:
m.setObjective(quicksum(c[i]*y[i] for i in range(n)) + quicksum(quicksum(D[i,j] * x[i,j]) for i in range(n) for j in range(n)), GRB.MINIMIZE)
N.B:我假设D
是矩阵n x n