我有一个Pyomo模型,其格式为:
from pyomo.environ import *
from pyomo.dae import *
m = AbstractModel()
m.t = ContinuousSet(bounds=(0,120))
m.T = Param(default=120)
m.S = Var(m.t, bounds=(0,None))
m.Sdot = DerivativeVar(m.S)
m.obj = Objective(expr=m.S[120],sense=maximize)
请注意,目标m.obj
依赖于参数m.T
。试图运行它会产生错误:
TypeError: unhashable type: 'SimpleParam'
使用expr=m.S[120]
之类的值会出现错误:
ValueError: Error retrieving component S[120]: The component has not been constructed.
在这两种情况下,我的目标都是相同的:在地平线上优化S
的最大可能值。
如何创建表达此内容的抽象模型?
答案 0 :(得分:1)
你正在处理两个有些不同的问题:
TypeError: unhashable type: 'SimpleParam'
由于Pyomo 4.3中的一个错误,您无法直接将简单Param
s用作其他组件的索引。也就是说,针对此特定问题的修复程序无法修复您的示例模型。
修复Objective
声明的技巧是将Objective
表达式封装在规则中:
def obj_rule(m):
return m.S[120]
# or better yet:
# return m.S[m.T]
# or
# return m.S[m.t.last()]
m.obj = Objective(rule=obj_rule,sense=maximize)
问题在于,在编写Abstract模型时,每个组件只是声明,而不是已定义。因此,Var S
被声明存在,但尚未定义(它是一个没有成员的空壳)。这会导致问题,因为Python(而不是Pyomo)会在调用m.S[120]
构造函数之前尝试将Objective
解析为特定变量。在Abstract模型中使用规则(函数)允许您推迟表达式的解析,直到Pyomo实际构建模型实例。 Pyomo按照您在Abstract模型上声明它们的顺序构造实例组件,因此当它触发obj_rule
时,前面的组件(S
,T
和{{1} }}都是构造的,t
在S
的已知点(在这种情况下,边界)有有效成员。