繁体   English   中英

如何在 Python Gekko 中设置 x[3]=6(非初始条件)的变量值?

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

我可以在 Gekko 中使用y = m.Var(5)设置初始条件 y(0)=5 但如何设置不是初始条件的值,例如 y(3)=6 其中时间值= 3 是 6,如红点所示?

指定内点

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()

我有一个模拟问题,我需要解决方案沿时间范围m.time = [0,1,2,3,4,5,6,7,8,9,10]获得中间值。 当我用x=m.Var(np.ones(11)*6)初始化时,求解器稍后会更改这些值。 我可以修复不在初始条件下的值之一吗? 这类似于边界值问题,其中起点或终点是固定的,但在这种情况下,指定值是时间范围的内部。

第一件事是在指定x=m.Var()时使用fixed_initial=False选项计算初始条件。 模型构建函数m.fix()可以修复视界中的任何点,例如m.fix(x,pos=3,val=6)但这也修复了该点的导数。

另一种方法是指定一个目标,以最小化时间=3 时与值6的偏差。

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

这会在任何地方创建目标,但p仅在 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()

Bryson 基准问题(参见#2)展示了四种修复非初始条件值的方法。

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)

这段代码可以修改为在中间有一个点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM