Gurobipy优化:如何设置变量等于0或大于等于100的约束
Gurobipy实现变量仅取0或≥100的约束方案
你需要实现的是典型的半连续取值约束,有两种成熟的实现方案:
方案1:使用Gurobi原生半连续变量(推荐)
*半连续变量(Semi-continuous)*的特性就是仅能取0,或者落在上下界[lb, ub]区间内的数值,完全匹配你的需求,不需要额外加约束,求解效率更高。
代码示例:
from gurobipy import GRB # 定义x为半连续变量,下界设为100,ub按你的业务场景设置x可取的最大值即可 x = model.addVars(T, M, vtype=GRB.SEMICONT, lb=100, ub=10000, name="x")
如果已经提前定义了x为连续变量,可以批量修改属性:
for t in T: for m in M: x[t,m].vtype = GRB.SEMICONT x[t,m].lb = 100
方案2:辅助二元变量+大M约束(兼容低版本/特殊场景)
如果因为版本限制或者其他需求不能用半连续变量,可以用辅助二元变量实现逻辑:
- 首先定义辅助二元变量和x的非负约束
from gurobipy import GRB # 定义辅助二元变量y,规则为y=1时x≥100,y=0时x=0 y = model.addVars(T, M, vtype=GRB.BINARY, name="y") # 先加x的非负约束,避免出现负数取值 model.addConstrs(x[t,m] >= 0 for t in T for m in M)
- 添加两组大M约束,其中
UB替换为你场景中x可取的最大合理值,不要设置过大避免数值稳定性问题
UB = 10000 # 按实际业务场景调整 # y=1时约束x≥100,y=0时该约束自动成立(x≥0满足要求) model.addConstrs(x[t,m] >= 100 * y[t,m] for t in T for m in M) # y=0时约束x≤0,结合非负约束得x=0;y=1时约束x≤UB,符合上限要求 model.addConstrs(x[t,m] <= UB * y[t,m] for t in T for m in M)
原方案问题说明
你之前同时添加x≥100和x<1两组约束是互斥的,会直接导致模型不可行,同时没有添加非负约束,所以会出现x取负数的情况。
内容的提问来源于stack exchange,提问作者Diego
相关产品推荐
相关产品推荐

