Pyomo 动态规划与离散输入集的目标函数
我刚开始学习Python和Pyomo,下面这段代码是用来根据一个简单的微分方程来计算电容器的大小。这里有一个离散数组,经过插值处理后用在问题的公式中。为了验证我的结果,我使用了这一行代码,但它报错了。
Pref = [pyo.value(m.intPload[i]) for i in m.t]
错误信息: ValueError: 评估参数值时出错 (intPload[0.03569]):当前参数值设置为无效值。这通常是因为标量参数或可变索引参数没有初始值或默认值。
**完整代码:
import numpy as np
from scipy import integrate
import math
import matplotlib.pyplot as plt
import pyomo.environ as pyo
from pyomo.dae import ContinuousSet, DerivativeVar
model = m = pyo.ConcreteModel()
# power and time data
t1 = np.array([0, 1, 2, 3, 4, 5]) #s
P1 = np.array([0, 10, 20, 30, 40, 0]) # W
# resample the data
dt = 1 # delta time, resampled every one second
tFinal = math.floor(t1[t1.size-1])
numSims = math.ceil(tFinal/dt)
tsecs = np.linspace(0, tFinal, numSims)
Pload = np.interp(tsecs, t1, P1)
# Capacitor rating
Cc = 1
Rsc = 2.4e-3 # capacitor internal resistance
VcMax = 3 # maximum capacitor cell voltage
IcMax = 50
# Pyomo problem formulation
m.t = ContinuousSet(initialize=tsecs)
m.Vc = pyo.Var(m.t, bounds =(0.5*VcMax, VcMax))
m.VcT = pyo.Var(m.t, bounds =(0.5*VcMax, VcMax))
m.Ic = pyo.Var(m.t, bounds=(-IcMax, IcMax))
m.N_sc = pyo.Var(bounds=(0, 100))
m.N_pc = pyo.Var(bounds=(0, 100))
m.dVcdt = DerivativeVar(m.Vc, wrt=m.t)
m.intPload = pyo.Param(m.t, mutable=True)
timepoints = list(m.t)
Pload_Int = np.interp(timepoints, t1, P1)
for i,t in enumerate(timepoints):
m.intPload[t] = Pload_Int[i]
m.obj = pyo.Objective(expr=(m.N_sc+m.N_pc)**2 + sum( (m.VcT[i]*m.N_sc*m.Ic[i]*m.N_pc - m.intPload[i])**2 for i in m.t), sense=pyo.minimize)
def _Vcdot(m, t):
return m.dVcdt[t] == -m.Ic[t]/Cc
m.Vcdot = pyo.Constraint(m.t,rule=_Vcdot)
def _VcTR(m, t):
return m.VcT[t] == m.Vc[t] -m.Ic[t]*Rsc
m.VcTR = pyo.Constraint(m.t,rule=_VcTR)
def _init_conditions(m):
yield m.Vc[0] == VcMax
#yield m.VcT[0] == VcMax
m.init_conditions = pyo.ConstraintList(rule=_init_conditions)
# Discretize model using Orthogonal Collocation
discretizer = pyo.TransformationFactory('dae.collocation')
discretizer.apply_to(model, nfe=8, ncp=5)
solver=pyo.SolverFactory('ipopt')
results = solver.solve(model,tee=True)
x1 = [pyo.value(m.Ic[i]) for i in m.t]
Pl = [pyo.value(m.Ic[i]*m.VcT[i]*m.N_sc*m.N_pc) for i in m.t]
Pref = [pyo.value(m.intPload[i]) for i in m.t]
#Pl2 = [pyo.value(m.intPload[i]) for i in m.t]
diffPl = [pyo.value(m.Ic[i]*m.VcT[i]*m.N_sc*m.N_pc - m.intPload[i]) for i in m.t]
plt.plot(x1)
plt.show( )
错误信息: ValueError: 评估参数值时出错 (intPload[0.03569]):当前参数值设置为无效值。这通常是因为标量参数或可变索引参数没有初始值或默认值。
在使用Pyomo DAE时,如何在某个时间段内给变量分配一个常量值?我想让m.intPload[i]的值呈阶梯状,但用上面的代码却只得到了采样实例。总之,我想把代码执行的设计空间离散化,或者至少让一些变量有一组离散的值。

1 个回答
1
你需要把处理intPload
值的代码放到调用离散化转换之后。离散化转换就是在m.t
中添加时间点,而你的插值代码没有考虑到这一点。