我正在尝试使用 Gekko 套件解决具有各种初始条件的多个优化问题。分配初始条件,使用 Gekko 运行优化,并收集每个解决方案。当我尝试更改参数、目标函数或初始条件时,Gekko 经常给我“找不到解决方案错误:第 2130 行,解决引发异常(apm_error)”。我在下面展示了一些案例,希望得到建议来解决我遇到的这个问题。我之前发布过类似的问题,但我希望这个问题更简洁明了。谢谢。
案例 1. 运行良好,没有错误。
from gekko import GEKKO
import pandas as pd
import numpy as np
dat = {'A0': [23221, 2198, 4296, 104906, 691], 'h': [0.04, 0.25, 0.07, 0, 12.58],'emax': [23221, 2198, 4296, 104906, 691] }
dftemp = pd.DataFrame(data=dat)
na=len(dftemp)
# time points
n=51
year=50
# constants
Pa0 = 3.061
Pe0 = 10.603
C0 = 100
r = 0.05
k=50
shift=10000000 # to make positive inside log function
ll=0.15
for i in range(0,na):
# create GEKKO model
m = GEKKO(remote=False)
m.time = np.linspace(0,year,n)
t=m.time
A0=dftemp.loc[i][0]
h=dftemp.loc[i][1]
emax=dftemp.loc[i][2]
A = m.SV(value=A0, lb=0, ub=A0)
E = m.SV(value=0, lb=0, ub=A0)
u = m.MV(value=0, lb=-emax, ub=emax)
u.STATUS = 1
t = m.Param(value=m.time)
C = m.Var(value=C0)
d = m.Var(value=1)
l = m.Param(value=ll)
# Equation
m.Equation(A.dt()==-u)
m.Equation(E.dt()==u)
m.Equation(C.dt()==-C/k)
m.Equation(d==m.exp(-t*r))
# Objective (Utility)
J = m.Var(value=0)
# Final objective
Jf = m.FV()
Jf.STATUS = 1
m.Connection(Jf,J,pos2='end')
m.Equation(J.dt() == m.log((A+E*(1-l))*h*Pa0-C*u+E*Pe0+shift)*d)
# maximize U
m.Maximize(Jf)
# options
m.options.IMODE = 6 # optimal control
m.options.NODES = 3 # collocation nodes
m.options.SOLVER = 3 # solver (IPOPT)
# solve optimization problem
m.solve()
# print profit
print('Optimal Profit: ' + str(Jf.value[0]))
案例2.将“时间点”的个数从n=51
改为n=501
出现错误
from gekko import GEKKO
import pandas as pd
import numpy as np
dat = {'A0': [23221, 2198, 4296, 104906, 691], 'h': [0.04, 0.25, 0.07, 0, 12.58],'emax': [23221, 2198, 4296, 104906, 691] }
dftemp = pd.DataFrame(data=dat)
na=len(dftemp)
# time points
n=501
year=50
# constants
Pa0 = 3.061
Pe0 = 10.603
C0 = 100
r = 0.05
k=50
shift=10000000 # to make positive inside log function
ll=0.15
for i in range(0,na):
# create GEKKO model
m = GEKKO(remote=False)
m.time = np.linspace(0,year,n)
t=m.time
A0=dftemp.loc[i][0]
h=dftemp.loc[i][1]
emax=dftemp.loc[i][2]
A = m.SV(value=A0, lb=0, ub=A0)
E = m.SV(value=0, lb=0, ub=A0)
u = m.MV(value=0, lb=-emax, ub=emax)
u.STATUS = 1
t = m.Param(value=m.time)
C = m.Var(value=C0)
d = m.Var(value=1)
l = m.Param(value=ll)
# Equation
m.Equation(A.dt()==-u)
m.Equation(E.dt()==u)
m.Equation(C.dt()==-C/k)
m.Equation(d==m.exp(-t*r))
# Objective (Utility)
J = m.Var(value=0)
# Final objective
Jf = m.FV()
Jf.STATUS = 1
m.Connection(Jf,J,pos2='end')
m.Equation(J.dt() == m.log((A+E*(1-l))*h*Pa0-C*u+E*Pe0+shift)*d)
# maximize U
m.Maximize(Jf)
# options
m.options.IMODE = 6 # optimal control
m.options.NODES = 3 # collocation nodes
m.options.SOLVER = 3 # solver (IPOPT)
# solve optimization problem
m.solve()
# print profit
print('Optimal Profit: ' + str(Jf.value[0]))
案例 3. 将目标函数从 m.log
更改为简单的线性求和。效果很好。
from gekko import GEKKO
import pandas as pd
import numpy as np
dat = {'A0': [23221, 2198, 4296, 104906, 691], 'h': [0.04, 0.25, 0.07, 0, 12.58],'emax': [23221, 2198, 4296, 104906, 691] }
dftemp = pd.DataFrame(data=dat)
na=len(dftemp)
# time points
n=51
year=50
# constants
Pa0 = 3.061
Pe0 = 10.603
C0 = 100
r = 0.05
k=50
shift=10000000 # to make positive inside log function
ll=0.15
for i in range(0,na):
# create GEKKO model
m = GEKKO(remote=False)
m.time = np.linspace(0,year,n)
t=m.time
A0=dftemp.loc[i][0]
h=dftemp.loc[i][1]
emax=dftemp.loc[i][2]
A = m.SV(value=A0, lb=0, ub=A0)
E = m.SV(value=0, lb=0, ub=A0)
u = m.MV(value=0, lb=-emax, ub=emax)
u.STATUS = 1
t = m.Param(value=m.time)
C = m.Var(value=C0)
d = m.Var(value=1)
l = m.Param(value=ll)
# Equation
m.Equation(A.dt()==-u)
m.Equation(E.dt()==u)
m.Equation(C.dt()==-C/k)
m.Equation(d==m.exp(-t*r))
# Objective (Utility)
J = m.Var(value=0)
# Final objective
Jf = m.FV()
Jf.STATUS = 1
m.Connection(Jf,J,pos2='end')
m.Equation(J.dt() == ((A+E*(1-l))*h*Pa0-C*u+E*Pe0+shift)*d)
# maximize U
m.Maximize(Jf)
# options
m.options.IMODE = 6 # optimal control
m.options.NODES = 3 # collocation nodes
m.options.SOLVER = 3 # solver (IPOPT)
# solve optimization problem
m.solve()
# print profit
print('Optimal Profit: ' + str(Jf.value[0]))
案例 4. 将目标函数从 m.log
更改为简单求和,并从目标函数中删除“变量”d
。发生错误
from gekko import GEKKO
import pandas as pd
import numpy as np
dat = {'A0': [23221, 2198, 4296, 104906, 691], 'h': [0.04, 0.25, 0.07, 0, 12.58],'emax': [23221, 2198, 4296, 104906, 691] }
dftemp = pd.DataFrame(data=dat)
na=len(dftemp)
# time points
n=51
year=50
# constants
Pa0 = 3.061
Pe0 = 10.603
C0 = 100
r = 0.05
k=50
shift=10000000 # to make positive inside log function
ll=0.15
for i in range(0,na):
# create GEKKO model
m = GEKKO(remote=False)
m.time = np.linspace(0,year,n)
t=m.time
A0=dftemp.loc[i][0]
h=dftemp.loc[i][1]
emax=dftemp.loc[i][2]
A = m.SV(value=A0, lb=0, ub=A0)
E = m.SV(value=0, lb=0, ub=A0)
u = m.MV(value=0, lb=-emax, ub=emax)
u.STATUS = 1
t = m.Param(value=m.time)
C = m.Var(value=C0)
d = m.Var(value=1)
l = m.Param(value=ll)
# Equation
m.Equation(A.dt()==-u)
m.Equation(E.dt()==u)
m.Equation(C.dt()==-C/k)
m.Equation(d==m.exp(-t*r))
# Objective (Utility)
J = m.Var(value=0)
# Final objective
Jf = m.FV()
Jf.STATUS = 1
m.Connection(Jf,J,pos2='end')
m.Equation(J.dt() == ((A+E*(1-l))*h*Pa0-C*u+E*Pe0+shift))
# maximize U
m.Maximize(Jf)
# options
m.options.IMODE = 6 # optimal control
m.options.NODES = 3 # collocation nodes
m.options.SOLVER = 3 # solver (IPOPT)
# solve optimization problem
m.solve()
# print profit
print('Optimal Profit: ' + str(Jf.value[0]))
案例5.将目标函数从m.log
改为简单线性求和,并将shift
改为0,出现错误
from gekko import GEKKO
import pandas as pd
import numpy as np
dat = {'A0': [23221, 2198, 4296, 104906, 691], 'h': [0.04, 0.25, 0.07, 0, 12.58],'emax': [23221, 2198, 4296, 104906, 691] }
dftemp = pd.DataFrame(data=dat)
na=len(dftemp)
# time points
n=51
year=50
# constants
Pa0 = 3.061
Pe0 = 10.603
C0 = 100
r = 0.05
k=50
shift=0
ll=0.15
for i in range(0,na):
# create GEKKO model
m = GEKKO(remote=False)
m.time = np.linspace(0,year,n)
t=m.time
A0=dftemp.loc[i][0]
h=dftemp.loc[i][1]
emax=dftemp.loc[i][2]
A = m.SV(value=A0, lb=0, ub=A0)
E = m.SV(value=0, lb=0, ub=A0)
u = m.MV(value=0, lb=-emax, ub=emax)
u.STATUS = 1
t = m.Param(value=m.time)
C = m.Var(value=C0)
d = m.Var(value=1)
l = m.Param(value=ll)
# Equation
m.Equation(A.dt()==-u)
m.Equation(E.dt()==u)
m.Equation(C.dt()==-C/k)
m.Equation(d==m.exp(-t*r))
# Objective (Utility)
J = m.Var(value=0)
# Final objective
Jf = m.FV()
Jf.STATUS = 1
m.Connection(Jf,J,pos2='end')
m.Equation(J.dt() == ((A+E*(1-l))*h*Pa0-C*u+E*Pe0+shift)*d)
# maximize U
m.Maximize(Jf)
# options
m.options.IMODE = 6 # optimal control
m.options.NODES = 3 # collocation nodes
m.options.SOLVER = 3 # solver (IPOPT)
# solve optimization problem
m.solve()
# print profit
print('Optimal Profit: ' + str(Jf.value[0]))
最佳答案
对于其中的许多情况,进行一些更改可能会有所帮助,例如:
- 重新制定以避免
m.log()
出现负数。中间变量也有帮助。
# Objective (Utility)
J = m.Var(value=0)
rhs = m.Intermediate((A+E*(1-l))*h*Pa0-C*u+E*Pe0+shift)
m.Equation(m.exp(J.dt()/d)==rhs)
- 优化前初始化。
APOPT
求解器在初始化方面做得更好,而IPOPT
使用APOPT
的初始化解决方案做得更好。 article 中讨论了初始化策略:Safdarnejad, S.M.、Hedengren, J.D.、Lewis, N.R.、Haseltine, E.,动态系统、计算机和化学工程优化的初始化策略,2015 年,卷。 78,第 39-50 页,DOI:10.1016/j.compchemeng.2015.04.016。
# solve optimization problem
m.options.NODES = 3 # collocation nodes
m.options.SOLVER = 1 # solver (APOPT)
m.options.IMODE=4
m.solve()
# solve optimization problem
m.options.TIME_SHIFT=0
m.options.SOLVER=3 # solver (IPOPT)
m.options.IMODE=6
m.solve()
案例 2:n=501 的成功解决方案
from gekko import GEKKO
import pandas as pd
import numpy as np
dat = {'A0': [23221, 2198, 4296, 104906, 691], \
'h': [0.04, 0.25, 0.07, 0, 12.58],\
'emax': [23221, 2198, 4296, 104906, 691] }
dftemp = pd.DataFrame(data=dat)
na=len(dftemp)
# time points
n=501
year=50
# constants
Pa0 = 3.061
Pe0 = 10.603
C0 = 100
r = 0.05
k=50
shift=10000000 # to make positive inside log function
ll=0.15
for i in range(0,na):
# create GEKKO model
m = GEKKO(remote=True)
m.time = np.linspace(0,year,n)
t=m.time
A0=dftemp.loc[i][0]
h=dftemp.loc[i][1]
emax=dftemp.loc[i][2]
A = m.SV(value=A0, lb=0, ub=A0)
E = m.SV(value=0, lb=0, ub=A0)
u = m.MV(value=0, lb=-emax, ub=emax)
u.STATUS = 1
t = m.Param(value=m.time)
C = m.Var(value=C0)
d = m.Var(value=1)
l = m.Param(value=ll)
# Equation
m.Equation(A.dt()==-u)
m.Equation(E.dt()==u)
m.Equation(C.dt()==-C/k)
m.Equation(d==m.exp(-t*r))
# Objective (Utility)
J = m.Var(value=0)
rhs = m.Intermediate((A+E*(1-l))*h*Pa0-C*u+E*Pe0+shift)
m.Equation(m.exp(J.dt()/d)==rhs)
# Final objective
final = np.zeros_like(m.time)
final[-1] = 1
final = m.Param(final)
# maximize U
m.Maximize(final*J)
# solve optimization problem
m.options.NODES = 3 # collocation nodes
m.options.SOLVER = 1 # solver (APOPT)
m.options.IMODE=4
print('\n\nInitializing with APOPT')
m.solve(disp=False)
# solve optimization problem
m.options.TIME_SHIFT=0
m.options.SOLVER=3 # solver (IPOPT)
m.options.IMODE=6
m.solve()
# print profit
print('Optimal Profit: ' + str(J.value[-1]))
请在其他情况下也尝试使用此方法。通常使用 m.sum()
比 sum
更好,因为 Gekko 将求和构造为内置对象而不是长字符串。
编辑:更新的解决方案 这是一个具有正确初始条件的更新解决方案。 IMODE=4
的初始条件不会转移到 IMODE=6
。另一种方法是将 IMODE=6
与等效的 COLDSTART=1
一起使用。
from gekko import GEKKO
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
dat = {'A0': [23221, 2198, 4296, 104906, 691], \
'h': [0.04, 0.25, 0.07, 0, 12.58],\
'emax': [23221, 2198, 4296, 104906, 691] }
dftemp = pd.DataFrame(data=dat)
na=len(dftemp)
# time points
n=101
year=50
# constants
Pa0 = 3.061
Pe0 = 10.603
C0 = 100
r = 0.05
k=50
shift=10000000 # to make positive inside log function
ll=0.15
plt.figure(figsize=(10,5))
for i in range(0,na):
# create GEKKO model
m = GEKKO(remote=True)
m.time = np.linspace(0,year,n)
t=m.time
A0=dftemp.loc[i][0]
h=dftemp.loc[i][1]
emax=dftemp.loc[i][2]
print('A (initial): ' + str(A0))
A = m.Var(value=A0, lb=0, ub=A0)
E = m.Var(value=0, lb=0, ub=A0)
u = m.MV(value=0, lb=-emax, ub=emax)
u.STATUS = 1
t = m.Param(value=m.time)
C = m.Var(value=C0)
d = m.Var(value=1)
l = m.Param(value=ll)
# Equation
m.Equation(A.dt()==-u)
m.Equation(E.dt()==u)
m.Equation(C.dt()==-C/k)
m.Equation(d==m.exp(-t*r))
# Objective (Utility)
J = m.Var(value=0)
rhs = m.Intermediate((A+E*(1-l))*h*Pa0-C*u+E*Pe0+shift)
m.Equation(m.exp(J.dt()/d)==rhs)
# Final objective
final = np.zeros_like(m.time)
final[-1] = 1
final = m.Param(final)
# maximize U
m.Maximize(final*J)
# solve optimization problem
m.options.NODES = 3 # collocation nodes
m.options.SOLVER = 1 # solver (APOPT)
m.options.IMODE=6
m.options.COLDSTART=1
print('\n\nInitializing with APOPT')
m.solve(disp=False)
# solve optimization problem
m.options.COLDSTART=0
m.options.TIME_SHIFT=0
m.options.SOLVER=3 # solver (IPOPT)
m.options.IMODE=6
m.solve()
# print profit
print('Optimal Profit: ' + str(J.value[-1]))
plt.plot(m.time,A.value,label='A case '+str(i))
plt.plot(m.time,E.value,label='E case '+str(i))
plt.plot(m.time,u.value,label='u case '+str(i))
plt.legend()
plt.show()
关于python - 更改参数、目标函数和初始条件时使用 Gekko 优化套件出现 "Solution Not Found"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66977417/