[英]How to enforce binary (or integer) variables in Python Gekko optimization?
[英]How to deal with the transversality condition (adjoint variables Lamda) in Python Gekko Optimization?
我有一个最优控制问题,我试图在 Python 中使用 GEKKO 进行模拟
m = GEKKO()
nt = 501
m.time = np.linspace(0,500,nt)
# Variables
u = m.MV(value=0,lb=0,ub=1)
u.STATUS = 1
H = m.Var(value=0.1,lb=0)
C = m.Var(value=0.1,lb=0)
M = m.Var(value=0.8,lb=0)
D = m.Var(value=0.1,lb=0)
I = m.Var(value=0.1,lb=0)
a0 = m.Var(value=10**-4)
b0 = m.Var(value=10**-1)
c0 = m.Var(value=0.005)
f0 = m.Var(value=1)
a1 = m.Var(value=10**-4)
b1 = m.Var(value=10**-2)
c1 = m.Var(value=0.005)
f1 = m.Var(value=1)
b2 = m.Var(value=0.02)
d2 = m.Var(value=0.1)
f2 = m.Var(value=1)
d3 = m.Var(value=0.1)
b4 = m.Var(value=10**-2)
c4 = m.Var(value=10**-2)
e4 = m.Var(value=10**-7)
p = np.zeros(nt)
p[-1] = 1
tf = m.Param(value=p)
La1 = m.Param()
La2 = m.Param()
La3 = m.Param()
La4 = m.Param()
La5 = m.Param()
# Control Variables Equations
m.Equation(H.dt()==a0-c0*H+b0*D*H*(1-H/f0))
m.Equation(C.dt()==a1-c1*C+b1*I*(M+D)*C*(1-C/f1))
m.Equation(M.dt()==b2*M*(1-M/f2)-d2*M*C)
m.Equation(D.dt()==-d3*D*C+u)
m.Equation(I.dt()==b4*D*H-e4*I*C+c4*I)
# Adjoint Variables Equations
m.Equation(La1.dt()==(-c0+b0*D-2*D*b0*H/f0)*La1+b4*D*La5)
m.Equation(La2.dt()==(-c1+b1*I*(M+D)*(1-2*C/f1))*La2-d2*M*La3-d3*D*La4-e4*I*La5)
m.Equation(La3.dt()==-1+b1*I*C*(1-C/f1)*La2+(b2*(1-2*M/f1)-d2*C)*La3)
m.Equation(La4.dt()==b1*H*(1-H/f0)*La1+b1*I*C*(1-C/f1)*La2-d3*C*La4+b4*H*La5)
m.Equation(La5.dt()==b1*(M+D)*C*(1-C/f1)*La2+(-e4*C-c4)*La5)
m.Equation(La1*tf==0)
m.Equation(La2*tf==0)
m.Equation(La3*tf==1)
m.Equation(La4*tf==0)
m.Equation(La5*tf==0)
# Objective Function
m.Obj(tf*M+0.5*m.integral(u**2))
m.options.IMODE=6
m.solve()
我正在研究的问题是一个通过树突状细胞注射实现的免疫治疗项目
我真的不知道如何推导出伴随变量方程和问题的最终时间条件。 请随时给我任何建议,Lz。
这里有一些建议:
La1 = m.Var()
La2 = m.Var()
La3 = m.Var()
La4 = m.Var()
La5 = m.Var()
您也可以使用m.Array()
在一行中定义它们。
La1,La2,La3,La4,La5 = m.Array(m.Var,5)
m.Param()
、 m.Const()
或只是 python 浮点数。 如果它们是需要计算的参数,请将它们设置为a0=m.FV(lb=0,ub=1)
类型,具有上下界和a0.STATUS=1
以使其成为求解器的自由度。a0 = 1e-4
b0 = 0.1
c0 = 0.005
f0 = 1
a1 = 1e-4
b1 = 1e-2
c1 = 0.005
f1 = 1
b2 = 0.02
d2 = 0.1
f2 = 1
d3 = 0.1
b4 = 1e-2
c4 = 1e-2
e4 = 1e-7
m.Minimize(tf*(M+0.5*m.integral(u**2)))
IMODE=4
或IMODE=7
(更快)进行仿真。 运行IMODE=7
时关闭显示,以免浪费时间进行大打印输出。m.options.IMODE=7
m.solve(disp=False)
tf=0
,则诸如m.Equation(La3*tf==1)
之类的等式是不可行的,因为它给出了等式0=1
。 相反,使用m.Equation(tf*(La3-1)==0)
以便方程仅在最后有效。 在添加这些方程之前,需要添加额外的自由度。 编写方程的另一种方法是使用客观的 function 形式,例如m.Minimize(tf*(La3-1)**2)
。 这对于求解器来说通常更容易找到解决方案,并且如果求解器无法达到最终值,则不会返回错误。from gekko import GEKKO
import numpy as np
m = GEKKO()
nt = 501
m.time = np.linspace(0,500,nt)
# Variables
u = m.MV(value=0,lb=0,ub=1)
u.STATUS = 1
H = m.Var(value=0.1,lb=0)
C = m.Var(value=0.1,lb=0)
M = m.Var(value=0.8,lb=0)
D = m.Var(value=0.1,lb=0)
I = m.Var(value=0.1,lb=0)
a0 = 1e-4
b0 = 0.1
c0 = 0.005
f0 = 1
a1 = 1e-4
b1 = 1e-2
c1 = 0.005
f1 = 1
b2 = 0.02
d2 = 0.1
f2 = 1
d3 = 0.1
b4 = 1e-2
c4 = 1e-2
e4 = 1e-7
p = np.zeros(nt)
p[-1] = 1
tf = m.Param(value=p)
La1,La2,La3,La4,La5 = m.Array(m.Var,5)
# Control Variables Equations
m.Equation(H.dt()==a0-c0*H+b0*D*H*(1-H/f0))
m.Equation(C.dt()==a1-c1*C+b1*I*(M+D)*C*(1-C/f1))
m.Equation(M.dt()==b2*M*(1-M/f2)-d2*M*C)
m.Equation(D.dt()==-d3*D*C+u)
m.Equation(I.dt()==b4*D*H-e4*I*C+c4*I)
# Adjoint Variables Equations
m.Equation(La1.dt()==(-c0+b0*D-2*D*b0*H/f0)*La1+b4*D*La5)
m.Equation(La2.dt()==(-c1+b1*I*(M+D)*(1-2*C/f1))*La2-d2*M*La3-d3*D*La4-e4*I*La5)
m.Equation(La3.dt()==-1+b1*I*C*(1-C/f1)*La2+(b2*(1-2*M/f1)-d2*C)*La3)
m.Equation(La4.dt()==b1*H*(1-H/f0)*La1+b1*I*C*(1-C/f1)*La2-d3*C*La4+b4*H*La5)
m.Equation(La5.dt()==b1*(M+D)*C*(1-C/f1)*La2+(-e4*C-c4)*La5)
#m.Equation(La1*tf==0)
#m.Equation(La2*tf==0)
#m.Equation(La3*tf==1)
#m.Equation(La4*tf==0)
#m.Equation(La5*tf==0)
# Objective Function
m.Minimize(tf*(M+0.5*m.integral(u**2)))
m.options.IMODE=7
m.solve(disp=False)
import matplotlib.pyplot as plt
plt.figure(figsize=(7,4))
plt.plot(m.time,H,label='H')
plt.plot(m.time,C,label='C')
plt.plot(m.time,M,label='M')
plt.plot(m.time,D,label='D')
plt.plot(m.time,I,label='I')
plt.legend()
plt.savefig('result.png',dpi=300)
plt.show()
不要忘记包含 [gekko] 标签,以便在提出新问题时更早地引起注意。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.