GEKKO建模如何在指定时间步设置MV的UPPER上限或STATUS属性约束
在Gekko中指定时间步设置MV上限与STATUS属性的可用策略
- 方法1:直接修改MV属性的时序值
Gekko中MV的UPPER、LOWER、STATUS等属性本身就是和m.time长度一致的数组,支持单独修改指定索引位置的取值,不需要额外新增约束,是最简单的实现方式:- 要设置指定时间步的上限:直接修改对应索引的
UPPER属性即可,比如要在第3个时间步(索引为2)将feed1的上限设为47,其他时间步保留全局上限48,仅需替换原代码中的m.fix(feed1,47,2)为feed1.UPPER[2] = 47 - 要设置指定时间步的STATUS属性:直接修改对应索引的
STATUS属性即可,比如feed1.STATUS[2] = 0即可让该时间步的feed1不参与优化、保持初始值不变,其他时间步仍正常优化
- 要设置指定时间步的上限:直接修改对应索引的
- 方法2:新增时间相关参数的不等式约束
如果需要批量处理多时间步的可变约束,或者需要和其他逻辑联动,可以定义一个和m.time等长的参数数组作为动态上限,再新增不等式约束即可:
# 定义feed1的动态上限,索引2位置设为47,其余为全局上限48 feed1_upper = m.Param([48,48,47,48,48]) # 新增上限约束 m.Equation(feed1 <= feed1_upper)
这种方式扩展性更强,上限值可以和其他参数、中间变量联动,适合复杂的生产调度场景。
修改后的可运行测试代码如下:
""" 修改后的测试代码,实现指定时间步设置MV上限 """ from gekko import GEKKO m=GEKKO(remote=False) m.time=[0,1,2,3,4] # 共5个离散时间点 m.options.CV_TYPE = 1 supply2=m.Param(5.5) # 分离单元可使用的stream2供应量 recovery=m.Const(value=0.92) # 单元提取效率 feed1=m.MV(20,lb=15,ub=40) # 进料1自变量 feed2=m.MV(5,lb=0,ub=10) # 进料2自变量 feed1.COST=1 # 进料1成本 feed2.COST=1.5 # 进料2成本 feed1.STATUS=1 # 进料1参与优化 feed2.STATUS=1 # 进料2参与优化 ovhds=m.CV(30) # 塔顶产物因变量 ovhds.STATUS=1 # 塔顶产物纳入目标函数 ovhds.SPLO=40 # 产物下限 ovhds.SPHI=50 # 产物上限 ovhds.COST=-2 # 产物收益(负成本) feed1.UPPER=48 # 进料1全局上限48 # 替换原fix语句,仅设置索引2位置的上限为47,不固定死取值 feed1.UPPER[2] = 47 # 如需要设置索引2位置STATUS为0,取消下行注释即可 # feed1.STATUS[2] = 0 # 待补充:库存体积建模的微分方程等动力学逻辑 supply2_flared=m.Intermediate(feed2-supply2) # 燃料气排放量 total_feed=m.Intermediate(feed1+feed2) # 总进料量 m.Equation(ovhds==total_feed*recovery) # 变量关联关系 m.options.IMODE=6 # 动态控制模式,后续可新增动力学/动态约束 m.solve() print("Feed1",feed1.value) print("Feed2", feed2.value) print("Product", ovhds.value)
两种方法均兼容后续添加的存储、动力学约束,无需调整原有核心逻辑。
内容的提问来源于stack exchange,提问作者JacquesStrydom
相关产品推荐
相关产品推荐

