跳转到主要内容

在懒惰的约束

回答

评论

3评论

  • 伊莱陶尔康
    Gurobi员工Gurobi员工

    关于“gurobipy。GenConstr' object has no attribute 'Lazy'" error:懒惰的属性只能用于线性约束(若干对象),而不是一般的约束(GenConstr对象)像指标约束。解决问题,你必须用你的一般约束使用线性约束。

    让\ (z \)是一个二进制变量,\ (y \ [\ l形,u] \)一个连续变量,和\ (c \)一个常数。指标约束

    $ ${对齐*}z = 1 \ \开始意味着y = c \{对齐*}$ $

    可以使用以下两个约束条件线性化:

    $ $ \{对齐*}开始y & \ leq u + (c - u) y和z \ \ \组\魔法+ z (c - \魔法)。\{对齐*}$ $

    如果\ (z = 0 \),上面的两个约束条件成为\ \魔法\ leq y \ leq u \)。在这种情况下,\ (y \)不受这些限制。如果\ (z = 1 \),两个约束意味着\ (y = c \)。

    关于““NoneType”类型的对象没有len()错误:没有变量在模型的名字相等\ (\ texttt {y_r_i_j} \)。因此,你的电话Model.getVarByName ()返回\ (\ texttt{一}\)。Model.addVars ()使用\ \ texttt{名称}\)关键字参数为基础构建独特的变量名。实际的变量名称将类似\ (\ texttt {y_r_i_j (0, 0, 0)} \), \ (\ texttt {y_r_i_j[0, 0, 1]} \),等。例如:

    > > > x = m。addVars (name = ' x ')
    > > > m.update ()
    > > > m。getAttr (VarName, m.getVars ())
    (“x [0]”,“x [1]”,“x [2]”)

    一个更简单的方法来访问你的\ (y \)变量的回调是创建一个新的属性模型对象和分配\ \ texttt {y} \)变量。然后,您可以查询这个新属性在回调函数:

    y = m。addVars(它们vtype =伽马线暴。二进制名称=“y”)
    m。_y吗= y

    defsubtourelim(模型,):
    如果= = GRB.Callback.MIPSOL:
    yvals = model.cbGetSolution (model._y)

    注意,延迟约束添加通过回调函数也必须是线性的。所以在这种情况下,你还必须线性化指标约束。

    关于“没有变量名可用指数”错误:Model.getVarByName()查询变量的VarName属性。然而,这些属性是不可用的,直到模型更新。为了解决这个问题,电话Model.update ()第一:

    m.update ()
    0
  • 埃文Triou
    Gurobi-versary
    第一个评论
    第一个问题

    谢谢您的清晰和完整的支持,它帮助我和很多脚本现在没问题!

    我想提一些奇怪的错误我面临和解决:

    rij =(元组列表(r, i, j)]

    z =模型。addVars(它们vtype =伽马线暴。连续的,name = ' z ')
    模型。_z z =
    def mycallback(模型):
    如果在哪里= = GRB.Callback.MIPSOL:
    zvals = model.cbGetSolution (model._z)
    打印(zvals) #一切看起来很好,它输出关键字我期望
    为r, i, j在zvals.keys ():
    模型。cbLazy (zvals [r, i, j] > = 0)

    消息错误在约束:不支持的操作数类型(s) -:“bool”和“NoneType”我dict改为NoneType一旦我在循环使用。我取代了zvals模型。_z,它解决了问题,但我无法理解为什么?仍然是一个线性pb吗?我的约束是经典…

    我认为是因为z是不习惯其他地方所以Gurobi丢弃在分辨率和没有价值的影响。但我红,(https://support.gurobi.com/hc/en-us/community/posts/360078009912-set-the-value-of-unused-variables-https://support.gurobi.com/hc/en-us/community/posts/360078009912-set-the-value-of-unused-variables-),这是不可能的。

    任何想法?

    在任何情况下,再次感谢帮助:)

    0
  • 伊莱陶尔康
    Gurobi员工Gurobi员工

    \ (\ texttt {MIPSOL} \)回调就是每当Gurobi发现一个新的现任的解决方案。Model.cbGetSolution ()返回变量的值在这个新的解决方案。

    考虑任何\ ((r, i, j) \)元组。在新的现任Gurobi找到了解决方案\ (z_ {rij} \)可能的值\ \)(0。在这种情况下,\ (\ texttt {zvals [r, i, j]} \) = \ \) (0。所以\ (\ texttt {zvals (r, i, j) > = 0} \)是真正的表达式\ (\ texttt {0 > = 0} \)。在Python中,这个评估\ (\ texttt{真}\)。因此,下面的调用Model.cbLazy ()

    模型。cbLazy (zvals (r, i, j) > =0)

    相当于

    model.cbLazy(真正的)

    这并不是一个有效的方式调用Model.cbLazy ()。

    正如你指出的那样,你的代码工作当您使用\ (\ texttt{模型。_z} \)代替\ (\ texttt {zvals} \)在你调用Model.cbLazy ()。这是因为\ (\ texttt{模型。_z} \)存储实际\ (z \)变量值而不是他们的解决方案。因此,代码

    model.cbLazy(模型。_z (r, i, j) > =0)

    增加了懒惰的约束\ (z_ {rij} \组0 \),我认为这是你想要做什么。

    我也会注意的下界\ (z \)变量\默认(0 \)。这意味着Gurobi找到的任何解决方案中,所有的\ (z \)变量都是非负的。因此,懒惰的约束\ (z_ {rij} \组0 \)始终是多余的。

    0

登录留下你的评论。