Pyomo线性规划报IndexedVar[1]组件未构造错误排查
Pyomo
IndexedVar未构造 报错排查 你遇到的Error retrieving component IndexedVar[1]: The component has not been constructed报错由多处代码语法、Pyomo建模逻辑错误共同导致,并非仅出现在目标函数行,具体错误点和修正方案如下:
具体错误点
- 核心触发报错的问题:ConcreteModel未完成实例化。原代码写为
QEMCAProfitModel = pyo.ConcreteModel,缺少实例化必需的括号,此时变量仅引用了Pyomo的模型类本身,而非可用的模型实例,后续绑定的变量、约束组件不会执行构造流程,访问索引变量时就会触发未构造错误。 - 语法错误1:目标函数行存在多余无意义反引号,
for iin I`位置和行尾的反引号会直接触发Python语法解析错误。 - 语法错误2:所有函数(结果打印函数、约束规则函数)内部的代码块没有正确缩进,不符合Python强制缩进的语法要求。
- 逻辑错误1:全局总量约束错误传入了作物索引集。预算约束、总土地面积约束这类对所有作物求和的全局约束是单条约束,不需要传入索引集
I,原写法会导致同一条约束被重复生成6次,增加无意义的计算量。 - 逻辑错误2:结果打印函数的松弛量计算部分变量名错误,循环约束的迭代变量为
i,但内部引用了未定义的Ci(Ci是你提前定义的单位成本参数字典),运行时会触发变量未定义错误。 - 逻辑错误3:单作物消费约束错误传入了作物索引集,每个消费约束仅对应单种作物的最低产出要求,属于单条约束,不需要传入索引集
I重复生成。
修正后可直接运行的代码
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import pyomo.environ as pyo def pyomoresults(model): # 结果打印函数 print('') print('=========================') print('QEMCAProfitModel Maximization Solution') print('=========================') print('') print('Objective Function Value at Optimum') for f in model.component_objects(pyo.Objective, active=True): print ('Objective', f) for index in f: print (' ', index, pyo.value(f[index])) print('') print('Decision Variable Values at Optimum') for v in model.component_objects(pyo.Var, active=True): print ('Variable', v) for index in v: print (' ', index, pyo.value(v[index])) print('') print ('Duals/Shadow Prices at Optimum') for d in model.component_objects(pyo.Constraint, active=True): print ('Constraint',d) for index in d: print (' ', index, model.dual[d[index]]) print('') print ("Slack at Optimum") for c in model.component_objects(pyo.Constraint, active=True): print (" Constraint", c) for index in c: print (" ", index, c[index].lslack(), ' - ', c[index].uslack()) # 实例化Concrete模型(必须加括号) QEMCAProfitModel = pyo.ConcreteModel() # 作物索引 I = [1,2,3,4,5,6] # 参数定义 # 单位面积利润 ETB/公顷 mPi = {1:15635.2, 2:9571.36, 3:13392.6, 4:39834.6, 5:49074.1, 6:11365.6} # 单位面积成本 ETB/公顷 crop_cost = {1:10467.37, 2:8160.47, 3:12392.22, 4:5702.01, 5:8265.88, 6:8514.31} # 决策变量:各作物种植面积 QEMCAProfitModel.L = pyo.Var(I, within=pyo.NonNegativeReals) # 目标函数:最大化总利润(去掉多余反引号) QEMCAProfitModel.Profit = pyo.Objective( expr=sum(mPi[i] * QEMCAProfitModel.L[i] for i in I), sense=pyo.maximize ) # 约束定义 # 预算约束(全局单约束,不需要传索引) def Budget_rule(model): return sum(crop_cost[i] * model.L[i] for i in I) <= 850636 QEMCAProfitModel.Budget_rule = pyo.Constraint(rule=Budget_rule) # 总土地面积上限约束 def Land_rule(model): return sum(model.L[i] for i in I) <= 47.77 QEMCAProfitModel.Land_rule = pyo.Constraint(rule=Land_rule) # 总土地面积下限约束(变量已经定义为非负,该约束实际可省略) def Land_rule_min(model): return sum(model.L[i] for i in I) >= 0 QEMCAProfitModel.Land_rule_min = pyo.Constraint(rule=Land_rule_min) # 各作物最低消费约束(单条约束,不需要传索引) QEMCAProfitModel.Consumption_rule_1 = pyo.Constraint( expr=4560.64 * QEMCAProfitModel.L[1] >= 51250 ) QEMCAProfitModel.Consumption_rule_2 = pyo.Constraint( expr=5764.71 * QEMCAProfitModel.L[2] >= 36710 ) QEMCAProfitModel.Consumption_rule_3 = pyo.Constraint( expr=9908.3 * QEMCAProfitModel.L[3] >= 30316 ) QEMCAProfitModel.Consumption_rule_4 = pyo.Constraint( expr=16614.81 * QEMCAProfitModel.L[4] >= 4850 ) QEMCAProfitModel.Consumption_rule_5 = pyo.Constraint( expr=20323.81 * QEMCAProfitModel.L[5] >= 4450 ) QEMCAProfitModel.Consumption_rule_6 = pyo.Constraint( expr=4400 * QEMCAProfitModel.L[6] >= 7100 ) # 配置对偶值后缀 QEMCAProfitModel.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT) # 求解 opt = pyo.SolverFactory('glpk') results = opt.solve(QEMCAProfitModel) # 输出结果 QEMCAProfitModel.display() QEMCAProfitModel.dual.display() pyomoresults(QEMCAProfitModel)
注:原代码中定义的总土地面积下限约束和变量
NonNegativeReals的定义域要求重复,可直接删除不影响计算结果;原成本参数名Ci和约束循环变量容易重名冲突,修正时改名为crop_cost避免歧义。
内容的提问来源于stack exchange,提问作者Israa Ameen Thiab
相关产品推荐
相关产品推荐

