Gekko二进制规划中含多函数的目标函数报错求助
Gekko整数规划报错解决:自定义目标函数无法解析
问题分析
你遇到的报错核心是Gekko的m.Minimize()要求传入可解析的数学表达式,但你直接传入了Python函数对象Func,且该函数内部涉及修改文件、调用外部排水模型等黑箱操作,Gekko无法将这类Python函数转换为求解器能识别的优化表达式。
错误原因
m.Minimize(Func)是错误写法:即便改为m.Minimize(Func(x))也不成立——x是Gekko的符号变量,而非数值,你的Func只能处理数值向量,无法直接解析符号变量。- 目标函数属于黑箱函数:依赖外部程序计算,无显式数学表达式,Gekko默认优化模式不支持直接处理这类函数。
解决方案
方案1:枚举法(适配你的小规模问题)
你的变量是8个二进制数,约束和为4,总共有C(8,4)=70种组合,直接枚举所有可能组合,计算目标值后选最优解,简单高效:
from gekko import GEKKO import itertools # 目标函数(接受数值向量输入) def Func(x): Mod_File('Example1.inp', x) Mod_File_name = Mod_File_Name('Example1.inp') L2_Norm = Norm_Peak_Flows(Mod_File_name, Dict_Links('Example1.inp')) return L2_Norm best_norm = float('inf') best_x = None # 生成所有满足sum(x)=4的二进制组合 for bits in itertools.combinations(range(8), 4): x = [0]*8 for idx in bits: x[idx] = 1 current_norm = Func(x) if current_norm < best_norm: best_norm = current_norm best_x = x print(f"最优解:{best_x},最小L2范数:{best_norm}")
方案2:Gekko黑箱优化(适配大规模问题)
若变量规模更大,用user_defined()包装黑箱函数,配合Gekko的黑箱优化模式:
from gekko import GEKKO m = GEKKO(remote=False) # 定义二进制变量 x = m.Array(m.Var, 8, lb=0, ub=1, integer=True) # 设置初始值 for xi in x: xi.value = 1 if xi.index in [1,3,5] else 0 # 定义目标变量 obj = m.Var() # 黑箱函数:输入数值向量,返回目标值 def black_box(x_val): Mod_File('Example1.inp', x_val) Mod_File_name = Mod_File_Name('Example1.inp') return Norm_Peak_Flows(Mod_File_name, Dict_Links('Example1.inp')) # 将黑箱函数注册到Gekko m.user_defined(obj, *x, func=black_box) # 设置优化目标与约束 m.Minimize(obj) m.Equation(sum(x) == 4) # 配置求解器与模式 m.options.SOLVER = 1 # APOPT混合整数规划求解器 m.options.IMODE = 2 # 黑箱优化模式 m.solve(disp=True) print(f"最优变量值:{[xi.value[0] for xi in x]}") print(f"最小L2范数:{obj.value[0]}")
关键注意事项
- 确保
Mod_File、Mod_File_Name等辅助函数能正确处理数值向量输入,而非Gekko符号变量。 - 方案1适合当前问题规模,计算速度远快于黑箱优化;方案2则适用于变量数量多、组合数庞大的场景。
内容的提问来源于stack exchange,提问作者Gwhyneth Eliscupidez
相关产品推荐
相关产品推荐

