首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更改参数、目标函数和初始条件时,使用Gekko优化套件时出现"Solution Not Found“错误

更改参数、目标函数和初始条件时,使用Gekko优化套件时出现"Solution Not Found“错误
EN

Stack Overflow用户
提问于 2021-04-07 06:47:29
回答 1查看 104关注 0票数 2

我正在尝试使用Gekko套件来解决具有各种初始条件的多个优化问题。分配初始条件,使用Gekko运行优化,并收集每个解。当我尝试更改参数、目标函数或初始条件时,Gekko经常给我“Solution Not Found error: line 2130,in solve raise Exception(Apm_error)”。我在下面介绍一些案例,希望能得到解决这个问题的建议。我之前也有一个类似的问题,但我希望这个问题更简洁和清晰。谢谢。

情况1.运行良好,没有错误。

代码语言:javascript
复制
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时出错

代码语言:javascript
复制
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改为简单的线性求和。效果很好。

代码语言:javascript
复制
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更改为简单的sum,并从目标函数中删除“可变”d。发生错误

代码语言:javascript
复制
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。发生错误

代码语言:javascript
复制
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]))
EN

回答 1

Stack Overflow用户

发布于 2021-04-09 12:51:03

对于这些情况中的许多情况,它可以帮助进行一些更改,例如:

  • 重新制定,以避免使用负值的m.log()。中间变量也可以提供帮助。

代码语言:javascript
复制
# 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.,Initialization strategies for Optimization of Dynamic Systems,Computers and Chemical,2015,Vol.78,pp.39-50,DOI: DOI

代码语言:javascript
复制
# 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的成功解决方案

代码语言:javascript
复制
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。另一种方法是在COLDSTART=1中使用等效的IMODE=6

代码语言:javascript
复制
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()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66977417

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档