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

如何在GEKKO中实现OR约束?电机优化求解遇阻求助

电机成本优化问题的解决方案

问题根源分析

核心问题出在决策变量x[motor]的下限设置错误:

  • 原代码中x[motor]的lb被设为电机的功率下限(比如Motor1的lb=0.6),但电机不运行时功率应为0,这导致当y[motor]=0(不运行)时,约束x[motor] <= 功率上限 * y[motor]要求x=0,与x的下限限制冲突,无法满足。
  • 当总功率约束设为4.7时,刚好是所有电机运行的最小总功率(0.6+2.1+1+1=4.7),此时所有y[motor]=1,x[motor]取下限即可满足所有约束;但总功率小于4.7时,必须有电机不运行,而x的下限限制导致无法实现,因此找不到可行解。

修正步骤

  1. 调整x[motor]的下限为0:允许电机不运行时功率为0,运行时通过约束限制功率范围。
  2. 保留运行/不运行的约束逻辑:
    • x[motor] >= 功率下限 * y[motor]:运行时(y=1)功率不低于下限,不运行时(y=0)功率≥0(符合lb=0)。
    • x[motor] <= 功率上限 * y[motor]:运行时功率不超过上限,不运行时功率≤0(结合lb=0,功率只能为0)。
  3. 简化价格函数:消除冗余计算,避免潜在数值问题。
  4. 按需设置总功率约束:可设为固定值或范围约束。

修正后的代码

from gekko import GEKKO

power_ranges = {
    'Motor1': (0.6, 1.1),
    'Motor2': (2.1, 6),
    'Motor3': (1, 1.94),
    'Motor4': (1, 1.94),
}

# 简化价格函数,消除冗余计算
prices = {
    'Motor1': lambda x: x * 5000,
    'Motor2': lambda y: (y / 0.45) * 5500,
    'Motor3': lambda z: z * 0.45 * 5100,
    'Motor4': lambda a: (a / 0.45) * 5200,
}

model = GEKKO()

# 定义决策变量:x的lb改为0,允许电机不运行时功率为0
x = {}
y = {}
for motor in power_ranges:
    lower, upper = power_ranges[motor]
    x[motor] = model.Var(lb=0, ub=upper)  # lb设为0
    y[motor] = model.Var(lb=0, ub=1, integer=True)

# 目标函数:最小化总成本
model.Minimize(sum(prices[motor](x[motor]) for motor in power_ranges))

# 运行/不运行约束:要么x=0(y=0),要么x在功率范围内(y=1)
for motor in power_ranges:
    lower, upper = power_ranges[motor]
    model.Equation(x[motor] >= lower * y[motor])
    model.Equation(x[motor] <= upper * y[motor])

# 设置总功率约束:可替换为范围约束
# 范围约束示例:
# model.Equation(sum(x[motor] for motor in power_ranges) >= 1)
# model.Equation(sum(x[motor] for motor in power_ranges) < 4.7)
model.Equation(sum(x[motor] for motor in power_ranges) == 1)

# 求解模型(SOLVER=1为APOPT,适合混合整数优化)
model.options.SOLVER = 1
model.solve(disp=False)  # disp=False关闭求解过程输出

# 输出结果
if model.options.APPSTATUS == 1:
    print("最优解:")
    for motor in power_ranges:
        print(f"{motor}: {round(float(x[motor].value[0]), 2)} (运行状态:{'运行' if round(y[motor].value[0]) ==1 else '停止'})")
    print(f"总成本:{round(float(model.options.OBJFCNVAL), 2)}")
else:
    print("未找到可行解。")

运行结果说明

  • 当总功率约束设为==1时,最优解为Motor3运行(功率1),其他电机停止,总成本2295.0,符合预期的最低成本。
  • 当设置为1<=sum(x)<4.7时,求解器会自动选择成本最低的组合(如仅运行Motor3)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 17:10:02