在Gurobi中添加二进制变量

时间:2019-03-17 11:33:28

标签: python linear-programming gurobi integer-programming

因此,当zz[i, j] = 1之间的距离小于或等于150和i时,我想添加一个二进制变量j,其中z[i, j] = 0除此以外。我有一个列表c,其中每个c[i][j]代表ij之间的距离。我当然不能在下面将z设置为普通的二进制变量:

y = m.addVars(I, J, vtype=GRB.BINARY, name="assign")

我想添加约束:

# One day mailing
m.addConstrs(
    z[i,j] <= y[i,j] for i in I for j in J,
    "Serve")

# Coverage Constraint
m.addConstr(
   quicksum(h[i] * z[i, j] for i in I for j in J) <= 
        0.9 * quicksum(h[i] * y[i, j] for i in I for j in J),
        "Cover")

其中h是带有整数的列表。如何设置z

1 个答案:

答案 0 :(得分:0)

首先,您需要添加z作为二进制变量:

z = m.addVars(I, J, vtype=GRB.BINARY, name="z")

然后,当且仅当z[i, j] = 1时,您需要约束以确保c[i, j] <= 150。 一种方法是使用指标约束:

z = 1 -> c <= 150
z = 0 -> c >= 150

这等效于

c > 150 -> z = 0
c < 150 -> z = 1

您将这些添加如下:

m.addConstrs((z[i, j] == 1) >> (c[i][j] <= 150) for i in I for j in J)
m.addConstrs((z[i, j] == 0) >> (c[i][j] >= 150) for i in I for j in J)

您还可以自己对此进行显式建模: 如果您在M的值上有mc[i][j] - 150的上限和下限(即,对于所有M >= c[i][j] - 150 >= m的限制是i, j),则可以使用以下约束:

M * (1-z) >= c - 150
m * z <= c - 150

如果c > 150,则两个不等式的右边将为正。然后,第一个强制1 - z = 1,因此强制z = 0。第二个不平等将被轻易满足。

如果c < 150,则右侧为负。第一个不平等变得微不足道,而第二个不平等迫使z = 1

对于Mc中的最大条目将起作用,对于m,如果所有-150均为非负数,则可以选择c[i][j]

您添加以下约束:

m.addConstrs( M * (1 - z[i, j]) >= c[i][j] - 150 for i in I for j in J )
m.addConstrs( m * z[i,j] <= c[i][j] - 150 for i in I for j in J )

请注意,我忽略了c = 150的情况。这是因为对于浮点数,总是只将等式视为在公差范围内,因此没有简单的方法可以区分严格和非严格不等式。您可以使用epsilon对此进行近似,例如:

z = 0 -> c >= 150 + epsilon