在PySCIPOpt主优化模型中调用含子优化模型的函数是否可行?
问题原因与解决方案
核心问题说明
当前的嵌套调用方式不可行。
优化库的变量实例与所属Model实例强绑定,不允许跨模型引用。你将主模型的变量n直接传入子模型optfunc的约束中,子模型无法识别外部变量的上下文,触发底层内存错误,表现为内核崩溃或程序无响应。单独调用optfunc时传入的是普通数值而非模型变量,因此可以正常运行。
可行改造方案
方案1:单模型拆分逻辑(适用于仅拆分代码模块、不需要独立求解子模型的场景)
不要在子函数中新建独立的Model实例,直接将主模型作为参数传入子函数,所有变量、约束都建立在同一个模型实例上:
def optfunc(mod, x): # 直接使用传入的主模型实例,不新建模型 y = mod.addVar("y", ub = 2, lb = -1) consl = mod.addCons(y + x <= 3, "cons") # 子函数仅返回新增的变量,不单独执行求解 return y
主模型代码调整如下:
mainfunc = Model() n = mainfunc.addVar("n",lb=1,ub=3) # 将主模型实例和变量一起传入子函数 c = optfunc(mainfunc, n) const = mainfunc.addCons(n + 0.5 == 1, "cons") # 目标函数可按需调整,比如要同时优化n和c可写为n + c mainfunc.setObjective(n, "maximize") mainfunc.optimize() sol = mainfunc.getBestSol() print(mainfunc.getSolVal(sol,n)) # 可直接获取子函数中新增变量的求解结果 print(mainfunc.getSolVal(sol,c))
方案2:双层优化求解(适用于确实需要独立求解子模型的场景)
如果你需要先基于主模型变量的取值求解子模型,再将子模型输出代入主模型,属于双层优化问题,不能直接传递变量实例,需要调整为迭代求解逻辑:
- 枚举或通过启发式算法给定主模型变量
n的候选数值 - 将数值传入
optfunc求解得到c的对应取值 - 将
c代入主模型验证约束、计算目标值,筛选得到最优解
也可直接使用支持双层优化的求解器接口实现对应逻辑。
内容的提问来源于stack exchange,提问作者Denver Pascua
相关产品推荐
相关产品推荐

