Optimization 有界变量的GEKKO优化是如何工作的?

Optimization 有界变量的GEKKO优化是如何工作的?,optimization,ode,bounds,gekko,Optimization,Ode,Bounds,Gekko,我用GEKKO来估计一个微分方程的参数,其中一个变量的界在0和1之间。然而,当我求解ODE时,我得到的值超出了这个变量的边界,所以我想知道是否有人知道GEKKO是如何找到解决方案的,因为这可能会帮助我解决这个问题。 下面是我用来拟合数据的代码。这给了我一个解x和u,其中x在0和1之间 但是,之后,我尝试使用scipy.integrate.solve_ivp来求解ODE,使用我得到的初始值u,而我得到的解不在这个界限之间。由于它应该是独特的,我想知道GEKKO遵循什么过程来找到解决方案(它是否将值

我用GEKKO来估计一个微分方程的参数,其中一个变量的界在0和1之间。然而,当我求解ODE时,我得到的值超出了这个变量的边界,所以我想知道是否有人知道GEKKO是如何找到解决方案的,因为这可能会帮助我解决这个问题。 下面是我用来拟合数据的代码。这给了我一个解x和u,其中x在0和1之间

但是,之后,我尝试使用scipy.integrate.solve_ivp来求解ODE,使用我得到的初始值u,而我得到的解不在这个界限之间。由于它应该是独特的,我想知道GEKKO遵循什么过程来找到解决方案(它是否将值投影到边界,或者它如何处理此问题?)任何评论都非常感谢

这是一个MVCE。如果你运行它,你可以看到,在GEKKO中,我得到了边界之间的一个解,然后,当我用solve_ivp解ODE时,我没有得到相同的解。你能解释一下为什么会发生这种情况,我该如何处理?我想用solve_ivp来预测下一个值

来自scipy.integrate import solve\u ivp的

从gekko进口gekko
将matplotlib.pyplot作为plt导入
时间=[0.0,0.11784511785,0.18855218855218855,\
0.2356902356902357]
m=GEKKO(远程=False)
m、 时间=[0.0,0.11784511785,0.18855218855218855,\
0.2356902356902357]
x_数据=[0.000377763048128617,0.002024573836061331\
0.0008954383363035536, 0.005331749410182463]
x=m.CV(值=x_数据,lb=0);x、 FSTATUS=1#适合测量
x、 SPLO=0
西格玛=m.FV(值=0.5,磅=0,磅=1);西格玛状态=1
d=m.Param(0.05)
k=m.Param(0.001)
b=m.Param(0.5)
r=m.FV(值=0.5,磅=0);r、 状态=1
m_param=m.param(1)
u=m.Var(值=0.1,磅=0,磅=1)
m、 免费(u)
a=m.Param(0.999)
Kmax=m.Param(100000)
m、 方程([x.dt()==x*(r*(1-a*u**2)*(1-x/(Kmax*(1-a*u**2)))-\
m_参数/(k+b*u)-d),u.dt()\
西格玛*(-2*a*(b**2)*r*(u**3)+4*a*b*k*r*(u**2)\
+2*a*(k**2)*r*u-b*m_参数/((b*u+k)**2)))
m、 options.IMODE=5#动态估计
m、 options.NODES=5个#配置节点
m、 options.EV_TYPE=1线性误差(2表示平方)
m、 求解(disp=False,debug=False)#显示解算器输出
def型号案例3(t、z、r、k、b、Kmax、sigma):
m=1
a=0.999
x、 u=z
dxdt=x*(r*(1-a*u**2)*(1-x/(Kmax*(1-a*u**2))-m/(k+b*u)-0.05)
dudt=sigma*(-2*a*(b**2)*r*(u**3)+4*a*b*k*r*(u**2)\
+2*a*(k**2)*r*u-b*m/((b*u+k)**2))
返回[dxdt,dudt]
sol=解决ivp(fun=模型案例3,t_span=[0.0,0.2356902356902357]\
y0=[0.000377763048128617,u.值[0]]\
t_eval=[0.0,0.11784551785,0.18855218855218855\
0.2356902356902357],  \
args=(r.value[0],0.001,0.51000000,sigma.value[0]))
图(ax1,ax2)=plt.子批次(1,2,figsize=(10,3),受约束的布局=真)
ax1.设置标题('x')
ax1.绘图(时间,x.值,时间,sol['y'][0])
ax2.设置标题(“u”)
ax2.绘图(时间、u.value、时间、sol['y'][1])
plt.show()

这不是Gekko版本的问题,因为我有Gekko 0.2.8,所以我想知道它是否与变量的初始化有关。我运行了我在spyder上发布的示例(我使用的是google colab),得到了正确的解决方案,但当我运行其余的案例时,我又得到了u的负值(使用solve_ivp求解),这非常奇怪。

当变量通过设置
lb
(下限)和
ub
(上限)创建时,可以为它添加一个绑定

z=m.Var(lb=0,ub=10)
创建变量后,使用
.lower
.upper
调整边界

z.LOWER=1
z、 上限=9
下面是一个示例问题,显示了在
x
被限制为大于0.5的情况下使用边界的情况

从gekko导入gekko
t_数据=[0,0.1,0.2,0.4,0.8,1]
x_数据=[2.0,1.6,1.2,0.7,0.3,0.15]
m=GEKKO(远程=False)
m、 时间=t_数据
x=m.CV(值=x_数据,lb=0.5,ub=3);x、 FSTATUS=1#适合测量
k=m.FV();k、 状态=1#可调参数
m、 方程(x.dt()=-k*x)#微分方程
m、 options.IMODE=5#动态估计
m、 options.NODES=5个#配置节点
m、 求解(disp=False)#显示解算器输出
k=k.值[0];印刷品(k)
结果图显示,边界已被强制执行,但由于下限约束(
x>=0.5
),模型预测不适合数据

将numpy导入为np
导入matplotlib.pyplot作为plt#绘图解决方案
plt.绘图(m.时间,x.值,'bo'\
label='Predicted(k='+str(np.round(k,2))+'))
plt.绘图(m.时间,x_数据,'rx',标签='Measured')
#绘图精确解
t=np.linspace(0,1);xe=2*np.exp(-k*t)
plt.plot(t,xe,'k:',label='精确解〕
plt.legend()
plt.xlabel('Time'),plt.ylabel('Value'))
plt.show()
在没有限制性下限的情况下,解算器将优化以最佳拟合点

x=m.CV(值=x_数据,lb=0.0,ub=3)

问题编辑回复1

变量(如
u
)超出边界的唯一方式是解算器未报告成功的解决方案。要报告成功的解决方案,解算器必须满足最优性要求。我建议您通过检查
m.solve()
命令后的
m.options.APPSTATUS==1来检查它是否满足所有等式。如果您可以包含一个具有示例数据的MVCE(),以便脚本可以运行,那么我们可以帮助您检查它

对问题编辑的回答2

感谢您提供了一个最小的可复制示例。下面是我使用Gekko 0.2.8得到的结果。如果您使用的是早期版本,我建议您使用
pip install gekko--upgrade进行升级<
EXIT: Optimal Solution Found.

 The solution was found.

 The final value of the objective function is  0.03164650667928192
 
 ---------------------------------------------------
 Solver         :  IPOPT (v3.12)
 Solution time  :  0.23339999999999997 sec
 Objective      :  0.0316473666078486
 Successful solution
 ---------------------------------------------------