You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

逻辑说明

  1. cumulative_weeks筛选出当前周及之前的所有周,实现累积效果
  2. 内层循环指定产品为[j, 'Q24'],确保只包含目标月份产品和Q24
  3. 避免使用与函数参数同名的循环变量(用x代替i,prod代替j),防止索引覆盖

运行后生成的约束将完全符合你期望的形式。

内容的提问来源于stack exchange,提问作者r0bt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 04:57:08