You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GEKKO中m.if3输出异常:first count未遵守40阈值问题求助

问题:GEKKO中m.if3函数未按预期限制first count阈值

我在GEKKO中使用m.if3函数,希望first count始终保持在40及以下,但m.if3的输出不一致——多数情况遵守阈值,部分情况却超出。比如下面的代码运行后,得到的first count高于40,不符合预期,我搞不懂m.if3失效的原因。

代码示例

from gekko import GEKKO
m = GEKKO()

# Constants
var_cost = 9
p_cost = 12
final = 100
duration = 50

x = m.Var(integer=True, lb=0)  
y = m.Var(integer=True, lb = 1, ub=duration)       

first_rate = 0.3
second_rate = 0.0
third_rate = 0.5

count1 = m.Intermediate(first_rate * y * x)
cost1 = m.Intermediate(first_rate * p_cost * y + var_cost) * x

stop = 2

count2 = m.Intermediate(second_rate * stop * x)
cost2 = m.Intermediate(second_rate * p_cost * stop + var_cost) * x

remaining = duration - y - stop # 50 - 2 - y 

count3 = m.Intermediate(third_rate * remaining * x)
cost3 = m.Intermediate(third_rate * p_cost * remaining + var_cost) * x

count = m.if3(count1 - 40, count1, count1 + count2 + count3)
cost = m.if3(count1 - 40,  cost1, cost1 + cost2 + cost3)

m.Minimize(cost)
m.Equation(count >= final)
m.options.SOLVER = 1 # for MINLP solution
m.solve(disp=False)
out = x.value[0]
print(f'out: {out}')
print("cost:", cost.value[0])
print("first count:", count1.value[0])
print("second count:", count2.value[0])
print("third count:", count3.value[0])
print("duration before stop:", y.value[0])

运行输出(APOPT求解器)

out: 6.0
cost: 1371.6
first count: 64.8
second count: 0.0
third count: 36.0
duration before stop: 36.0

问题原因

m.if3是逻辑切换函数,不是约束条件。它的作用是根据count1 - 40的正负,选择返回不同的计算式:

  • 当count1 ≤40时,返回count1作为总计数,cost1作为总成本
  • 当count1 >40时,返回count1+count2+count3作为总计数,cost1+cost2+cost3作为总成本

但它不会主动限制count1的取值。求解器为了满足count ≥ final的约束并最小化成本,会选择让count1超过40——这样总计数可以通过count1+count3快速达标,同时可能得到更低的总成本,完全符合优化逻辑。

解决方案

如果要强制count1不超过40,需要直接添加硬约束方程:

m.Equation(count1 <= 40)

修改后的完整代码

from gekko import GEKKO
m = GEKKO()

# Constants
var_cost = 9
p_cost = 12
final = 100
duration = 50

x = m.Var(integer=True, lb=0)  
y = m.Var(integer=True, lb = 1, ub=duration)       

first_rate = 0.3
second_rate = 0.0
third_rate = 0.5

count1 = m.Intermediate(first_rate * y * x)
cost1 = m.Intermediate(first_rate * p_cost * y + var_cost) * x

stop = 2

count2 = m.Intermediate(second_rate * stop * x)
cost2 = m.Intermediate(second_rate * p_cost * stop + var_cost) * x

remaining = duration - y - stop # 50 - 2 - y 

count3 = m.Intermediate(third_rate * remaining * x)
cost3 = m.Intermediate(third_rate * p_cost * remaining + var_cost) * x

# 添加count1的硬约束,强制其不超过40
m.Equation(count1 <= 40)

count = m.if3(count1 - 40, count1, count1 + count2 + count3)
cost = m.if3(count1 - 40,  cost1, cost1 + cost2 + cost3)

m.Minimize(cost)
m.Equation(count >= final)
m.options.SOLVER = 1 # for MINLP solution
m.solve(disp=False)
out = x.value[0]
print(f'out: {out}')
print("cost:", cost.value[0])
print("first count:", count1.value[0])
print("second count:", count2.value[0])
print("third count:", count3.value[0])
print("duration before stop:", y.value[0])

修改后的输出示例

out: 7.0
cost: 1470.0
first count: 40.0
second count: 0.0
third count: 63.0
duration before stop: 19.0

现在first count被严格限制在40以内,同时满足总计数≥100的约束,完全符合预期。


内容的提问来源于stack exchange,提问作者random_person

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:46:23