Pyomo中索引集上的累积约束表达式构建问题
问题:Pyomo中按(周,月份)维度设置特定产品的累积约束
我用Pyomo构建优化模型,需要为model.WEEKS和model.MONTHS维度下的auction*volume乘积设置累积上下限约束。现有约束规则生成的结果会包含所有月份的项,但我需要每个(week, month)键对应的约束仅包含该月份产品及Q24产品的累积项(例如(1, 'F24')对应auction[1,F24]*volume[1,F24] + auction[1,Q24]*volume[1,Q24]的累积求和)。请问能否通过单个hedge_rule定义实现该需求?
模型基础代码
from pyomo.environ import ConcreteModel, Set, Var, NonNegativeIntegers, Binary, Param model = ConcreteModel() model.WEEKS = Set(initialize=[1,2,3]) model.PRODS = Set(initialize=['Q24','J24','F24']) model.MONTHS = Set(initialize=['J24','F24']) model.volume = Var(model.WEEKS, model.PRODS, within=NonNegativeIntegers) model.auction = Var(model.WEEKS, model.PRODS, within=Binary) model.HedgeMin = Param(model.WEEKS, model.MONTHS, within=NonNegativeIntegers, initialize={(1,'J24'):45,(1,'F24'):45, (2,'J24'):90,(2,'F24'):90, (3,'J24'):135,(3,'F24'):135}) model.HedgeMax = Param(model.WEEKS, model.MONTHS, within=NonNegativeIntegers, initialize={(1,'J24'):60,(1,'F24'):60, (2,'J24'):120,(2,'F24'):120, (3,'J24'):180,(3,'F24'):180})
当前约束规则及问题
当前的约束规则会错误地将所有月份的项求和,代码如下:
def hedge_rule(model, i,j): subset = {x for x in model.WEEKS if x <= i} return (model.HedgeMin[i,j], sum(model.auction[i,j] * model.volume[i,j] for i in subset for j in model.MONTHS), model.HedgeMax[i,j]) model.hedge_const = Constraint(model.WEEKS, model.MONTHS, rule=hedge_rule)
问题点:
- 循环变量
i和j覆盖了函数参数,导致索引逻辑混乱 - sum迭代了所有
model.MONTHS,不符合仅包含目标月份和Q24的需求
期望的约束形式
Key : Lower : Body : Upper : Active (1, 'F24') : 45.0 :auction[1,F24]*volume[1,F24] + auction[1,Q24]*volume[1,Q24] : 60.0 : True (1, 'J24') : 45.0 :auction[1,J24]*volume[1,J24] + auction[1,Q24]*volume[1,Q24]: 60.0 : True (2, 'F24') : 90.0 :auction[1,F24]*volume[1,F24] + auction[2,F24]*volume[2,F24] + auction[1,Q24]*volume[1,Q24] + auction[2,Q24]*volume[2,Q24] : 120.0 : True (2, 'J24') : 90.0 :auction[1,J24]*volume[1,J24] + auction[2,J24]*volume[2,J24] + auction[1,Q24]*volume[1,Q24] + auction[2,Q24]*volume[2,Q24]: 120.0 : True (3, 'F24') : 135.0 :auction[1,F24]*volume[1,F24] + auction[2,F24]*volume[2,F24] + auction[3,F24]*volume[3,F24] + auction[1,Q24]*volume[1,Q24] + auction[2,Q24]*volume[2,Q24] + auction[3,Q24]*volume[3,Q24]: 180.0 : True (3, 'J24') : 135.0 :auction[1,J24]*volume[1,J24] + auction[2,J24]*volume[2,J24] + auction[3,J24]*volume[3,J24] + auction[1,Q24]*volume[1,Q24] + auction[2,Q24]*volume[2,Q24] + auction[3,Q24]*volume[3,Q24]: 180.0 : True
解决方案:单个规则实现需求
可以通过调整sum的迭代范围实现,核心是针对每个(i,j),只累积该月份j和固定产品Q24在所有<=i的周中的auction*volume乘积。修改后的约束规则如下:
def hedge_rule(model, i, j): # 定义累积的周范围:所有小于等于当前周i的周 cumulative_weeks = [x for x in model.WEEKS if x <= i] # 求和项:每个累积周x对应的(x,j)和(x,'Q24')的auction*volume total = sum(model.auction[x, prod] * model.volume[x, prod] for x in cumulative_weeks for prod in [j, 'Q24']) return (model.HedgeMin[i,j], total, model.HedgeMax[i,j]) model.hedge_const = Constraint(model.WEEKS, model.MONTHS, rule=hedge_rule)
逻辑说明
cumulative_weeks筛选出当前周及之前的所有周,实现累积效果- 内层循环指定产品为
[j, 'Q24'],确保只包含目标月份产品和Q24 - 避免使用与函数参数同名的循环变量(用x代替i,prod代替j),防止索引覆盖
运行后生成的约束将完全符合你期望的形式。
内容的提问来源于stack exchange,提问作者r0bt
相关产品推荐
相关产品推荐

