繁体   English   中英

Python Gekko Optimization中的横向条件(伴随变量Lamda)如何处理?

[英]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。

这里有一些建议:

  1. La1 - La5 需要是变量而不是固定参数。
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)
  1. 常量 a0 - e4 需要是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
  1. 仅最小化积分的最后一个值。 通过添加括号来解决此问题。
m.Minimize(tf*(M+0.5*m.integral(u**2)))
  1. 切换到IMODE=4IMODE=7 (更快)进行仿真。 运行IMODE=7时关闭显示,以免浪费时间进行大打印输出。
m.options.IMODE=7
m.solve(disp=False)
  1. 如果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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM