我喜欢在y模型中约束变量值u <1。将ub = 1添加到变量定义u = m.Var(name ='u',value = 0,lb = -2,ub = 1),但是导致“找不到解决方案”(退出:收敛到本地不可行。问题可能不可行。我想我必须重新制定问题以避免这种情况,但是我无法找到应该如何完成此操作的示例。约束变量值时,如何编写适当的模型以避免不可行的解决方案?
我不得不通过添加像m.Equation(u <1)这样的方程来重新制定问题,
import numpy as np
from gekko import GEKKO
import matplotlib.pyplot as pyplt
m = GEKKO(remote=False)
t = np.linspace(0, 1000, 101) # time
d = np.ones(t.shape)
d[0:10] = 0
y_delay=0
# Add data to model
m.time = t
K = m.Const(0.01, name='K')
r = m.Const(name='r', value=0) # Reference
d = m.Param(name='d', value=d) # Disturbance
y = m.Var(name='y', value=0, lb=-2, ub=2) # State variable
u = m.Var(name='u', value=0, lb=-2, ub=1) # Output
e = m.Var(name='e', value=0)
Tc = m.FV(name='Tc', value=1200, lb=60, ub=1200) # time constant
# Update variable status
Tc.STATUS = 1 # Optimizer can adjust value
Kp = m.Intermediate(1 / K * 1 / Tc, name='Kp')
Ti = m.Intermediate(4 * Tc, name='Ti')
# Model equations
m.Equations([y.dt() == K * (u-d),
e == r-y,
u.dt() == Kp*e.dt()+Kp/Ti*e])
# Model constraints
m.Equation(y < 0.5)
m.Equation(y > -0.5)
# Model objective
m.Obj(-Tc)
# options
m.options.IMODE = 6 # Problem type: 6 = Dynamic optimization
# solve
m.solve(disp=True, debug=True)
print('Tc: %6.2f [s]' % (Tc.value[-1], ))
fig1, (ax1, ax2, ax3) = pyplt.subplots(3, sharex='all')
ax1.plot(t, y.value)
ax1.set_ylabel("y", fontsize=8), ax1.grid(True, which='both')
ax2.plot(t, e.value)
ax2.set_ylabel("e", fontsize=8), ax2.grid(True, which='both')
ax3.plot(t, u.value)
ax3.plot(t, d.value)
ax3.set_ylabel("u and d", fontsize=8), ax3.grid(True, which='both')
pyplt.show()
退出:收敛到局部不可行点。问题可能不可行。
发生错误。 错误代码为2
如果将u的上限更改为2,则可以按预期解决优化问题。
答案 0 :(得分:2)
y
指定为受控变量来使用软约束,并使用SPHI
和SPLO
设置上限和下限设定点范围。
y = m.CV(name='y', value=0) # Controlled variable
y.STATUS = 1
y.TR_INIT = 0
y.SPHI = 0.5
y.SPLO = -0.5
我还从lb
和ub
中删除了y
和u
,以免给它们带来可能导致不可行的困难。您还有一个目标,就是用Tc
使m.Obj(-Tc)
的值最大化。当求解器能够调整值时,它将达到最大限制:1200
。从图中可以看到,y
的值超出了设定点范围。控制器可能无法将其保持在该范围内。对约束进行软约束(基于目标)的方法会惩罚偏差,但不会导致不可行的解决方案。如果您需要加大对违反SPHI
或SPLO
的惩罚,则可以调整参数WSPHI
和WSPLO
。
似乎您具有一阶动态模型,并且您正在尝试优化PID参数。如果您需要对控制器输出(执行器)的饱和度建模,则可以使用if3
,max3
,min3
或相应的if2
,max2
,{{1} }函数可能很有用。动态优化课程中有关于min2
objectives和tuning的更多信息。
这是解决您问题的可行方案:
CV
答案 1 :(得分:0)
感谢您对我的问题的广泛而有用的回答。对此,我真的非常感激。 正如您正确观察到的那样,我正在尝试针对我的简单控制问题优化调整参数。我已经用软约束执行了您的代码,它肯定解决了可行性问题。我还添加了WSPHI / LO参数并将其值设置为较高,以在约束范围内找到解决方案。尽管如此,我还是希望有一个模型,其中控制输出(“ u”)的边界为[0,1]。根据您的回答,我可能必须在模型中添加“ if”或“ max / min”语句,以避免在“ u”达到界限时出现一组不可行的方程。例如“如果u <0,则u.dt()= 0否则u.dt()= Kp * e…”。或者可以添加一个变量(类型松弛变量)以确保方程组的可行性吗?我还将研究动态优化课程链接中的材料,以更好地了解动态建模。再次感谢您在这个问题上为我提供了正确的指导。