我可以使用什么 GEKKO 模型构造或建模策略来固定 MV 在特定时间的 UPPER 值甚至状态属性

What GEKKO model construct(s) or modelling strategy can I use to fix the UPPER value or even status attribute of MV at a specific time

我计划使用 GEKKO 解决动态生产调度问题,涉及 供应、处理、消耗流程,在某些步骤之间具有 hold-up(存储)。我想在 horizon 上最大化一些 objective。但是,在某些时间步,某些单元操作的处理能力可能存在 pre-defined 限制。虽然我可以使用 fix(var,val,pos) 函数将变量完全固定在 pos,但将其限制在 UPPER 一侧更能代表我想要完成的事情,并且在某些情况下可能会产生不同的解决方案.
这是一些玩具问题代码,还没有包含动态):

"""
Simple toy problem to test flexibillity of limiting MV's at certain time points in the
horizon without fixing them specifically, i.e. leave one bound unconstrained.
"""

from gekko import GEKKO

m=GEKKO(remote=False)
m.time=[0,1,2,3,4]  #Use 5 discrete points
m.options.CV_TYPE = 1

supply2=m.Param(5.5)  #Supply of stream2 available to a separation unit op
recovery=m.Const(value=0.92)  #Extraction efficiency of unit op
feed1=m.MV(20,lb=15,ub=40)  #define feed 1 as an independent variable
feed2=m.MV(5,lb=0,ub=10) #define feed 2 as an independent variable

feed1.COST=1  #cost of feed stream 1
feed2.COST=1.5 #cost of feed stream 2

feed1.STATUS=1  #use feed1 in optimisation
feed2.STATUS=1  #use feed2 in optimisation

ovhds=m.CV(30) #define ovhds of unit op as dependent variable
ovhds.STATUS=1 #use in Objective function
ovhds.SPLO=40  #low limit for dependent variable
ovhds.SPHI=50  #high limit for dependenent variable
ovhds.COST=-2  # negative cost (aka profit) from extracted stream
feed1.UPPER=48 #set overall upper limit of 48 for feed1 MV
m.fix(feed1,47,2)  #fix feed 1 at a point pos=2 in the horizon
#TODO: add dynamics e.g. differential equations to model inventory volumes.

supply2_flared=m.Intermediate(feed2-supply2)  #another independent variable
total_feed=m.Intermediate(feed1+feed2)  #the total intake of feed

m.Equation(ovhds==total_feed*recovery)  #define relationship between dependent and independent variable

m.options.IMODE=6 #dynamic control, dynamics and dynamic constraints to be added as Equations later.
m.solve()

print("Feed1",feed1.value)
print("Feed2", feed2.value)
print("Product", ovhds.value)

定义一个随时间变化的参数,例如 feed1_ub 并包含一个不等式约束 m.Equation()

feed1_ub = m.Param([48,48,30,48,48])
m.Equation(feed1<=feed1_ub)

这是一个完整的脚本:

from gekko import GEKKO

m=GEKKO(remote=False)
m.time=[0,1,2,3,4]  #Use 5 discrete points
m.options.CV_TYPE = 1

supply2=m.Param(5.5)  #Supply of stream2 available to a separation unit op
recovery=m.Const(value=0.92)  #Extraction efficiency of unit op
feed1=m.MV(20,lb=15,ub=40)  #define feed 1 as an independent variable
feed2=m.MV(5,lb=0,ub=10) #define feed 2 as an independent variable

feed1.COST=1  #cost of feed stream 1
feed2.COST=1.5 #cost of feed stream 2

feed1.STATUS=1  #use feed1 in optimisation
feed2.STATUS=1  #use feed2 in optimisation

ovhds=m.CV(30) #define ovhds of unit op as dependent variable
ovhds.STATUS=1 #use in Objective function
ovhds.SPLO=40  #low limit for dependent variable
ovhds.SPHI=50  #high limit for dependenent variable
ovhds.COST=-2  # negative cost (aka profit) from extracted stream
feed1.UPPER=48 #set overall upper limit of 48 for feed1 MV

supply2_flared=m.Intermediate(feed2-supply2)  #another independent variable
total_feed=m.Intermediate(feed1+feed2)  #the total intake of feed

m.Equation(ovhds==total_feed*recovery)  #define relationship between dependent and independent variable

feed1_ub = m.Param([48,48,30,48,48])
m.Equation(feed1<=feed1_ub)

m.options.IMODE=6 #dynamic control, dynamics and dynamic constraints to be added as Equations later.
m.solve()

print("Feed1",feed1.value)
print("Feed2", feed2.value)
print("Product", ovhds.value)

解决方案

EXIT: Optimal Solution Found.

 The solution was found.

 The final value of the objective function is  -92.03399437705355
 
 ---------------------------------------------------
 Solver         :  IPOPT (v3.12)
 Solution time  :  0.043 sec
 Objective      :  -92.03399324684949
 Successful solution
 ---------------------------------------------------
 

Feed1 [20.0, 48.0, 30.000000009, 48.0, 48.0]
Feed2 [5.0, 6.3478260396, 10.0, 6.3478260399, 6.3478260394]
Product [30.0, 49.999999965, 36.8000001, 49.999999965, 49.999999965]