Gurobi/Drake中MIP优化续跑及最优解质量监控方法问询
MIP优化会话续跑与解质量增量检查方法
一、Gurobi中实现会话续跑(保存/加载分支定界树)
Gurobi支持保存包含完整分支定界树、已找到解、剪枝信息的状态文件,以此实现续跑,步骤如下:
第一次运行与状态保存
import gurobipy as gp from gurobipy import GRB # 创建或加载MIP模型 model = gp.Model("long_run_mip") # ... 完成变量、约束、目标函数定义 ... # 设置15分钟时间限制(单位:秒) model.setParam(GRB.Param.TimeLimit, 900) model.optimize() # 保存完整会话状态到.mst文件(包含分支定界树) model.write("mip_session_state.mst")
续跑加载与再优化
# 加载保存的会话状态 model = gp.read("mip_session_state.mst") # 再次设置15分钟时间限制 model.setParam(GRB.Param.TimeLimit, 900) model.optimize() # 优化完成后可覆盖保存状态,用于下一轮续跑 model.write("mip_session_state.mst")
.mst是Gurobi的状态文件,包含所有续跑所需的上下文信息,并非仅二进制黑盒。
二、Drake中实现MIP续跑
Drake底层默认调用Gurobi作为MIP求解器,可通过访问底层Gurobi模型实现续跑:
第一次运行与状态保存
from pydrake.solvers.mathematicalprogram import MathematicalProgram from pydrake.solvers.gurobi import GurobiSolver # 创建Drake规划问题 prog = MathematicalProgram() # ... 添加变量、约束、目标函数 ... # 初始化Gurobi求解器与上下文 solver = GurobiSolver() context = solver.MakeDefaultContext(prog) # 设置15分钟时间限制 solver.SetSolverOption(context, "TimeLimit", 900) solver.Solve(context) # 获取底层Gurobi模型并保存状态 gurobi_model = solver.access_grb_model(context) gurobi_model.write("drake_mip_session.mst")
续跑加载与再优化
# 创建与原问题结构完全一致的新规划实例 new_prog = MathematicalProgram() # ... 复制原问题的变量、约束、目标定义 ... new_context = solver.MakeDefaultContext(new_prog) new_gurobi_model = solver.access_grb_model(new_context) # 加载之前保存的状态文件 new_gurobi_model.read("drake_mip_session.mst") # 设置新的时间限制并续跑 solver.SetSolverOption(new_context, "TimeLimit", 900) updated_result = solver.Solve(new_context)
注意:续跑时的MathematicalProgram结构必须与原问题完全一致,否则加载状态会出错。
三、其他增量检查解质量的方法
1. 实时监控优化进度
无需中断优化,通过回调或日志实时获取解质量:
- Gurobi:启用回调函数,定时输出当前最优值、下界、gap:
def progress_callback(model, where): if where == GRB.Callback.MIP: current_gap = model.cbGet(GRB.Callback.MIP_GAP) current_obj = model.cbGet(GRB.Callback.MIP_OBJVAL) current_bound = model.cbGet(GRB.Callback.MIP_OBJBND) print(f"当前Gap: {current_gap*100:.2f}% | 目标值: {current_obj:.2f} | 下界: {current_bound:.2f}") model.setParam(GRB.Param.Callback, progress_callback) model.optimize() - Drake:开启求解器日志输出,会转发Gurobi的实时进度信息,或通过上述Gurobi回调方法实现。
2. 定期保存中间可行解
在优化过程中,每当找到更优可行解时自动保存:
- Gurobi:在回调中捕获新可行解事件并保存:
def save_solution_callback(model, where): if where == GRB.Callback.MIPSOL: # 获取当前可行解 solution = model.cbGetSolution(model.getVars()) # 保存解到文本文件 with open("current_best_sol.txt", "w") as f: for var, val in zip(model.getVars(), solution): f.write(f"{var.VarName}: {val:.4f}\n") # 同步保存会话状态 model.write("latest_session.mst") model.setParam(GRB.Param.Callback, save_solution_callback)
3. 动态调整优化时长
无需固定15分钟循环,根据当前gap动态调整:比如当gap小于预设阈值(如3%)时提前终止,否则延长优化时间;或根据剩余计算资源灵活设置时间限制。
内容的提问来源于stack exchange,提问作者HoliInn
相关产品推荐
相关产品推荐

