如何在Pyomo中为变量建立随首个集合元素变化的二级索引
Pyomo创建元素对应不同子集合的双索引变量
常规场景(统一子集合)
当第一个集合N的所有元素对应相同的第二个集合U时,实现方式很直接:
from pyomo.environ import* model = ConcreteModel() N=[1,2,3] U=['A','B','C','D'] model.X = Var(N,U,within=NonNegativeReals) model.X.pprint()
输出结果:
X : Size=12, Index=X_index Key : Lower : Value : Upper : Fixed : Stale : Domain (1, 'A') : 0 : None : None : False : True : NonNegativeReals (1, 'B') : 0 : None : None : False : True : NonNegativeReals (1, 'C') : 0 : None : None : False : True : NonNegativeReals (1, 'D') : 0 : None : None : False : True : NonNegativeReals (2, 'A') : 0 : None : None : False : True : NonNegativeReals (2, 'B') : 0 : None : None : False : True : NonNegativeReals (2, 'C') : 0 : None : None : False : True : NonNegativeReals (2, 'D') : 0 : None : None : False : True : NonNegativeReals (3, 'A') : 0 : None : None : False : True : NonNegativeReals (3, 'B') : 0 : None : None : False : True : NonNegativeReals (3, 'C') : 0 : None : None : False : True : NonNegativeReals (3, 'D') : 0 : None : None : False : True : NonNegativeReals
需求与错误尝试
现在需要让N的每个元素对应不同大小的U子集合,直接用列表的列表传入Var()会触发维度不匹配的错误:
错误代码:
from pyomo.environ import* model = ConcreteModel() N=[1,2,3] U=[['A','B','C','D'],['B','C','E','G'],['A','C','D']] model.X = Var(N,U,within=NonNegativeReals) model.X.pprint()
报错信息:
The value=['A', 'C', 'D'] has dimension 3 and is not valid for Set OrderedScalarSet which has dimen=4
期望输出:
X : Size=12, Index=X_index Key : Lower : Value : Upper : Fixed : Stale : Domain (1, 'A') : 0 : None : None : False : True : NonNegativeReals (1, 'B') : 0 : None : None : False : True : NonNegativeReals (1, 'C') : 0 : None : None : False : True : NonNegativeReals (1, 'D') : 0 : None : None : False : True : NonNegativeReals (2, 'B') : 0 : None : None : False : True : NonNegativeReals (2, 'C') : 0 : None : None : False : True : NonNegativeReals (2, 'E') : 0 : None : None : False : True : NonNegativeReals (2, 'G') : 0 : None : None : False : True : NonNegativeReals (3, 'A') : 0 : None : None : False : True : NonNegativeReals (3, 'C') : 0 : None : None : False : True : NonNegativeReals (3, 'D') : 0 : None : None : False : True : NonNegativeReals
解决方案
通过字典映射+生成有效索引对的方式实现需求:
- 用字典定义N中每个元素对应的U子集合
- 生成所有符合要求的
(N元素, U元素)索引对 - 将这个索引对集合传入
Var()的参数中
代码实现:
from pyomo.environ import* model = ConcreteModel() N = [1,2,3] # 字典存储每个N元素对应的U子集 U_map = { 1: ['A','B','C','D'], 2: ['B','C','E','G'], 3: ['A','C','D'] } # 生成所有有效索引组合 X_index = [(n, u) for n in N for u in U_map[n]] # 创建变量 model.X = Var(X_index, within=NonNegativeReals) model.X.pprint()
运行这段代码即可得到期望的输出。
内容的提问来源于stack exchange,提问作者Samuel M
相关产品推荐
相关产品推荐

