如何从Pyomo约束的index_set获取集合维度名称?
Pyomo约束索引集维度名称获取方法
问题背景
你定义了如下约束及索引集,希望从model.a.index_set()中获取维度名称(即Units和YEARS),用于输出对偶值时标注索引含义:
index_set_a = pyo.Set( initialize=[(p, j) for p in model.Units for j in model.YEARS if model.check_year[p] <= j] ) model.a = pyo.Constraint(index_set_a, rule=rule_a)
此前尝试修改集合定义时触发错误:Cannot apply a Set operator to an indexed Set component (IndexedSet),且处理Var时可用的var.index_set.subsets()逻辑无法直接复用。
核心问题
最初的index_set_a仅通过initialize生成无序元组集合,未与Units、YEARS原始子集建立关联,因此无法通过subsets()提取维度名称;而错误写法混淆了普通二维集合与IndexedSet的定义逻辑,导致报错。
解决方案
方案1:用filter参数定义带筛选的二维集合
直接基于原始子集的笛卡尔积,通过filter筛选符合条件的元素,集合会保留与原始子集的关联,可直接复用Var的维度名称获取逻辑:
# 正确定义索引集 index_set_a = pyo.Set( model.Units, model.YEARS, filter=lambda model, p, j: model.check_year[p] <= j ) model.a = pyo.Constraint(index_set_a, rule=rule_a) # 获取维度名称 index_set = model.a.index_set() for subset in index_set.subsets(): print(subset.name)
输出:
Units YEARS
方案2:通过within参数关联原始子集
若需保留initialize写法,可通过within指定元素来自Units与YEARS的笛卡尔积,再从within属性中提取原始子集:
# 定义关联原始子集的索引集 index_set_a = pyo.Set( dimen=2, within=model.Units * model.YEARS, initialize=[(p, j) for p in model.Units for j in model.YEARS if model.check_year[p] <= j] ) model.a = pyo.Constraint(index_set_a, rule=rule_a) # 获取维度名称 index_set = model.a.index_set() for subset in index_set.within.subsets(): print(subset.name)
同样会输出Units和YEARS。
错误原因说明
你此前尝试的写法:
index_set_a = pyo.Set( model.InstallableUnits, model.YEARS, initialize=[(p, j) for p in model.Units for j in model.YEARS if model.check_year[p] <= j] )
错误在于:将model.InstallableUnits和model.YEARS作为Set前两个参数时,Pyomo会认为你要创建IndexedSet(集合族),但此时传入的initialize参数是针对普通二维集合的初始化逻辑,两者冲突触发报错。
内容的提问来源于stack exchange,提问作者phaebz
相关产品推荐
相关产品推荐

