【问题标题】:Adding binary variable in Gurobi在 Gurobi 中添加二进制变量
【发布时间】:2019-03-17 11:33:27
【问题描述】:

所以我想在ij 之间的距离小于或等于150 和z[i, j] = 0 时添加一个二进制变量z 其中z[i, j] = 1。我有一个列表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

【问题讨论】:

    标签: python linear-programming gurobi integer-programming


    【解决方案1】:

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

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

    那么你需要约束来确保z[i, j] = 1当且仅当c[i, j] &lt;= 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)
    

    您也可以自己显式地建模: 如果c[i][j] - 150 的值有Mm 的上限和下限(即,所有i, jM &gt;= c[i][j] - 150 &gt;= m),则可以使用以下约束:

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

    如果c &gt; 150,则两个不等式的右侧都是正数。然后第一个强制1 - z = 1,因此强制z = 0。第二个不等式将很容易得到满足。

    如果c &lt; 150,则右侧为负数。第一个不等式变得微不足道,而第二个不等式强制z = 1

    对于Mc 中的最大输入数可以,对于m,如果所有c[i][j] 都是非负数,您可以选择-150

    您可以按如下方式添加这些约束:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-01
      相关资源
      最近更新 更多