Gurobi多周期设施选址问题中决策变量约束的正确实现
多周期设施选址约束的正确实现方式
问题背景
定义参数:
period = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] facility = ['f1', 'f2', 'f3', 'f4', 'f5']
声明二进制决策变量:
X_f = m.addVars(facility, period, vtype=GRB.BINARY, name="X_f")
需要实现的约束逻辑:
- 每个设施若在周期0未开启(
X_f[f,0]=0),则后续所有周期必须保持关闭 - 每个设施若在周期0已开启(
X_f[f,0]=1),则后续所有周期必须保持开启
错误原因分析
你之前尝试通过判断X_f[f,0].X的值来添加约束,报错AttributeError: Index out of range for attribute 'X'的核心原因是:变量的.X属性只有在模型优化完成后才会被赋值,在构建约束阶段直接访问这个属性是无效的,此时变量还没有具体的数值。
正确实现方法
需要通过线性约束直接关联周期0和后续周期的变量,利用二进制变量的特性强制两者取值一致,无需提前判断变量值。
方法一:直接强制等价约束
对每个设施,要求后续所有周期的变量值与周期0完全相等:
for f in facility: # 遍历周期1到11(跳过周期0) for t in period[1:]: m.addConstr( X_f[f, t] == X_f[f, 0], name=f"facility_{f}_fixed_status_{t}" )
方法二:拆分为两个单向约束(逻辑等价)
如果需要更清晰地体现约束逻辑,可以拆成两个约束:
- 若周期0未开启,后续周期不能开启:
X_f[f,t] ≤ X_f[f,0] - 若周期0已开启,后续周期必须开启:
X_f[f,t] ≥ X_f[f,0]
代码实现:
for f in facility: for t in period[1:]: # 约束1:周期0关闭则后续必须关闭 m.addConstr(X_f[f, t] <= X_f[f, 0], name=f"no_open_after_close_{f}_{t}") # 约束2:周期0开启则后续必须保持开启 m.addConstr(X_f[f, t] >= X_f[f, 0], name=f"no_close_after_open_{f}_{t}")
这两种方法逻辑完全等价,都能实现你需要的设施状态固定规则。
内容的提问来源于stack exchange,提问作者noobcoder
相关产品推荐
相关产品推荐

