如何在PYOMO的energy_balance约束中使用二进制变量insufficient_dispatch
Pyomo条件约束实现方案
Pyomo不支持直接在约束里写Python的if-else逻辑,必须把条件约束转化为线性约束组,这里用大M法解决你的需求,分两步完成:
1. 把二进制变量insufficient_dispatch[m]的逻辑转化为线性约束
你需要这个变量在lost_load[m] ≥ 0.1*load[m]时取1,否则取0,用大M法实现:
# 定义大M值,取场景中lost_load最大可能值的1.1倍(确保足够大) M = max(model.load.values()) * 1.1 # 极小值ε,避免浮点误差导致的边界歧义 ε = 1e-6 # 约束1:当insufficient_dispatch[m]=1时,lost_load[m] ≥ 0.1*load[m] def lost_load_high_rule(model, m): return model.lost_load[m] >= 0.1 * model.load[m] - M * (1 - model.insufficient_dispatch[m]) model.lost_load_high = pyo.Constraint(model.timeset, rule=lost_load_high_rule) # 约束2:当insufficient_dispatch[m]=0时,lost_load[m] ≤ 0.1*load[m] - ε def lost_load_low_rule(model, m): return model.lost_load[m] <= 0.1 * model.load[m] - ε + M * model.insufficient_dispatch[m] model.lost_load_low = pyo.Constraint(model.timeset, rule=lost_load_low_rule)
2. 实现基于insufficient_dispatch[m]的能量平衡约束
你的需求可以通过两组线性约束覆盖:
# 定义总供应表达式,简化后续约束写法 model.total_supply = pyo.Expression(model.timeset, rule=lambda model, m: model.solar_use[m] + model.wind_use[m] + model.e_out[m] - model.e_in[m] + model.lost_load[m]) # 基础约束:两种场景都满足0.9*grid[m] ≤ total_supply[m] def balance_base_rule(model, m): return 0.9 * model.grid[m] <= model.total_supply[m] model.balance_base = pyo.Constraint(model.timeset, rule=balance_base_rule) # 严格约束:仅当insufficient_dispatch[m]=0时,要求grid[m] ≤ total_supply[m] def balance_strict_rule(model, m): return model.grid[m] <= model.total_supply[m] + M * (1 - model.insufficient_dispatch[m]) model.balance_strict = pyo.Constraint(model.timeset, rule=balance_strict_rule)
逻辑说明
- 当
insufficient_dispatch[m]=0时,balance_strict约束生效,强制grid[m] ≤ total_supply[m],balance_base约束会自动满足; - 当
insufficient_dispatch[m]=1时,balance_strict约束中的M*(1-0)会让约束松弛,此时只有balance_base约束生效,即0.9*grid[m] ≤ total_supply[m]。
注意点
- 大M值不能太小,否则会限制模型可行域;也不能过大,避免数值计算不稳定;
- ε的取值要足够小,不会影响模型结果的合理性,仅用来避免边界条件下的二进制变量歧义。
内容的提问来源于stack exchange,提问作者Vesper
相关产品推荐
相关产品推荐

