Pyomo新手求助:遍历集合及其子集的两个独立方程未达预期
解决Pyomo集合与子集遍历的问题
嘿,作为Pyomo新手碰到这种集合遍历的问题太正常啦!我先帮你梳理下代码里的关键问题,再给你修正后的示例~
首先先把你提供的代码完整还原(补上必要的导入和模型定义):
from pyomo.environ import ConcreteModel, Set, Param model = ConcreteModel() model.E = Set(initialize = [0, 1, 2, 3]) model.E_n = Set(model.E, initialize = {0:[1,2,3,4,5], 1:[6,7,8,9,10], 2:[11,12,13,14,15], 3:[16,17,18,19,20]}) model.int_rate = 0.05 def R_discount_inv_init(model, i): return sum(1 / (1 + model.int_rate)**(i - 1) for i in model.E) model.cum_disc_inv_cost = Param(model.E, initialize = R_discount_inv_init) # 未完成的部分:def R_di...
核心问题分析
变量名冲突:这是导致你结果不符合预期的关键!在
R_discount_inv_init函数中,你把输入参数命名为i,但循环遍历model.E时又用了i作为循环变量,这会直接覆盖输入的i值。比如当你计算i=0对应的参数时,循环里的i会依次变成0、1、2、3,完全偏离了你原本想针对每个i∈E计算折现和的逻辑。折现逻辑可能不符合预期:当
i=0时,(i-1)等于-1,这会让(1+0.05)^-1变成1/1.05,而你的求和会把这个值重复计算多次,这大概率不是你想要的折现周期逻辑,得确认你的折现起始点是否正确。子集遍历逻辑缺失:你提到要处理两个独立的方程(涉及
E和E_n),但目前只看到针对E的Param定义,后续处理E_n时也容易出现类似的遍历错误。
修正后的代码示例
1. 修复折现参数的初始化函数
把循环变量改成和输入参数不同的名字(比如k),避免冲突:
def R_discount_inv_init(model, i): # 用k作为循环变量,避免覆盖输入的i return sum(1 / (1 + model.int_rate)**(k - 1) for k in model.E) model.cum_disc_inv_cost = Param(model.E, initialize = R_discount_inv_init)
2. 遍历子集E_n的示例(假设你要定义相关Param或约束)
如果是要计算每个i∈E对应的子集E_n[i]的某种统计值,比如元素求和:
# 定义Param:每个i对应的子集元素总和 def subset_sum_init(model, i): return sum(n for n in model.E_n[i]) model.subset_total = Param(model.E, initialize = subset_sum_init)
如果是要定义约束,比如每个子集的元素和不小于某个值:
from pyomo.environ import Constraint # 约束:每个i对应的子集元素和 >= 20 def subset_sum_constraint_rule(model, i): return sum(n for n in model.E_n[i]) >= 20 model.subset_sum_constraint = Constraint(model.E, rule=subset_sum_constraint_rule)
调试建议
写完代码后,可以用model.pprint()打印模型的所有组件,直观检查每个Param、Set的值是否符合预期:
model.pprint()
内容的提问来源于stack exchange,提问作者O.Ayo
相关产品推荐
相关产品推荐

