使用pydrake对接Gurobi获取二阶锥规划迭代中间解遇NaN问题
问题分析与解决方案
问题定位
Gurobi的optimization_status:7对应GRB.INTERRUPTED状态,即求解因迭代次数限制被中断。Drake当前逻辑中,仅当求解器返回成功状态(如最优、可行)时,才会将求解结果拷贝到变量中;若is_success() == False,则变量值默认填充为NaN,这就是你遇到的核心问题。
解决步骤
1. 配置求解器并获取底层Gurobi模型
在构建二阶锥规划问题后,配置Gurobi迭代次数限制,并直接访问Gurobi的原生模型实例:
from pydrake.solvers.gurobi import GurobiSolver from pydrake.solvers.mathematicalprogram import MathematicalProgram import gurobipy as gp # 构建你的二阶锥规划问题 prog = MathematicalProgram() # ... 添加变量、约束、目标函数 ... solver = GurobiSolver() # 设置迭代次数限制 solver.SetSolverOption(prog, "IterationLimit", 100) # 开启Gurobi日志(可选,便于观察迭代过程) solver.SetSolverOption(prog, "OutputFlag", 1) # 执行求解 result = solver.Solve(prog) # 获取Gurobi原生模型 gurobi_model = solver.access_model()
2. 直接提取中断前的迭代解
无论Drake的result是否标记成功,只要Gurobi完成了部分迭代,就可以从原生模型中提取变量的当前值:
# 遍历Drake决策变量,映射到Gurobi变量并取值 drake_vars = prog.decision_variables() for var in drake_vars: var_idx = solver.GetVariableIndex(prog, var) gurobi_var = gurobi_model.getVars()[var_idx] # 获取中断前的最后解值 current_value = gurobi_var.X print(f"Variable {var.GetName()}: {current_value}")
3. 实时追踪每一步迭代解(可选)
如果需要观察每一次迭代的解演化,可以注册Gurobi的回调函数,在迭代过程中实时获取解:
def iteration_callback(model, where): # 在每次MIP节点迭代时触发 if where == gp.GRB.Callback.MIPNODE: # 获取当前迭代的解向量 iteration_sol = model.cbGetNodeRel(model.getVars()) print(f"Iteration solution: {iteration_sol}") # 注册回调函数 solver.SetSolverOption(prog, "Callback", iteration_callback) # 再次执行求解即可实时打印迭代解 result = solver.Solve(prog)
关键注意事项
- Gurobi的
INTERRUPTED状态下,gurobi_var.X存储的是中断前的最后可行解;若迭代过程中未找到可行解,值可能为初始值或NaN,需结合gurobi_model.Status判断。 - 确保安装了
gurobipy依赖(与Gurobi版本匹配),否则无法使用回调和原生模型的API。
内容的提问来源于stack exchange,提问作者Alan Papalia
相关产品推荐
相关产品推荐

