因此,当z
和z[i, j] = 1
之间的距离小于或等于150时,我想添加二进制变量i
,其中j
,否则z[i, j] = 0
。我有一个列表c
,其中每个c[i][j]
代表i
和j
之间的距离。我当然不能将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
?
首先,您需要将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
的值有上限和下限m
和c[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
。
对于M
,c
的最大进入将会这样做,对于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