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

SCIP求解MILP问题时如何设置初始猜测及代码疑问

SCIP MILP问题添加新变量后设置初始猜测的疑问与解答

我在使用SCIP库时,因文档不完善,无法理清设置初始猜测的方法调用流程。现有一个包含n个整数与连续变量及约束的MILP问题,需求是:先求解该问题得到最优解,再向问题中添加一个新变量及相关约束,将原最优解作为n+1变量新问题的部分初始猜测。我设想的实现代码如下:

SCIPsolve(scipeEnv); // 求解含n个变量的问题
SCIP_Sol *sol = SCIPgetBestSol(scipEnv); // 获取最优解
SCIP_Sol *copiedSol = nullptr; // 最优解的副本
SCIPcreateSolCopy(scipEnv, copiedSol, sol); // 复制最优解

// [1] 复制得到的解是否与原问题关联,转换原问题状态时是否需要解绑?
// [2] 是否必须进行解的复制操作?

SCIPfreeTransform(scip); // 将问题转换回原始状态

// *** 向问题中添加新变量及相关约束 ***

SCIPcreatePartialSol(scip, &copiedSol, nullptr);

// [3] 是否通过以下流程创建初始猜测:获取最优解→复制解→基于复制解创建部分解?
// 还是需要将最优解的值提取到临时双精度变量中,再创建部分解并传入这些值?

SCIP_Bool stored;
SCIPaddSolFree(scipEnv, &copiedSol, &stored);

疑问解答

[1] 复制得到的解是否与原问题关联,转换原问题状态时是否需要解绑?

复制得到的copiedSol与原转换后的问题强绑定。调用SCIPfreeTransform将问题转回原始状态时,原转换问题的内存会被释放,绑定在它上面的解会直接失效。因此,必须在调用SCIPfreeTransform前,要么解绑复制的解,要么提前提取解中的变量值——后者更稳妥,因为解绑操作容易出错。

[2] 是否必须进行解的复制操作?

是的,必须复制。SCIPgetBestSol返回的是SCIP内部管理的解对象,当你修改问题结构(比如添加变量)或释放转换状态时,这个内部解会被销毁或标记为无效。复制解可以把解的内容独立出来,避免后续操作导致原始最优解不可用。另外注意:你代码里的SCIPcreateSolCopy调用有误,正确格式是SCIPcreateSolCopy(scip, &copiedSol, sol);——第二个参数需要传指针的指针,否则无法正确分配内存。

[3] 两种初始猜测设置方式的可行性

你设想的流程不可行,因为SCIPcreatePartialSol是创建新的空部分解,不是基于已有解修改;而且原复制的解在SCIPfreeTransform后已经失效,无法复用。更可靠的方式是提取原最优解的变量值,再为新问题创建部分解并赋值:

  1. 遍历原问题所有变量,用SCIPgetSolVal提取每个变量在最优解中的值,存入临时数组;
  2. 添加新变量与约束后,调用SCIPcreatePartialSol创建空的部分解;
  3. 用SCIPsetSolVal将临时数组中的值赋值给部分解对应的原变量,同时为新变量设置一个合理的初始值(比如0或业务相关的猜测值);
  4. 最后调用SCIPaddSolFree将这个部分解作为初始猜测加入SCIP。

这种方式避开了问题状态转换带来的解失效问题,逻辑更清晰,也更稳定。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 10:21:12