Pyomo报错:ScalarParam未构造即求值,求解决方案
解决Pyomo中"ValueError: Evaluating the numeric value of parameter 'ScalarParam' before the Param has been constructed"错误
错误信息
执行代码时触发如下错误:
ValueError: Evaluating the numeric value of parameter 'ScalarParam' before the Param has been constructed (there is currently no value to return).
可复现代码片段
本人正在优化一个大型模型,以下是能复现该问题的代码:
from pyomo.environ import ConcreteModel, Set, RangeSet, Param, Var, Objective, Constraint, SolverFactory model = ConcreteModel() model.days = Set(initialize=RangeSet(31)) T = model.days model.Y = Param(initialize=1) model.L= Param(initialize=330) model.LL= Param(initialize=3300) model.LU= Param(initialize=3300) model.U= Param(initialize=250) model.X0= Param(initialize=0) model.M= Var(T,bounds=(0, None), initialize = 10) model.X= Var(T,bounds=(0, None), initialize = 10) def obj_rule(model): return sum(model.X[i] for i in model.days) model.funcobj = Objective(rule=obj_rule, sense=maximize) def C1A_rule(model,t): return model.Y*model.L <= model.M[t] def C1B_rule(model,t): return model.M[t] <= model.Y*model.U model.C1A = Constraint(model.days, rule=C1A_rule) model.C1B = Constraint(model.days, rule=C1B_rule) def C14_rule(model,i): # 物料平衡约束(b1部门) if i == T[1]: # Pyomo集合为1索引 return (model.X[i] == model.M[i] + model.X0) if i != T[1]: return (model.X[i] == model.M[i] + model.X[i-1]) model.C14 = Constraint(model.days, rule=C14_rule) def C15A_rule(model,t): return model.LL <= model.M[t] / 1.15741e-5 def C15B_rule(model,t): return model.M[t] / 1.15741e-5 <= model.LU model.C15A = Constraint(model.days, rule=C15A_rule) model.C15B = Constraint(model.days, rule=C15B_rule) SolverFactory('glpk', executable='/usr/bin/glpsol').solve(model).write()
解决方法
错误根源是约束C15A和C15B中直接对变量进行了浮点数除法操作,Pyomo在构建约束时会尝试提前计算参数的数值,导致参数未完成初始化时触发报错。解决方式是将除法转换为乘法,避免直接数值运算,让Pyomo正确处理表达式逻辑:
修改
C15A_rule和C15B_rule的约束逻辑:- 原
C15A的model.LL <= model.M[t] / 1.15741e-5等价于model.LL * 1.15741e-5 <= model.M[t] - 原
C15B的model.M[t] / 1.15741e-5 <= model.LU等价于model.M[t] <= model.LU * 1.15741e-5
- 原
修改后的约束代码:
def C15A_rule(model,t): return model.LL * 1.15741e-5 <= model.M[t] def C15B_rule(model,t): return model.M[t] <= model.LU * 1.15741e-5
验证效果
替换修改后的约束代码后,模型可以正常完成构建与求解,不会再触发该数值计算错误。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

