Gekko求解混合整数规划报Solution Not Found错误排查
问题原因
- 核心错误是
m.MV()的误用。MV是Gekko中为动态控制、参数估计场景设计的操纵变量,本身属于决策变量范畴,自带求解自由度。你将表达式直接传入MV构造函数且开启STATUS=1,相当于告诉求解器这些MV可以自由取值,但没有给MV和对应表达式建立等式约束,直接导致模型结构混乱,可行域判断失效,求解器返回无可行整数解的报错。 - 代码中
tempo_b1、tempo_b2、tempo_total本质是基于决策变量计算得到的中间观测值,不属于需要求解器调整的决策变量,用MV定义完全不符合Gekko的变量类型规则。 - 原模型中二进制变量与连续变量相乘的双线性项属于混合整数规划的标准可处理形式,本身不存在建模错误,不需要额外特殊处理。
修复方案
- 移除所有错误的
m.MV()定义,将这类中间计算项替换为m.Intermediate()定义。Intermediate是Gekko专门用于存储中间计算结果的类型,不会额外增加模型自由度,会随决策变量的求解结果自动计算取值。 - 不需要给中间项设置
STATUS参数,Intermediate类型不参与决策变量调整,无需配置求解状态。 - 保留原有的二进制变量互斥约束、变量上下界、APOPT求解器配置即可正常求解。
修复后可正常运行的代码如下:
from gekko import GEKKO m = GEKKO(remote=False) # 二进制开关变量 braco_gas_1 = m.Var(integer=True, lb=0,ub=1) braco_eh_1 = m.Var(integer=True, lb=0,ub=1) braco_gas_2 = m.Var(integer=True, lb=0,ub=1) braco_eh_2 = m.Var(integer=True, lb=0,ub=1) # 连续权重变量 vazao_gas = m.Var(value=100,lb=0,ub=150) vazao_eh = m.Var(value=100,lb=0,ub=150) # 常量定义 volume_gas = 1000 volume_eh = 2000 # 用Intermediate定义目标组成项,仅用于结果观测,不增加自由度 tempo_b1 = m.Intermediate(vazao_gas*braco_gas_1 + volume_gas*braco_gas_2) tempo_b2 = m.Intermediate(vazao_eh*braco_eh_1 + volume_eh*braco_eh_2) tempo_total = m.Intermediate(tempo_b1+tempo_b2) # 每组二进制变量仅一个为真的互斥约束 m.Equation(braco_gas_1+braco_gas_2 == 1) m.Equation(braco_eh_1+braco_eh_2 == 1) # 配置求解目标与求解器 m.Maximize(tempo_total) m.options.SOLVER = 1 m.solve(disp=False) # 打印结果 print('Braco_gas_1:', braco_gas_1.value[0]) print('Braco_gas_2:', braco_gas_2.value[0]) print('Braco_eh_1:', braco_eh_1.value[0]) print('Braco_eh_2:', braco_eh_2.value[0]) print('vazao_gas:', vazao_gas.value[0]) print('vazao_eh:', vazao_eh.value[0]) print('volume_gas:', volume_gas) print('volume_eh:', volume_eh) print('tempo_b1:', tempo_b1.value[0]) print('tempo_b2:', tempo_b2.value[0]) print('tempo_total:', tempo_total.value[0])
修复后求解可正常得到最优解:最优开关组合为
braco_gas_2=1、braco_eh_2=1,此时连续变量取上下界内任意值都不影响目标计算,目标最大值为3000。如果开关切到连续变量分支,连续变量取到上界150时对应目标值仅为300,明显低于常量分支收益,因此求解器会自动选择收益更高的常量分支。
内容的提问来源于stack exchange,提问作者Paulo Britto
相关产品推荐
相关产品推荐

