How to set variable value at x[3]=6 (not initial condition) in Python Gekko?

喜欢而已 提交于 2020-08-07 08:16:08

问题


I can set an initial condition y(0)=5 in Gekko with y = m.Var(5) but how do I set a value that is not the initial condition such as y(3)=6 where the value at time=3 is 6 as shown by the red dot?

from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
m = GEKKO(remote=False)
m.time = np.linspace(0,10,11)
x = m.Var(np.ones(11)*6)
m.Equation(5*x.dt() == -x)
m.options.IMODE = 4
m.solve()
plt.plot(m.time, x.value)
plt.plot([3],[6],'ro',MarkerSize=5)
plt.show()

I have a simulation problem where I need the solution to arrive at intermediate values along the time horizon m.time = [0,1,2,3,4,5,6,7,8,9,10]. When I initialize with x=m.Var(np.ones(11)*6) the values are later changed by the solver. Can I fix one of the values not at the initial condition? This is similar to a boundary value problem where the beginning or end points is fixed but in this case a specified value is internal to the time horizon.


回答1:


The first thing is to make the initial condition calculated with fixed_initial=False option when you specify x=m.Var(). The model building function m.fix() can fix any point in the horizon such as with m.fix(x,pos=3,val=6) but this also fixes the derivative at that point.

An alternative method is to specify an objective to minimize the deviation from the value of 6 at time=3.

pi = np.zeros(11); pi[3]=1
p = m.Param(pi)
m.Minimize(p*(x-6)**2)

This creates the objective everywhere but p is only non-zero at time=3.

from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
m = GEKKO(remote=False)
m.time = np.linspace(0,10,11)
x = m.Var(np.zeros(11)*6,fixed_initial=False)
m.Equation(5*x.dt() == -x)
pi = np.zeros(11); pi[3]=1
p = m.Param(pi)
m.Minimize(p*(x-6)**2)
m.options.IMODE = 6
m.solve()
plt.plot(m.time, x.value)
plt.plot([3],[6],'ro',MarkerSize=5)
plt.show()



回答2:


The Bryson benchmark problem (see #2) shows four ways to fix values that are not initial conditions.

if option == 1:
    # most likely to cause DOF issues because of many 
    #  zero (0==0) equations
    m.Equation(final*x1 == 0)
    m.Equation(final*x2 == 0) 
elif option == 2:
    # inequality constraint approach is better but there
    #   are still many inactive equations
    m.Equation((final*x1)**2 <= 0)
    m.Equation((final*x2)**2 <= 0)
elif option == 3: #requires GEKKO version >= 0.0.3a2
    # fix the value just at the endpoint (best option)
    m.fix(x1,pos=nt-1,val=0)
    m.fix(x2,pos=nt-1,val=0)
else:
    #penalty method ("soft constraint") that may influence
    # optimal solution because there is just one
    # combined objective and it may interfere with
    # minimizing myObj
    m.Obj(1000*(final*x1)**2)
    m.Obj(1000*(final*x2)**2)

m.Obj(myObj*final)

This code could be adapted to have a point in the middle.



来源:https://stackoverflow.com/questions/59234190/how-to-set-variable-value-at-x3-6-not-initial-condition-in-python-gekko

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!