Gurobi约束和目标函数

时间:2019-07-14 08:47:39

标签: linear-programming gurobi

我对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

这是代数的图像:

enter image description here

到目前为止,我的代码如下,

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数组。有帮助吗?

2 个答案:

答案 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