关于GEKKO中条件语句('m.if3')的问题

Question about the conditional statement ('m.if3') in the GEKKO

我想在 GEKKO 代码中添加一些条件语句。

我用 'm.if3' 添加了以下语句。但是,如果没有条件语句,它会返回语法错误。

'R1_1 = m.if3(R1<0, 0, R1)'

#%% GEKKO
m = GEKKO(remote=False)

#print(m.version)
#m.time = np.linspace(0, 3600, 100)
m.time = np.array([0,tstep])

cH = m.CV(value=cs0[0])
cM = m.CV(value=cs0[1])
cW = m.CV(value=cs0[2])
cF = m.CV(value=cs0[3])

R1_1 = m.Var()

r3 = m.Intermediate(r0*(1-cF/cFeMax)**(1/3))
r2 = m.Intermediate(r0*((2*cH + 3*cM)/cFeMax)**(1/3))
r1 = m.Intermediate(r0*(2*cH/cFeMax)**(1/3))
x = m.Intermediate(r1/r0)
y = m.Intermediate(r2/r0)
z = m.Intermediate(r3/r0)
A1 = m.Intermediate(1/x**2/(kd[0]*(1+1/Keq[0])))
A2 = m.Intermediate(1/y**2/(kd[1]*(1+1/Keq[1])))
A3 = m.Intermediate(1/z**2/(kd[2]*(1+1/Keq[2])))
B1 = m.Intermediate((y-x)/x/y*r0/Dif[1])
B2 = m.Intermediate((z-y)/y/z*r0/Dif[2])
B3 = m.Intermediate((1-z)/z*r0/Dif[3])
F = 0
W = m.Intermediate((A1+B1)*(A3*(A2+B2+B3+F)+(A2+B2)*(B3+F))+A2*(A3*(B2+B3+F))+B2*(B3+F))
ceq1 = m.Intermediate((cg0[0]+cg0[1])/(1+Keq[0]))
ceq2 = m.Intermediate((cg0[0]+cg0[1])/(1+Keq[1]))
ceq3 = m.Intermediate((cg0[0]+cg0[1])/(1+Keq[2]))

R1 = m.Intermediate(3/r0/W*((A3*(A2+B2+B3+F)+(A2+B2)*(B3+F))*(cg0[0]-ceq1) \
                     -(A3*(B2+B3+F)+B2*(B3+F))*(cg0[0]-ceq2) \
                     -A2*(B3+F)*(cg0[0]-ceq3)))
R2 = m.Intermediate(3/r0/W*(-(B2*(A3+B3+F)+A3*(B3+F))*(cg0[0]-ceq1) \
                     +((A1+B1+B2)*(A3+B3+F)+A3*(B3+F))*(cg0[0]-ceq2) \
                     -(A1+B1)*(B3+F)*(cg0[0]-ceq3)))
R3 = m.Intermediate(3/r0/W*(-A2*(B3+F)*(cg0[0]-ceq1) \
                    -(A1+B1)*(B3+F)*(cg0[0]-ceq2) \
                    +((A1+B1)*(A2+B2+B3+F)+A2*(B2+B1+F))*(cg0[0]-ceq3)))

R1_1 = m.if3(R1<0, 0, R1)

m.Equation(cH.dt() == nus[0].dot([R1_1, R2, R3]))
m.Equation(cM.dt() == nus[1].dot([R1_1, R2, R3]))
m.Equation(cW.dt() == nus[2].dot([R1_1, R2, R3]))
m.Equation(cF.dt() == nus[3].dot([R1_1, R2, R3]))

m.options.IMODE = 4
m.options.SOLVER = 3
m.options.nodes = 2

异常:@error:模型表达式 *** 函数字符串语法错误:括号不匹配

位置:4
(0)))-((((1-int_v5))*(i35)-slk_1 ?

您只需更正一次(删除 <0)即可使用 Gekko 中的 if3 功能。

R1_1 = m.if3(R1, 0, R1)

m.if3 函数使用一个条件,根据条件是小于零还是大于或等于零来切换所使用的内容(参数 2 或 3)。以下是帮助 (m.if3) 的结果以及一些额外的解释:

if3(condition, x1, x2) method of gekko.gekko.GEKKO instance

IF conditional with a binary switch variable.
The traditional method for IF statements is not continuously
differentiable and can cause a gradient-based optimizer to fail
to converge.

Usage: y = m.if3(condition,x1,x2)
Inputs:
   condition: GEKKO variable, parameter, or expression
   x1 and x2: GEKKO variable, parameter, or expression
Output: GEKKO variable y = x1 when condition<0
                       y = x2 when condition>=0

另一件需要考虑的事情是 if3 函数使用二进制变量,您需要使用混合整数求解器来找到整数解。您可以删除将求解器切换到 IPOPT 的行(if3 默认切换到 APOPT 求解器),也可以手动将选项切换到 APOPT。

m.options.SOLVER = 1

您的脚本中缺少一些常量。我添加了一些虚拟变量只是为了使它成为 运行.

from gekko import GEKKO
import numpy as np

m = GEKKO()

help(m.if3)

tstep = 1.0
cs0=[1,1,1,1]
r0 = 1.0
cFeMax = 1.0
kd = [1,1,1]
Keq = [1,1,1]
Dif = [1,1,1,1]
cg0 = [1,1,1]
nus = np.array([[1,1,1],[1,1,1],[1,1,1],[1,1,1]])

m.time = np.array([0,tstep])

cH = m.CV(value=cs0[0])
cM = m.CV(value=cs0[1])
cW = m.CV(value=cs0[2])
cF = m.CV(value=cs0[3])

R1_1 = m.Var()

r3 = m.Intermediate(r0*(1-cF/cFeMax)**(1/3))
r2 = m.Intermediate(r0*((2*cH + 3*cM)/cFeMax)**(1/3))
r1 = m.Intermediate(r0*(2*cH/cFeMax)**(1/3))
x = m.Intermediate(r1/r0)
y = m.Intermediate(r2/r0)
z = m.Intermediate(r3/r0)
A1 = m.Intermediate(1/x**2/(kd[0]*(1+1/Keq[0])))
A2 = m.Intermediate(1/y**2/(kd[1]*(1+1/Keq[1])))
A3 = m.Intermediate(1/z**2/(kd[2]*(1+1/Keq[2])))
B1 = m.Intermediate((y-x)/x/y*r0/Dif[1])
B2 = m.Intermediate((z-y)/y/z*r0/Dif[2])
B3 = m.Intermediate((1-z)/z*r0/Dif[3])
F = 0
W = m.Intermediate((A1+B1)*(A3*(A2+B2+B3+F)+(A2+B2)*(B3+F))+A2*(A3*(B2+B3+F))+B2*(B3+F))
ceq1 = m.Intermediate((cg0[0]+cg0[1])/(1+Keq[0]))
ceq2 = m.Intermediate((cg0[0]+cg0[1])/(1+Keq[1]))
ceq3 = m.Intermediate((cg0[0]+cg0[1])/(1+Keq[2]))

R1 = m.Intermediate(3/r0/W*((A3*(A2+B2+B3+F)+(A2+B2)*(B3+F))*(cg0[0]-ceq1) \
                     -(A3*(B2+B3+F)+B2*(B3+F))*(cg0[0]-ceq2) \
                     -A2*(B3+F)*(cg0[0]-ceq3)))
R2 = m.Intermediate(3/r0/W*(-(B2*(A3+B3+F)+A3*(B3+F))*(cg0[0]-ceq1) \
                     +((A1+B1+B2)*(A3+B3+F)+A3*(B3+F))*(cg0[0]-ceq2) \
                     -(A1+B1)*(B3+F)*(cg0[0]-ceq3)))
R3 = m.Intermediate(3/r0/W*(-A2*(B3+F)*(cg0[0]-ceq1) \
                    -(A1+B1)*(B3+F)*(cg0[0]-ceq2) \
                    +((A1+B1)*(A2+B2+B3+F)+A2*(B2+B1+F))*(cg0[0]-ceq3)))

R1_1 = m.if3(R1, 0, R1)

m.Equation(cH.dt() == nus[0].dot([R1_1, R2, R3]))
m.Equation(cM.dt() == nus[1].dot([R1_1, R2, R3]))
m.Equation(cW.dt() == nus[2].dot([R1_1, R2, R3]))
m.Equation(cF.dt() == nus[3].dot([R1_1, R2, R3]))

m.options.IMODE = 4
m.options.SOLVER = 1
m.options.nodes = 2

m.solve()