如何在Drake中使用Gurobi回调函数获取根节点松弛解
Drake搭配Gurobi获取根节点松弛解实现方案
核心逻辑
不需要靠解析日志拿结果,Drake的Gurobi求解器封装预留了原生模型访问入口,直接调用Gurobi原生API就能精准拿到预求解、自动割生成全部完成后的根松弛结果,适配逻辑如下:
- 求解前设置Gurobi参数
NodeLimit=0,强制求解器跑完根节点的预求解、割生成流程后立刻终止,不进入后续分支定界流程;Presolve和Cuts参数保持默认自动配置即可,不需要额外修改,会按默认策略跑完全部根节点预处理流程。 - 求解完成后通过Drake接口拿到原生Gurobi模型实例,直接读取Gurobi内置属性拿目标界和解值,不要依赖Drake通用返回结果里的最优值字段——因为节点数到0触发终止时,求解状态不是“找到最优解”,Drake封装层不会主动填充这个状态下的目标值。
- 如果用的是Python绑定的Drake,逻辑完全一致,拿到gurobi model对象后直接读对应属性即可。
可直接复用的C++示例代码
#include <drake/solvers/gurobi_solver.h> #include <gurobi_c.h> // 前置步骤:构建完成你的MathematicalProgram,填充所有变量、约束、目标 drake::solvers::MathematicalProgram prog; // ... 这里是你构建混合控制问题的代码 drake::solvers::GurobiSolver solver; drake::solvers::SolverOptions options; // 核心参数:限制只求解根节点 options.SetOption(drake::solvers::GurobiSolver::id(), "NodeLimit", 0); // 可选:打开日志方便核对流程,不需要也可以关闭 options.SetOption(drake::solvers::GurobiSolver::id(), "OutputFlag", 1); drake::solvers::MathematicalProgramResult solve_result; solver.Solve(prog, std::nullopt, options, &solve_result); // 拿到底层原生Gurobi模型指针 GRBmodel* grb_model = const_cast<GRBmodel*>(solver.gurobi_model(solve_result)); // 读取预求解+割生成完成后的根松弛目标界 double root_relax_bound = 0.0; GRBgetdblattr(grb_model, GRB_DBL_ATTR_OBJBND, &root_relax_bound); // 读取所有变量对应的根松弛解值 const int var_count = prog.num_vars(); std::vector<double> root_relax_solution(var_count); GRBgetdblattrarray(grb_model, GRB_DBL_ATTR_X, 0, var_count, root_relax_solution.data());
Python绑定版本示例代码
from pydrake.solvers import GurobiSolver, SolverOptions # 前置步骤:构建完成你的MathematicalProgram prog # ... 构建问题的代码 solver = GurobiSolver() options = SolverOptions() # 核心参数:限制只跑根节点 options.SetOption(GurobiSolver.id(), "NodeLimit", 0) result = solver.Solve(prog, None, options) # 拿到原生gurobi model对象 grb_model = solver.gurobi_model(result) # 读根松弛目标界 root_relax_bound = grb_model.ObjBound # 读根松弛解 root_relax_solution = [var.X for var in grb_model.getVars()]
注意:不需要修改Drake源码做适配,上述逻辑全部在用户侧代码即可实现,也不需要依赖日志输出做字符串解析,拿到的数值是Gurobi内部直接存储的精确结果,不会出现日志打印不全拿不到值的问题。
内容的提问来源于stack exchange,提问作者Jisun Lee
相关产品推荐
相关产品推荐

