如何在GEKKO中约束模型变量

时间:2019-09-13 13:07:16

标签: gekko

我喜欢在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,则可以按预期解决优化问题。

2 个答案:

答案 0 :(得分:2)

如您所见,对变量的硬约束可能导致不可行的解决方案。我建议您通过将变量y指定为受控变量来使用软约束,并使用SPHISPLO设置上限和下限设定点范围。

y = m.CV(name='y', value=0)  # Controlled variable
y.STATUS = 1
y.TR_INIT = 0
y.SPHI = 0.5
y.SPLO = -0.5

我还从lbub中删除了yu,以免给它们带来可能导致不可行的困难。您还有一个目标,就是用Tc使m.Obj(-Tc)的值最大化。当求解器能够调整值时,它将达到最大限制:1200。从图中可以看到,y的值超出了设定点范围。控制器可能无法将其保持在该范围内。对约束进行软约束(基于目标)的方法会惩罚偏差,但不会导致不可行的解决方案。如果您需要加大对违反SPHISPLO的惩罚,则可以调整参数WSPHIWSPLO

test results

似乎您具有一阶动态模型,并且您正在尝试优化PID参数。如果您需要对控制器输出(执行器)的饱和度建模,则可以使用if3max3min3或相应的if2max2,{{1} }函数可能很有用。动态优化课程中有关于min2 objectivestuning的更多信息。

CV Tuning Demonstration

这是解决您问题的可行方案:

CV

答案 1 :(得分:0)

感谢您对我的问题的广泛而有用的回答。对此,我真的非常感激。 正如您正确观察到的那样,我正在尝试针对我的简单控制问题优化调整参数。我已经用软约束执行了您的代码,它肯定解决了可行性问题。我还添加了WSPHI / LO参数并将其值设置为较高,以在约束范围内找到解决方案。尽管如此,我还是希望有一个模型,其中控制输出(“ u”)的边界为[0,1]。根据您的回答,我可能必须在模型中添加“ if”或“ max / min”语句,以避免在“ u”达到界限时出现一组不可行的方程。例如“如果u <0,则u.dt()= 0否则u.dt()= Kp * e…”。或者可以添加一个变量(类型松弛变量)以确保方程组的可行性吗?我还将研究动态优化课程链接中的材料,以更好地了解动态建模。再次感谢您在这个问题上为我提供了正确的指导。