如何修复Python GEKKO最佳控制代码中的“找不到解决方案”错误

时间:2019-07-08 21:13:03

标签: python nonlinear-optimization gekko

我正在尝试在K. Renee Fister和Jennifer Hughes Donnelly于2005年发表的论文“免疫疗法:最优控制理论方法”的图1中重现该结果。为此,我编写了一个数值最优控制求解器使用Python的GEKKO软件包。我使用了与本文相同的初始条件,控制范围,参数值和模型方程式。但是,当我运行代码时,出现以下错误:

Traceback (most recent call last):
  File "xxxxxx", line 45, in <module>
    m.solve(disp=False) #solve
  File "xxxx", line 783, in solve
    raise Exception(response)
Exception:  @error: Solution Not Found

我希望程序的输出能够提供两个数字:一个是ODE动态,另一个是最佳控制解决方案。

我尝试过多种方式更改代码:修改目标功能,时间步数以及更改最佳控制模式,但是,每次都会遇到相同的错误。下面是我正在使用的代码:

from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt

m = GEKKO()
nt = 1010
m.time = np.linspace(0,350,nt)

# Variables
X = m.Var(value=1)
Y = m.Var(value=1)
Z = m.Var(value=1)
OF = m.Var(value=0)
v = m.Var(value=0,lb=0,ub=1) #Control is initially 0 with a lower bound of 0 and an upper bound of 1

p = np.zeros(nt) #mark final time point
p[-1] = 1.0 #all zeros except the end, which is 1
final = m.Param(value=p) #final depends on integration limits

#Parameter Values
c = .000085
mu2 = .03
p1 = .1245
a = 1
r2 = .18
mu3 = 10
p2 = 5
g1 = 20000000 #2e7
g2 = 100000 #1e5
g3 = 1000 #1e3
b = 1*10**(-9)
s2 = 100000000
B = 100000000

# Equations
m.Equation(X.dt() == c*Y-mu2*X+(p1*X*Z)/(g1+Z))
m.Equation(Y.dt() == r2*Y*(1-b*Y)-(a*X*Y)/(g2+Y))
m.Equation(Z.dt() == (p2*X*Y)/(g3+Y)-mu3*Z+v*s2)
m.Equation(OF.dt() == X-Y+Z-B*v)

m.Obj(-OF*final)

m.options.IMODE = 6 #optimal control mode
m.solve(disp=False) #solve

plt.figure(figsize=(4,3)) #plot results
plt.subplot(2,1,1)
plt.plot(m.time,X.value,'k-',label=r'$S$')
plt.plot(m.time,Y.value,'b-',label=r'$R$')
plt.plot(m.time,Z.value,'g-',label=r'$E$')
plt.plot(m.time,OF.value,'r-',label=r'$OF$')
plt.legend()
plt.ylabel('CV')
plt.subplot(2,1,2)
plt.plot(m.time,v.value,'g--',label=r'$v$')
plt.legend()
plt.xlabel('Time')
plt.ylabel('Value')
plt.show()

此代码是通过修改this Youtube video中提供的示例GEKKO代码得出的。解决该问题的任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

当求解器无法找到解决方案并报告“找不到解决方案”时,有一种故障排除方法可以诊断问题。首先要做的是使用m.solve(disp=True)查看求解器输出。求解器可能已经确定了一个不可行的问题,或者达到了最大迭代次数而没有收敛到解决方案。

不可行的问题

如果求解器由于方程不可行而失败,则发现变量和方程的组合不可解。您可以尝试放宽变量界限,或使用运行目录中的infeasibilities.txt文件确定哪个方程式不可行。从infeasibilities.txt时可以用m.open_folder()查看的本地运行目录中检索m=GEKKO(remote=False)文件。

最大迭代限制

如果求解器达到默认的迭代限制(m.options.MAX_ITER=250),则可以尝试增加此限制,也可以尝试以下策略。

  • 通过为APOPT设置m.options.SOLVER=1,为BPOPT设置m.options.SOLVER=2,为IPOPT设置m.options.SOLVER=3m.options.SOLVER=0来尝试所有可用的求解器,以尝试使用其他求解器。
  • 首先,通过解决变量数等于方程数的平方问题来找到可行的解决方案。 Gekko提供了两个选项来帮助解决此问题,其中包括m.options.COLDSTART=1(为所有FV和MV设置STATUS = 0)或m.options.COLDSTART=2(设置STATUS = 0并执行块对角三角形分解以查找可能的不可行方程)。 / li>
  • 一旦找到可行的解决方案,请尝试以该解决方案作为初始猜测进行优化。

我将使用您在YouTube视频中引用的Luus example optimal control problem来演示此策略。在没有任何这些策略的情况下,此问题可以成功解决,但我将对其进行修改以显示如何使用这些方法。

Luus Optimal Control

import numpy as np
import matplotlib.pyplot as plt
from gekko import GEKKO
m = GEKKO(remote=False)
nt = 101; m.time = np.linspace(0,2,nt)
x = m.Var(value=1)
u = m.MV(value=0,lb=-1,ub=1); u.STATUS=1
p = np.zeros(nt); p[-1] = 1.0; final = m.Param(value=p)
m.Equation(x.dt()==u)
m.Minimize(m.integral(0.5*x**2)*final)
m.options.IMODE = 6; m.solve()

plt.figure(1)
plt.plot(m.time,x.value,'k-',lw=2,label='x')
plt.plot(m.time,u.value,'r--',lw=2,label='u')
plt.legend(); plt.xlabel('Time'); plt.ylabel('Value')
plt.show()

Luus Optimal Control

假设求解器未成功。您可以通过将m.solve()替换为以下内容进行初始化:

# initialize to get a feasible solution
m.options.COLDSTART=2
m.solve()

# optimize, preserving the initial conditions (TIME_SHIFT=0)
m.options.TIME_SHIFT=0
m.options.COLDSTART=0
m.solve()

初始化策略在文章中也有更详细的描述:

  • Safdarnejad,S.M.,Hedengren,J.D.,Lewis,N.R.,Haseltine,E.,《动态系统优化的初始化策略》,《计算机和化学工程》,2015年,第1期。 78,第39-50页,DOI:10.1016 / j.compchemeng.2015.04.016。 article link