[英]Gekko: Problem with the obtained solution
我正在嘗試解決 GEKKO 中的以下最優控制問題:
我先驗地知道c
的路徑是:
其中參數值為:r = 0.33,i = 0.5,K(0) = 10 和 T = 10。
我在 Python 中編寫了以下代碼:
import numpy as np
import matplotlib.pyplot as plt
from gekko import GEKKO
m = GEKKO(remote=True)
nt = 101; m.time = np.linspace(0,10,nt)
r = 0.33
i = 0.5
# Variables
c = m.Var()
k = m.Var(value=10)
objective = m.Var()
rate = [-r*t/10 for t in range(0, 101)]
factor = m.exp(rate)
p = np.zeros(nt)
p[-1] = 1.0
final = m.Param(value=p)
disc = m.Param(value=factor)
# Equations
m.Equation(k.dt() == i*k - c)
m.Equation(objective.dt() == disc*m.log(c))
# Objective Function
m.Maximize(final*objective)
m.options.IMODE = 6
m.solve()
plt.figure(1)
plt.plot(m.time,c.value,'k:',LineWidth=2,label=r'$C$')
plt.plot(m.time,k.value,'b-',LineWidth=2,label=r'$K$')
plt.legend(loc='best')
plt.xlabel('Time')
plt.ylabel('Value')
plt.show()
這顯然是不正確的,因為c
應該隨着時間的推移而增加,而不僅僅是目測事先給出的解決方案。
我不確定我錯在哪里。
當前編寫的最優控制問題是無界的。 c
的值將 go 到無窮大以最大化 function。 我在c
上設置了100
的上限,求解器達到了該上限。 我重新制定了 model 以反映當前的問題陳述。 這里有一些建議:
m.integral()
function 使 model 更具可讀性。c
初始化為0
以外的值(默認值)。 您可能還希望使用c>0.01
設置下限,以便在求解器嘗試值<0
時m.log(c)
不是未定義的。factor = m.exp(rate)
。 請改用factor = np.exp(rate)
,除非它位於可以計算的 Gekko 方程中。m.options.NODES=3
和c=m.MV()
和c.STATUS=1
來提高求解精度。 默認值為m.options.NODES=2
,但並不准確。m.free_initial(c)
釋放初始條件來計算c
的初始值。import numpy as np
import matplotlib.pyplot as plt
from gekko import GEKKO
m = GEKKO(remote=True)
nt = 101; m.time = np.linspace(0,10,nt)
r = 0.33
i = 0.5
# Variables
c = m.MV(4,lb=0.01,ub=100); c.STATUS=1
#m.free_initial(c)
k = m.Var(value=10)
objective = m.Var(0)
t = m.Param(m.time)
m.Equation(objective==m.exp(-r*t)*m.log(c))
# just to include on the plot
iobj = m.Intermediate(m.integral(objective))
p = np.zeros(nt)
p[-1] = 1.0
final = m.Param(value=p)
# Equations
m.Equation(k.dt() == i*k - c)
# Objective Function
m.Maximize(final*m.integral(objective))
m.options.IMODE = 6
m.solve()
plt.figure(1)
plt.subplot(3,1,1)
plt.plot(m.time,c.value,'k:',linewidth=2,label=r'$C_{gekko}$')
C_sol = r*10*np.exp((i-r)*m.time)/(1-np.exp(-r*10))
plt.plot(m.time,C_sol,'r--',linewidth=2,label=r'$C_{exact}$')
plt.ylabel('Value'); plt.legend(loc='best')
plt.subplot(3,1,2)
plt.plot(m.time,k.value,'b-',linewidth=2,label=r'$K$')
plt.legend(loc='best')
plt.subplot(3,1,3)
plt.plot(m.time,objective.value,'g:',linewidth=2,label=r'$obj$')
plt.plot(m.time,iobj.value,'k',linewidth=2,label=r'$\int obj$')
plt.legend(loc='best')
plt.xlabel('Time')
plt.show()
是否有其他信息表明此問題缺失?
編輯:添加了額外的約束k>0
。
按照評論中的建議添加了額外的約束。 由於最后的c
值似乎不會影響解決方案,因此最終與精確解決方案存在細微差別。
import numpy as np
import matplotlib.pyplot as plt
from gekko import GEKKO
m = GEKKO(remote=True)
nt = 101; m.time = np.linspace(0,10,nt)
r = 0.33
i = 0.5
# Variables
c = m.MV(4,lb=0.001,ub=100); c.STATUS=1; c.DCOST=1e-6
m.free_initial(c)
k = m.Var(value=10,lb=0)
objective = m.Var(0)
t = m.Param(m.time)
m.Equation(objective==m.exp(-r*t)*m.log(c))
# just to include on the plot
iobj = m.Intermediate(m.integral(objective))
p = np.zeros(nt)
p[-1] = 1.0
final = m.Param(value=p)
# Equations
m.Equation(k.dt() == i*k - c)
# Objective Function
m.Maximize(final*m.integral(objective))
m.options.IMODE = 6
m.options.NODES = 3
m.solve()
plt.figure(1)
plt.subplot(3,1,1)
plt.plot(m.time,c.value,'k:',linewidth=2,label=r'$C_{gekko}$')
C_sol = r*10*np.exp((i-r)*m.time)/(1-np.exp(-r*10))
plt.plot(m.time,C_sol,'r--',linewidth=2,label=r'$C_{exact}$')
plt.ylabel('Value'); plt.legend(loc='best')
plt.subplot(3,1,2)
plt.plot(m.time,k.value,'b-',linewidth=2,label=r'$K$')
plt.legend(loc='best')
plt.subplot(3,1,3)
plt.plot(m.time,objective.value,'g:',linewidth=2,label=r'$obj$')
plt.plot(m.time,iobj.value,'k',linewidth=2,label=r'$\int obj$')
plt.legend(loc='best')
plt.xlabel('Time')
plt.show()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.